Join the Stack Overflow Community
Stack Overflow is a community of 6.4 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

I have a simple actionmethod, that returns some json. It runs on ajax.example.com. I need to access this from another site someothersite.com.

If I try to call it, I get the expected...:

Origin http://someothersite.com is not allowed by Access-Control-Allow-Origin.

I know of two ways to get around this: JSONP and creating a custom HttpHandler to set the header.

Is there no simpler way?

Is it not possible for a simple action to either define a list of allowed origins - or simple allow everyone? Maybe an action filter?

Optimal would be...:

return json(mydata, JsonBehaviour.IDontCareWhoAccessesMe);
share|improve this question
1  
Please have a look here for vNext and MVC6: neelbhatt40.wordpress.com/2015/09/10/… – Neel Sep 11 '15 at 13:17

10 Answers 10

up vote 277 down vote accepted

For plain ASP.NET MVC Controllers

Create a new attribute

public class AllowCrossSiteJsonAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        filterContext.RequestContext.HttpContext.Response.AddHeader("Access-Control-Allow-Origin", "*");
        base.OnActionExecuting(filterContext);
    }
}

Tag your action:

[AllowCrossSiteJson]
public ActionResult YourMethod()
{
    return Json("Works better?");
}

For ASP.NET Web API

using System;
using System.Web.Http.Filters;

public class AllowCrossSiteJsonAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
        if (actionExecutedContext.Response != null)
            actionExecutedContext.Response.Headers.Add("Access-Control-Allow-Origin", "*");

        base.OnActionExecuted(actionExecutedContext);
    }
}

Tag a whole API controller:

[AllowCrossSiteJson]
public class ValuesController : ApiController
{

Or individual API calls:

[AllowCrossSiteJson]
public IEnumerable<PartViewModel> Get()
{
    ...
}

For Internet Explorer <= v9

IE <= 9 doesn't support CORS. I've written a javascript that will automatically route those requests through a proxy. It's all 100% transparent (you just have to include my proxy and the script).

Download it using nuget corsproxy and follow the included instructions.

Blog post | Source code

share|improve this answer
3  
This works perfectly, thanks. :) – Kjensen Jun 9 '11 at 9:37
4  
Amazing! I luv MVC + U! – ppumkin Jan 25 '12 at 15:15
1  
in awe of the elegance of this solution – BraveNewMath Dec 14 '12 at 9:59
3  
You could easily extend the attribute to accept a specific origin if you wanted to limit CORS to your own domains. – Petrus Theron Feb 22 '13 at 11:34
2  
You should be able to add this to the RegisterHttpFilters in your App_Start\FilterConfig correct? Doing so would apply it to all of the Api controllers in your project. Coupling this with pate's comment above you could limit CORS to your domain(s) for all controllers. – bdwakefield Mar 12 '13 at 18:04

If you are using IIS 7+, you can place a web.config file into the root of the folder with this in the system.webServer section:

<httpProtocol>
   <customHeaders>
      <clear />
      <add name="Access-Control-Allow-Origin" value="*" />
   </customHeaders>
</httpProtocol>

See: http://msdn.microsoft.com/en-us/library/ms178685.aspx And: http://enable-cors.org/#how-iis7

share|improve this answer
3  
I would argue that this is simpler than the accepted answer. – sellmeadog Jan 8 '13 at 22:34
1  
I can't remember why anymore, but this method does not always work in IIS 7+ – LaundroMatt Jan 9 '13 at 15:31
    
Hmm. The only reason I can think it wouldn't work is if a request originates from a non-CORS browser. But I'll continue to investigate. – sellmeadog Jan 9 '13 at 16:53
21  
Also, this would make the entire website CORS-friendly. If somebody wants to mark only a single action or controller as CORS-friendly, then the accepted answer is much better. – Lev Dubinets Feb 8 '13 at 16:43
1  
If you see the ASP.Net section, it has a hint: "Note: this approach is compatible with IIS6, IIS7 Classic Mode, and IIS7 Integrated Mode." – percebus Dec 13 '13 at 20:28

I ran into a problem where the browser refused to serve up content that it had retrieved when the request passed in cookies (e.g., the xhr had its withCredentials=true), and the site had Access-Control-Allow-Origin set to *. (The error in Chrome was, "Cannot use wildcard in Access-Control-Allow-Origin when credentials flag is true.")

Building on the answer from @jgauffin, I created this, which is basically a way of working around that particular browser security check, so caveat emptor.

public class AllowCrossSiteJsonAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        // We'd normally just use "*" for the allow-origin header, 
        // but Chrome (and perhaps others) won't allow you to use authentication if
        // the header is set to "*".
        // TODO: Check elsewhere to see if the origin is actually on the list of trusted domains.
        var ctx = filterContext.RequestContext.HttpContext;
        var origin = ctx.Request.Headers["Origin"];
        var allowOrigin = !string.IsNullOrWhiteSpace(origin) ? origin : "*";
        ctx.Response.AddHeader("Access-Control-Allow-Origin", allowOrigin);
        ctx.Response.AddHeader("Access-Control-Allow-Headers", "*");
        ctx.Response.AddHeader("Access-Control-Allow-Credentials", "true");
        base.OnActionExecuting(filterContext);
    }
}
share|improve this answer

Sometimes OPTIONS verb as well causes problems

Simply: Update your web.config with the following

<httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Origin" value="*" />
        <add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept" />
      </customHeaders>
    </httpProtocol>
  </system.webServer>

And update the webservice/controller headers with httpGet and httpOptions

// GET api/Master/Sync/?version=12121
        [HttpGet][HttpOptions]
        public dynamic Sync(string version) 
        {
share|improve this answer
    
BTW, in sitefinity you need to add * to the System advanced settings in the security section – Bishoy Hanna Sep 3 '14 at 2:37
    
which are the files in which I need to update the controller headers? – user3281466 Oct 19 '14 at 8:52

WebAPI 2 now has a package for CORS which can be installed using : Install-Package Microsoft.AspNet.WebApi.Cors -pre -project WebServic

Once this is installed, follow this for the code :http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api

share|improve this answer

This is really simple , just add this in web.config

<system.webServer>
  <httpProtocol>
    <customHeaders>
      <add name="Access-Control-Allow-Origin" value="http://localhost" />
      <add name="Access-Control-Allow-Headers" value="X-AspNet-Version,X-Powered-By,Date,Server,Accept,Accept-Encoding,Accept-Language,Cache-Control,Connection,Content-Length,Content-Type,Host,Origin,Pragma,Referer,User-Agent" />
      <add name="Access-Control-Allow-Methods" value="GET, PUT, POST, DELETE, OPTIONS" />
      <add name="Access-Control-Max-Age" value="1000" />
    </customHeaders>
  </httpProtocol>
</system.webServer>

In Origin put all domains that have access to your web server, in headers put all possible headers that any ajax http request can use, in methods put all methods that you allow on your server

regards :)

share|improve this answer

Add this line to your method, If you are using a API.

HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*"); 
share|improve this answer

This tutorial is very useful. To give a quick summary:

  1. Use the CORS package available on Nuget: Install-Package Microsoft.AspNet.WebApi.Cors

  2. In your WebApiConfig.cs file, add config.EnableCors() to the Register() method.

  3. Add an attribute to the controllers you need to handle cors:

[EnableCors(origins: "<origin address in here>", headers: "*", methods: "*")]

share|improve this answer
    
I had to use this method because I needed to set a custom header in my request, and the custom attribute method did not work with the browsers pre-flight request. This seems to work in all cases. – lehn0058 Feb 29 at 19:25
    public ActionResult ActionName(string ReqParam1, string ReqParam2, string ReqParam3, string ReqParam4)
    {
        this.ControllerContext.HttpContext.Response.Headers.Add("Access-Control-Allow-Origin","*");
         /*
                --Your code goes here --
         */
        return Json(new { ReturnData= "Data to be returned", Success=true }, JsonRequestBehavior.AllowGet);
    }
share|improve this answer

There is a pleasant nuget package for doing this:

documentation and examples at

http://brockallen.com/2012/06/28/cors-support-in-webapi-mvc-and-iis-with-thinktecture-identitymodel/

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.