Wednesday, October 4, 2017

Cross-Origin Request Blocked (CORS)

To speed up the development and future upgrade, we split the huge application into multiple AJAX services. Each AJAX service in running in it's own application pool and it can be run on different server. The design works perfectly. But, when you want to consume the AJAX services through the browser, you bang your head: "Cross-Origin Request Blocked".

This is the error message that appeared in the Firefox:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost/schedule/q?code=tx&ts=1507099862873. (Reason: CORS header ‘Access-Control-Allow-Origin’ does not match ‘(null)’).

Google Chrome returned an error message that is slightly different:

Failed to load http://localhost/schedule/q?code=tx&ts=1507099946004: The 'Access-Control-Allow-Origin' header contains multiple values '*, *', but only one is allowed. Origin 'http://localhost:56269' is therefore not allowed access.

Now, if you are googling for the solution, you will end up with add the following settings in the web.config.

  <httpProtocol>
    <customHeaders>
      <add name="Access-Control-Allow-Origin" value="*" />
      <add name="Access-Control-Allow-Headers" value="Content-Type" />
      <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
    </customHeaders>
  </httpProtocol>

But, the wild card origin is no longer supported. You ended up with adding the specific origin.

  <httpProtocol>
    <customHeaders>
      <add name="Access-Control-Allow-Origin" value="http://localhost:56292" />
      <add name="Access-Control-Allow-Headers" value="Content-Type" />
      <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
    </customHeaders>
  </httpProtocol>

Imagine that you are hosting your AJAX services in multiple servers with different sub-domains.... the above solution will not work. This is because you are not allowed adding more than one domain name to "Access-Control-Allow-Origin".

To solve the problem, we need to handle the OPTIONS verb by adding the following settings in the web.config:

  <system.webServer>
    <handlers>
      <add verb="OPTIONS" name="check_opt" path="*" type="ajaxLib.CORS_OPTIONS" />
    </handlers>
  </system.webServer>

And below is the simplified code that allows CORS:

namespace ajaxLib {
public class CORS_OPTIONS : IHttpHandler
{
  public void ProcessRequest(HttpContext context)
  {
        if (context.Request.HttpMethod.ToUpper() == "OPTIONS") {
           string s = context.Request.Headers["Origin"];

           if (!string.IsNullOrWhiteSpace(s))
           {
             context.Response.AppendHeader("Access-Control-Allow-Origin", s);
             context.Response.AppendHeader("Access-Control-Allow-Headers", "Content-Type");
             context.Response.AppendHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
           }
    }
  }

  public bool IsReusable { get { return false; }}

}}

Two possibilities if you want to use the above code in the live environment,

1. If your service allows public access without any restriction, skip checking the Origin value.
2. If your service allows specific domain to access, you must check the Origin value before return it to the caller.



Saturday, July 22, 2017

Decoupling the code with "notification" design

In C#, there are many different ways to decouple the program and the most common ways of doing so is to use one of the following:
  • event - it's multicasting. You listen to what you need.
  • interface  - it's dynamic. You can incorporate the interface into any of your class.
  • callback using Action<T> or Func<T> - you handle what you are interested.
Other than the above, there is another way to decouple the code - using "notification messages". For example, the lowest level WndProc (in WinForm) which processes all Windows messages. Let's make use of this strategy in our C# program.

The core of this strategy - the publisher & subscriber + multi-threaded object. Let's call it NotificationServer. This core object allows the publisher to send the notification messages into the message pool. It also allows the subscriber to subscribe and listen to the notification messages that they are interested. You will find tons of example on how to implement the publisher & subscriber + multi-threaded in the Internet.


The notification message object contains the following properties:
  • message ID - the ID that allows the subscriber to identify the purpose of it.
  • session ID - it's GUID type and it's used in conjunction with broadcast flag.
  • data - it's an object to be passing around.
  • broadcast - it's a flag which tells the NotificationServer whether it should send the message to a specific subscriber or all subscribers. This can be very useful if you are implementing a TCP NotificationServer.
  • should feedback - it's a flag that indicate whether it waits for the NotificationServer's respond. This can be very useful if you are implementing a TCP NotificationServer.
The NotificationServer design
  • Embedded NotificationServer- the implementation is to have a publisher & subscriber + multi-threaded object.
  • The fun does not stop here - you can embed the NotificationServer class into a TCP server class and all communications are done through TCP communication. In this case, you will have a TCP NotificationServer which is able to run as a Windows Service. The publisher and subscribers can be any program, ASP.Net web page or another Windows Service. The publisher and subscribers could be running from the same computer or different computer.  
In our TCP NotificationServer implementation, the notification message is serialized into JSON format. We chose JSON format because we are reusing the TCP NotificationServer in various projects.

Monday, May 15, 2017

A better way to configure Intelli-sense for Javascript in VS2015

Now, I'm moving toward the direction of developing fat client using Javascript (JS) and I need a
better way of enable the intelli-sense support for Javascript in the fat client.

Earlier, I found out that we can include the reference in each JS file by adding the following line.
When the number of JS files that you are developing are increasing, added this reference line might be headache.

   /// <reference path="jquery-1.7.js" />

Here is a better way:

1. Add a "_references.js" file into "js" folder (let says you are keeping all your JS files in a folder call "js" instead of "scripts").

2. In the Quick Launch bar (located at top right corner), key in "Javascript" and look for "IntelliSense -> References"  option. Clicks on it.



3. Choose "Implicit (Web)" option.
4. In the "Add a reference to current group" field, key in "~/js/_references.js".
5. Click Add button.
6. Click OK.



7. Back to the Solution Explorer. Right click on _references.js and you will find two new options.

- Auto-sync- means that VS will add all the JS files automatically.
- Update Javascript References - this is manually sync the JS files.