Try out ASP.NET Web API CORS support using the nightly builds


Recently we just added the support for CORS in Web API. You can find more information on this from our Channel 9 video. Although the feature is checked in, it’s not officially released yet. Nevertheless, you can try it out using our signed nightly builds. In this post, I’ll give you a step by step walkthrough on how to upgrade your MVC 4 project and install the Microsoft.AspNet.WebApi.Cors package from the nightly builds.

Step 1. Create a new Web API project

Start with a new Web API template.

image

Step 2. Uninstall the Microsoft.AspNet.Mvc.FixedDisplayModes package.

This package is not needed and will prevent you from updating to the latest nightly build.

image

Step 3. Install Microsoft.AspNet.WebApi.Cors package from the nightly builds

See the instruction here on using the nightly builds. Once the package source is set, you should be able to see the CORS package (Microsoft.AspNet.WebApi.Cors).

image

There’s one more step you need to follow (Step 4) before running the application. Otherwise you’ll see the following error.

image

Step 4. Fix up the binding redirects in web.config

You can just replace the existing <assemblyBinding> with the following.

<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:bcl="urn:schemas-microsoft-com:bcl">
<dependentAssembly>
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages.Razor" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="EntityFramework" publicKeyToken="b77a5c561934e089" />
<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-1.3.0.0" newVersion="1.3.0.0" />
</dependentAssembly>
</assemblyBinding>

After that, your application should run just fine.

image

 

Trying it out

To make a quick cross-origin request you can just browse to the test client that I have hosted on Azure: http://webapisample.azurewebsites.net/Help/Api/GET-api-Values

image

Click on “Test API”, paste the full URI to your Web API and click “Send”. You’ll see that the request failed because your Web API doesn’t have CORS enabled by default.

image

Now, let’s enable CORS for your APIs by calling config.EnableCors(new EnableCorsAttribute()) as shown in the sample below. This will enable CORS for all your controllers and allow all origins.  See the feature spec for more information.

Update 04/26/13: The EnableCorsAttribute now requires the allowed origins, headers and methods in the constructor. To allow all, use EnableCorsAttribute(“*”, “*”, “*”).

using System.Web.Http;
using System.Web.Http.Cors;

namespace MvcApplication20
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);

config.EnableSystemDiagnosticsTracing();

config.EnableCors(new EnableCorsAttribute());
}
}
}

After that, the same request will succeed and we get back the response.

image

Few notes when testing this with IE

  • IE does not consider the port to be a part of the Security Identifier (origin) used for Same Origin Policy enforcement. This means if you have test client on localhost:3030 and the Web API on localhost:8080, IE won’t be making a cross-origin request
  • When using the test client hosted on azure, you might need to add it to the trusted site to call the Web API hosted on your local machine (localhost)

image

Hope you find this useful!

Yao

Comments (41)

  1. Cors implementation says:

    Hi Lin,

    I have created a small application using Restful Wcf service. I am using the frame work VS 2012. I found one roadblock during the development. I have two different server. In one server i hosted my application and another server hosted the Restful Wcf service. Using Ajax jquery when i am trying to communicate with the service. Its working fine in IE9 and get the JSON data but its not working for FF and Chrome browser.

    Can you please suggest what is the approach i can proceed with. I already tried 2 days still i didn't any solutions. Any help would be greatly appreciated.

    MailId: mail2prakash.mca@gmail.com

  2. Tan says:

    Is the package only available for VS2012? I can't find it in Nuget VS2010.

  3. Hi Prakash,

    Maybe the reason it worked on IE is because "IE does not consider the port to be a part of the Security Identifier (origin) used for Same Origin Policy enforcement. This means if you have test client on localhost:3030 and the Web API on localhost:8080, IE won’t be making a cross-origin request". To double check can you use fiddler or IE's F12 developer tools and see if the origin header is sent and whether you get back the Access-Control-Allow-Origin in the response? Then compare the result with other browsers.

  4. Hi Tan,

    The package is available as part of the nightly builds and you need to add it to the NuGet package source, see the instruction here: aspnetwebstack.codeplex.com/wikipage

    The assemblies are targeted to .NET 4.5.

  5. Bruce says:

    Hi Yao,

    I want in non-English version Web API Project (VS is Chinese) to test CORS, but NuGet will show error message, like this:

    http://i.imgur.com/U2t4PcD.png

    I know to change VS language to English then create new Web API Project will fine, but have any idea disable NuGet Package language check?

  6. Osman says:

    Yao,

    [EnableCors(Origins = new[] { "http://*.sample.com&quot; })]

    does support virtual directories within the same domain.

    like this "http://*.sample.com&quot;

    start (*) is the different apps under different VDs

    Thanks!

  7. Joseph Lam says:

    Will it eventually support .Net 4.0?

  8. James Hancock says:

    With the latest the EnableCorsAttribute requires parameters for origins, headers and methods. How do you allow all?

  9. Hi Bruce,

    The nightly build packages for other languages are not publicly available at the moment. They probably won't be available until the official release, so please use the English build for now to tryout the features.

  10. Hi Osman,

    We don't support pattern like "http://*.sample.com&quot; because "http://foo.sample.com&quot; and "http://bar.sample.com&quot; are considered different origin.

  11. Hi jlamkw,

    Most of the Web API assemblies will be targeting .NET 4.5 moving forward.

  12. Hi James,

    You can use "*" to allow all origins/headers/method: [EnableCors("*", "*", "*")]

  13. Justin Hixson says:

    Does this package support a Self-Hosted API as well?

  14. Hi Justin,

    Yes, it does support self-host.

  15. Bonny says:

    Step 3. Install Microsoft.AspNet.WebApi.Cors package from the nightly builds.

    The nightly build seems is not available, I'm not seeing them in my nugget, please advice.

    Thanks!

  16. Hi Bonny,

    Have you added the following NuGet package source?

    http://www.myget.org/…/aspnetwebstacknightly

    Here's more info on how to use the nightly builds: aspnetwebstack.codeplex.com/wikipage

  17. Andrew says:

    How do I uninstall and install packages from an EXISTING mvc4 project to enable this?

  18. Andrew says:

    I am a moron and figured it out… now battling through errors like "Could not load file or assembly 'System.Net.Http.Formatting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies."

  19. Hi Andrew,

    Try adding the following in web.config:

     <dependentAssembly>

       <assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" />

       <bindingRedirect oldVersion="1.0.0.0-5.0.0.0" newVersion="5.0.0.0" />

     </dependentAssembly>

  20. Pascal says:

    Hi Yao,

    Regarding the [EnableCors("*", "*", "*")], is there any way to load the origins in a dynamic way like via appsettings or dataset?

  21. Pascal says:

    Aaaand….. nvm… That part in the codeplex documentation is still the same… Works as a charm!

  22. Brian says:

    When can we expect this to be officially released?

  23. Francisco says:

    I followed your step-by-step, and accessing from webapisample.azurewebsites.net/…/GET-api-Values to my localhost: http://localhost:26160/api/produto it worked fine.

    But for some reason, if I try to access it from another localhost: http://localhost:18215/ (using chrome) I get an error: XMLHttpRequest cannot load http://localhost/api/produto. Origin http://localhost:18215 is not allowed by Access-Control-Allow-Origin.

    Any thoughts?

    Thank you.

  24. Francisco says:

    Sorry for the question above. The problem wasn't related with CORS.  I have already fixed it.

    Thank you.

  25. Had this working GREAT yesterday. Updated build today and get this dll version error. How to update?

    "Assembly 'System.Web.Http.Cors, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' uses 'System.Web.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' which has a higher version than referenced assembly 'System.Web.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'"

  26. Hi Brian,

    Please keep an eye on http://www.asp.net/web-api for announcements and updates.

  27. Hi Francisco,

    No problem. Glad you figured it out.

  28. Hi thehitman3030,

    Can you try adding a binding redirect for System.Web.Http?

     <dependentAssembly>

       <assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" />

       <bindingRedirect oldVersion="1.0.0.0-5.0.0.0" newVersion="5.0.0.0" />

     </dependentAssembly>

  29. mandeep says:

    i am not able to see a any api when i type cors in nuget of VS2012

  30. Hi Yao –

    I got the nightly build and setup everything.

    It's just strange that when I execute cross domain call from jquery, it encountered an error. Status is error with xml httprequest text is empty string.

    But looking into Fiddler, my call actually returned 200/OK with response as JSON formatted.

    What am I missing here?

    Thanks.

  31. jesse says:

    They're integrated CORS support in the prelease builds on the main nuget package source. You don't need to configure the nightlies repo anymore.

    http://www.asp.net/…/enabling-cross-origin-requests-in-web-api

  32. Yazid says:

    Hi Yao,

    I've got the cors setup and added the assembly binding in the web.config.

    When I launched, it gave me this error.

    Could not load file or assembly 'System.Web.Helpers' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

    Any clule?

  33. Yazid says:

    Forget what I've just said. It works now.

  34. KO says:

    Hi Yao,

    I am having the same issues as thehitman3030. I've added a binding redirect for System.Web.Http:

    <dependentAssembly>

      <assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" />

      <bindingRedirect oldVersion="1.0.0.0-5.0.0.0" newVersion="5.0.0.0" />

    </dependentAssembly>

    but still receiving the exact same error. Any other idea?

  35. sri says:

    Yao,

    Did you fix this error? I am getting the same after updating Microsoft.AspNet.WebApi.WebHost

  36. Kreso says:

    Same problem as thehitman3030.Made proposed chanes to config but still the same:

    System.Web.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' which has a higher version than referenced assembly 'System.Web.Http, Version=4.0.0.0

  37. JP says:

    Having the same problem with System.Web.Http as thehitman3030.

  38. Jed says:

    Also having the same problem as thehitman3030.

  39. Jac says:

    Hello,

    I have tried to follow your instructions on the scaffolded Web API site produced  by VS 2013 RTM with individual accounts: see http://www.asp.net/…/individual-accounts-in-web-api

    I am enabling CORS globally in WebApiConfig.cs. Everything works fine in chrome.exe with –disable-web-security parameter, but without disabling we security the call to /Token gets cancelled.

    So the question is, how do you enable CORS on the Token endpoint in ApplicationOAuthProvider.cs?

    Thanks.

  40. SureshKalimuthu says:

    I am getting error "redirects are not allowed for cors preflight requests". The response code is 302 because the call is redirected to ACS authorization server. Is redirects supported in CORS?

  41. Nitin Rawat says:

    I followed all your steps but i am getting following error on building the webapi:

    Could not load file or assembly 'System.Web.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

    Please suggest some solution.