Asp.Net WebApi2启用CORS不能与AspNet.WebApi.Cors一起使用5.2.3

我试图按照http://enable-cors.org/server_aspnet.html上的步骤使我的RESTful API(使用ASP.NET WebAPI2实现)与跨源请求(启用CORS)一起工作。 这不工作,除非我修改web.config。

我安装了WebApi Cors依赖项:

install-package Microsoft.AspNet.WebApi.Cors -ProjectName MyProject.Web.Api 

然后在我的App_Start我有类WebApiConfig如下:

 public static class WebApiConfig { public static void Register(HttpConfiguration config) { var corsAttr = new EnableCorsAttribute("*", "*", "*"); config.EnableCors(corsAttr); var constraintsResolver = new DefaultInlineConstraintResolver(); constraintsResolver.ConstraintMap.Add("apiVersionConstraint", typeof(ApiVersionConstraint)); config.MapHttpAttributeRoutes(constraintsResolver); config.Services.Replace(typeof(IHttpControllerSelector), new NamespaceHttpControllerSelector(config)); //config.EnableSystemDiagnosticsTracing(); config.Services.Replace(typeof(ITraceWriter), new SimpleTraceWriter(WebContainerManager.Get<ILogManager>())); config.Services.Add(typeof(IExceptionLogger), new SimpleExceptionLogger(WebContainerManager.Get<ILogManager>())); config.Services.Replace(typeof(IExceptionHandler), new GlobalExceptionHandler()); } } 

但之后我运行的应用程序,我请求与Fiddler的资源,如: http:// localhost:51589 / api / v1 /个人,并在响应我看不到我应该看到的HTTP标头,如:

  • Access-Control-Allow-Methods: POST, PUT, DELETE, GET, OPTIONS
  • Access-Control-Allow-Origin: *

我错过了一些步骤? 我已经在控制器上使用了以下注释:

[EnableCors(origins: "http://example.com", headers: "*", methods: "*")]

同样的结果,没有启用CORS。

但是,如果我在web.config中添加以下内容(甚至不需要安装AspNet.WebApi.Cors依赖项):

 <system.webServer> <httpProtocol> <!-- THESE HEADERS ARE IMPORTANT TO WORK WITH CORS --> <!-- <customHeaders> <add name="Access-Control-Allow-Origin" value="*" /> <add name="Access-Control-Allow-Methods" value="POST, PUT, DELETE, GET, OPTIONS" /> <add name="Access-Control-Allow-Headers" value="content-Type, accept, origin, X-Requested-With, Authorization, name" /> <add name="Access-Control-Allow-Credentials" value="true" /> </customHeaders> --> </httpProtocol> <handlers> <!-- THESE HANDLERS ARE IMPORTANT FOR WEB API TO WORK WITH GET,HEAD,POST,PUT,DELETE and CORS--> <!-- <remove name="WebDAV" /> <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,PUT,DELETE" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /> <remove name="ExtensionlessUrlHandler-Integrated-4.0" /> <remove name="OPTIONSVerbHandler" /> <remove name="TRACEVerbHandler" /> <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /> --> </handlers> 

任何帮助将不胜感激!

谢谢。

我为你创build了一个简化的演示项目。

  • 资料来源 : https : //github.com/bigfont/webapi-cors
  • Api链接 : https : //cors-webapi.azurewebsites.net/api/values

您可以尝试从您当地的提琴手的上述API链接查看标题。 这是一个解释。

Global.ascx

所有这一切都是调用WebApiConfig 。 这只是代码组织。

 public class WebApiApplication : System.Web.HttpApplication { protected void Application_Start() { WebApiConfig.Register(GlobalConfiguration.Configuration); } } 

WebApiConfig.cs

您在这里的关键方法是EnableCrossSiteRequests方法。 这就是你需要做的一切。 EnableCorsAttribute是一个全局作用域的CORS属性 。

 public static class WebApiConfig { public static void Register(HttpConfiguration config) { EnableCrossSiteRequests(config); AddRoutes(config); } private static void AddRoutes(HttpConfiguration config) { config.Routes.MapHttpRoute( name: "Default", routeTemplate: "api/{controller}/" ); } private static void EnableCrossSiteRequests(HttpConfiguration config) { var cors = new EnableCorsAttribute( origins: "*", headers: "*", methods: "*"); config.EnableCors(cors); } } 

值控制器

Get方法接收我们全局应用的EnableCors属性。 Another方法覆盖全局EnableCors

 public class ValuesController : ApiController { // GET api/values public IEnumerable<string> Get() { return new string[] { "This is a CORS response.", "It works from any origin." }; } // GET api/values/another [HttpGet] [EnableCors(origins:"http://www.bigfont.ca", headers:"*", methods: "*")] public IEnumerable<string> Another() { return new string[] { "This is a CORS response. ", "It works only from two origins: ", "1. www.bigfont.ca ", "2. the same origin." }; } } 

Web.config文件

你不需要在web.config中添加任何特殊的东西。 事实上,这就是演示的web.config的外观 – 它是空的。

 <?xml version="1.0" encoding="utf-8"?> <configuration> </configuration> 

演示

 var url = "https://cors-webapi.azurewebsites.net/api/values" $.get(url, function(data) { console.log("We expect this to succeed."); console.log(data); }); var url = "https://cors-webapi.azurewebsites.net/api/values/another" $.get(url, function(data) { console.log(data); }).fail(function(xhr, status, text) { console.log("We expect this to fail."); console.log(status); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 

在CORS请求的情况下,所有现代浏览器都使用OPTION谓词进行响应,然后通过实际的请求。 这应该是用来在CORS请求的情况下提示用户确认。 但是,如果你想要跳过这个validation过程的API的情况下,将以下片段添加到Global.asax

  protected void Application_BeginRequest(object sender, EventArgs e) { HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*"); if (HttpContext.Current.Request.HttpMethod == "OPTIONS") { HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "POST, PUT, DELETE"); HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept"); HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000"); HttpContext.Current.Response.End(); } } 

在这里,我们只是通过检查选项动词通过检查。

你只需要改变一些文件。 这对我有用。

Global.ascx

 public class WebApiApplication : System.Web.HttpApplication { protected void Application_Start() { WebApiConfig.Register(GlobalConfiguration.Configuration); } } 

WebApiConfig.cs

所有的请求必须调用这个代码。

 public static class WebApiConfig { public static void Register(HttpConfiguration config) { EnableCrossSiteRequests(config); AddRoutes(config); } private static void AddRoutes(HttpConfiguration config) { config.Routes.MapHttpRoute( name: "Default", routeTemplate: "api/{controller}/" ); } private static void EnableCrossSiteRequests(HttpConfiguration config) { var cors = new EnableCorsAttribute( origins: "*", headers: "*", methods: "*"); config.EnableCors(cors); } } 

一些控制器

没有什么改变。

Web.config文件

您需要在web.config中添加处理程序

 <configuration> <system.webServer> <handlers> <remove name="ExtensionlessUrlHandler-Integrated-4.0" /> <remove name="OPTIONSVerbHandler" /> <remove name="TRACEVerbHandler" /> <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /> </handlers> </system.webServer> </configuration> 

我只是将自定义标题添加到Web.config,它像一个魅力。

在configuration – system.webServer:

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

我有相同的解决scheme前端应用程序和后端。 为了这个工作,我需要设置Web服务项目(后端)作为默认工作。

我正在使用ReST,还没有尝试过别的。

在我的Web.config CORS的一些修改后突然停止在我的Web API 2项目(至less在预检期间的OPTIONS请求)工作。 看来您需要在Web.config中提供以下部分,否则(全局)EnableCorsAttribute将无法在OPTIONS请求上工作。 请注意,这是Visual Studio将在新的Web API 2项目中添加的完全相同的部分。

 <system.webServer> <handlers> <remove name="ExtensionlessUrlHandler-Integrated-4.0"/> <remove name="OPTIONSVerbHandler"/> <remove name="TRACEVerbHandler"/> <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0"/> </handlers> </system.webServer> 

我刚刚遇到了同样的问题,试图在全球范围内启用CORS 。 但是,我发现它确实工作,但只有当请求包含一个Origin头值。 如果您省略origin标题值,则该响应将不包含Access-Control-Allow-Origin

我使用了一个名为DHC的Chrome插件来testing我的GET请求。 它允许我轻松地添加Origin标头。

这些答案都没有真正的工作。 正如其他人指出,如果请求有一个Origin头,Cors包将只使用Access-Control-Allow-Origin头。 但是你通常不能在请求中添加一个Origin头部,因为浏览器也可能试图调节这个。

如果你想要一个快速和肮脏的方式来允许跨网站的请求到一个Web API,只是写一个自定义的filter属性真的很容易:

 public class AllowCors : ActionFilterAttribute { public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) { if (actionExecutedContext == null) { throw new ArgumentNullException("actionExecutedContext"); } else { actionExecutedContext.Response.Headers.Remove("Access-Control-Allow-Origin"); actionExecutedContext.Response.Headers.Add("Access-Control-Allow-Origin", "*"); } base.OnActionExecuted(actionExecutedContext); } } 

然后在你的Controller动作上使用它:

 [AllowCors] public IHttpActionResult Get() { return Ok("value"); } 

一般来说,我不保证这个安全性,但是比在web.config中设置头文件可能要安全得多,因为这样你可以只按照你需要的方式来应用它们。

当然,修改上面的内容很简单,只允许某些来源,方法等。

WEBAPI2:解决scheme。 的global.asax.cs:

 var cors = new EnableCorsAttribute("*", "*", "*"); config.EnableCors(cors); 

在解决scheme资源pipe理器中,右键单击api-project。 在属性窗口中设置“匿名身份validation” 启用

希望这有助于未来的人。

我发现这个问题,因为我遇到了大多数浏览器发送的OPTIONS请求的问题。 我的应用程序路由select请求,并使用我的IoC构造大量的对象,有些人因为各种原因在这个奇怪的请求types抛出exception。

基本上所有的OPTIONS请求,如果他们导致你的问题,忽略路线:

 var constraints = new { httpMethod = new HttpMethodConstraint(HttpMethod.Options) }; config.Routes.IgnoreRoute("OPTIONS", "{*pathInfo}", constraints); 

更多信息: 停止Web API处理选项请求

希望这有助于未来的人。 我的问题是,我跟OP一样的教程来启用全局CORS。 不过,我也在我的AccountController.cs文件中设置了一个Action特定的CORS规则:

 [EnableCors(origins: "", headers: "*", methods: "*")] 

并得到有关原点不能为空或空string的错误。 但是错误发生在所有地方的Global.asax.cs文件中。 解决scheme是将其更改为:

 [EnableCors(origins: "*", headers: "*", methods: "*")] 

注意*在起源? 缺less这是导致Global.asax.cs文件中的错误。

希望这有助于某人。