Enable cross origin request with ASP.NET MVC

October 5, 2011

tags: , , ,
7 comments

As you know you can’t make an Ajax cross domain request. The browser block this kind of requests. To enable Cross-Origin Requests (CORS) you need to add some headers to the server response: “Access-Control-Allow-Origin” and “Access-Control-Allow-Methods”.

So I made a MVC filter that will allow cross domain calls:

public class AllowCrossDomain : ActionFilterAttribute

{

    public const string AllDomains = "*";

 

    private readonly string[] _allowMethods;

    private string _allowOrigin;

 

    public AllowCrossDomain()

        : this(null, null)

    {

 

    }

 

    public AllowCrossDomain(string allowOrigin, params string[] allowMethods)

    {

        _allowMethods = allowMethods;

        _allowOrigin = allowOrigin;

 

        if (string.IsNullOrWhiteSpace(_allowOrigin))

        {

            _allowOrigin = AllDomains;

        }

        if (_allowMethods == null || _allowMethods.Length == 0)

        {

            _allowMethods = new[] { "GET" };

        }

    }

 

    public override void OnActionExecuting(ActionExecutingContext filterContext)

    {

        filterContext.HttpContext.Response.Headers.Add("Access-Control-Allow-Origin", _allowOrigin);

        filterContext.HttpContext.Response.Headers.Add("Access-Control-Allow-Methods", string.Join(", ", _allowMethods));

        filterContext.HttpContext.Response.Headers.Add("Access-Control-Max-Age", "86400");

    }

To use it just put it on a method on controller:

[AllowCrossDomain]

public ActionResult Index()

{

    return Json(new {sample="a sample data",crossDomain="you can read it from cross domain"})

}

Simple…

A few things before you try this:

1. “Cassini” doesn’t support this kind of headers you will need to run it on IIS \ IIS Express

2. CROS are supported only by modern browsers FF 3.6+ all chrome browsers, modern smart phones…

3. In order to enable it on IE you need to change the security settings:

 

you can read more about CROS here: http://www.w3.org/TR/cors/

 

Keep Writing, Compiling, and Debugging

Alon Nativ

Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

7 comments

  1. Gal SegalOctober 5, 2011 ב 10:15 AM

    Another way is to support JSONP wrapping for ajax calls:
    it is compliant with all browsers and doesn’t require messing with IE settings :)

    Reply
  2. Alon NativOctober 5, 2011 ב 1:25 PM

    Hi Gal,
    The problem that in this way you can only make GET request and you are not able to create a pure REST services…

    I agree with the IE problem I won’t create a site like that unless it is only for mobile

    I hope that in the future IE will support at out of the box

    Thanks,
    A.

    Reply
  3. JonathanNovember 18, 2011 ב 2:01 AM

    If adding headers with the statement filterContext.Headers.Add(“Header”, “Value”) is not supported (throws a PlatformNotSupportedException) you can set the headers like this
    filterContext.HttpContext.Response.AddHeader(“Header”, “Value”);

    So OnActionExecuting method will be like shown below

    [CODE]
    ///

    /// Adds the headers to allow crossDomain requests
    ///

    /// FilterContext of the current action
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
    try
    {
    filterContext.HttpContext.Response.Headers.Add(“Access-Control-Allow-Origin”, _allowOrigin);
    filterContext.HttpContext.Response.Headers.Add(“Access-Control-Allow-Methods”, string.Join(“, “, _allowMethods));
    filterContext.HttpContext.Response.Headers.Add(“Access-Control-Max-Age”, “86400″);
    }
    catch
    {
    //Adding headers is not supported in that way. Try another one
    filterContext.HttpContext.Response.AddHeader(“Access-Control-Allow-Origin”, _allowOrigin);
    filterContext.HttpContext.Response.AddHeader(“Access-Control-Allow-Methods”, string.Join(“, “, _allowMethods));
    filterContext.HttpContext.Response.AddHeader(“Access-Control-Max-Age”, “86400″);
    }
    }
    [/CODE]

    Reply
  4. Alon NativNovember 18, 2011 ב 9:39 AM

    Hi Jonathan,
    The problem is that you are trying to run the code on Cassini and not on IIS.

    as I wrote above:
    “1. “Cassini” doesn’t support this kind of headers you will need to run it on IIS \ IIS Express”

    Thanks,
    A.

    Reply
  5. ForbesJuly 21, 2012 ב 8:00 PM

    Whoa. That was a great article. Please keep writing as I love your
    style.

    Reply
  6. PVecchioSeptember 11, 2012 ב 12:16 AM

    Nice – but does not work for me in Chrome (21).
    Still get the dreaded error: Origin http://localhost is not allowed by Access-Control-Allow-Origin

    Tried this with both IIS and IIS Express.

    IE does work if I use this in my ajax call:

    $.support.cors = true;

    The code above does clearly hit the controller, but seems to have no affect in Chrome.

    Also tried adding to the web.config:


    Still does not help Chrome.
    Any other suggestions?

    Reply
  7. unknownOctober 5, 2013 ב 10:08 PM

    Tu veux acheter quoi de beau ? ^^

    Reply