Asp.Net WebApi2 Habilita CORS que no funciona con AspNet.WebApi.Cors 5.2.3

Traté de seguir los pasos en http://enable-cors.org/server_aspnet.html para que mi API RESTful (implementada con ASP.NET WebAPI2) funcione con solicitudes de origen cruzadas (CORS habilitado). No funciona a menos que modifique el web.config.

Instalé la dependencia de WebApi Cors:

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

Luego, en mi App_Start , tengo la clase WebApiConfig siguiente manera:

 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())); config.Services.Add(typeof(IExceptionLogger), new SimpleExceptionLogger(WebContainerManager.Get())); config.Services.Replace(typeof(IExceptionHandler), new GlobalExceptionHandler()); } } 

pero después de ejecutar la aplicación, solicito un recurso con Fiddler como: http: // localhost: 51589 / api / v1 / persons y en la respuesta no puedo ver los encabezados HTTP que debería ver, como:

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

¿Me estoy perdiendo un paso? Lo he intentado con la siguiente anotación en el controlador:

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

El mismo resultado, no CORS habilitado.

Sin embargo, si agrego lo siguiente en mi web.config (sin siquiera instalar la dependencia AspNet.WebApi.Cors), funciona:

    <!--       -->    <!--       -->  

¡Cualquier ayuda sería muy apreciada!

Gracias.

Creé un proyecto de demostración simplificado para ti.

Puede probar el Enlace API anterior desde su Fiddler local para ver los encabezados. Aquí hay una explicación.

Global.ascx

Todo lo que hace es llamar a WebApiConfig . No es más que la organización del código.

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

WebApiConfig.cs

El método clave para su aquí es el método EnableCrossSiteRequests . Esto es todo lo que necesitas hacer. EnableCorsAttribute es un atributo CORS con ámbito global .

 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); } } 

Controlador de valores

El método Get recibe el atributo EnableCors que aplicamos globalmente. El Another método anula el EnableCors global.

 public class ValuesController : ApiController { // GET api/values public IEnumerable 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 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

No necesita agregar nada especial en web.config. De hecho, así es como se ve el web.config de la demostración: está vacío.

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

Manifestación

 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); }); 
  

Solo necesitas cambiar algunos archivos. Esto funciona para mí

Global.ascx

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

WebApiConfig.cs

Todas las solicitudes tienen que llamar a este código.

 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); } } 

Algunos controladores

Nada para cambiar

Web.config

Necesita agregar controladores en su web.config

           

En el caso de la solicitud de CORS, todos los navegadores modernos responden con un verbo OPTION, y luego la solicitud real continúa. Se supone que se debe usar para solicitar confirmación al usuario en caso de una solicitud CORS. Pero en el caso de una API, si desea omitir este proceso de verificación, agregue el siguiente fragmento a 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(); } } 

Aquí solo estamos pasando el cheque al buscar el verbo OPTIONS.

Acabo de agregar encabezados personalizados a Web.config y funcionó a las mil maravillas.

En la configuración – system.webServer:

       

Tengo la aplicación de front-end y el backend en la misma solución. Para que esto funcione, necesito configurar el proyecto de servicios web (Backend) como predeterminado para que esto funcione.

Estaba usando ReST, no he intentado con nada más.

Después de algunas modificaciones en mi Web.config CORS de repente dejó de funcionar en mi proyecto Web API 2 (al menos para la solicitud OPTIONS durante la comprobación previa). Parece que necesita tener la sección que se menciona a continuación en su Web.config o, de lo contrario, el (global) EnableCorsAttribute no funcionará en las solicitudes OPTIONS. Tenga en cuenta que esta es exactamente la misma sección que Visual Studio agregará en un nuevo proyecto de Web API 2.

         

Ninguna de estas respuestas realmente funciona. Como otros señalaron, el paquete Cors solo usará el encabezado Access-Control-Allow-Origin si la solicitud tiene un encabezado Origin. Pero generalmente no se puede agregar un encabezado de origen a la solicitud porque los navegadores pueden intentar regularlo también.

Si desea una forma rápida y sucia de permitir solicitudes entre sitios a una API web, es mucho más fácil simplemente escribir un atributo de filtro personalizado:

 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); } } 

Entonces solo utilízalo en tu acción de Controlador:

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

No responderé por la seguridad de esto en general, pero probablemente sea mucho más seguro que establecer los encabezados en el archivo web.config, ya que de esta manera puede aplicarlos solo tan específicamente como los necesite.

Y, por supuesto, es simple modificar lo anterior para permitir solo ciertos orígenes, métodos, etc.

WEBAPI2: SOLUCIÓN. global.asax.cs:

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

En el explorador de soluciones, haga clic derecho en api-project. En la ventana de propiedades, configure ‘Autenticación anónima’ en Habilitado.

Espero que esto ayude a alguien en el futuro.

Acabo de experimentar este mismo problema, tratando de habilitar CORS globalmente . Sin embargo, descubrí que funciona, pero solo cuando la solicitud contiene un valor de encabezado de Origin . Si omite el valor del encabezado de origin , la respuesta no contendrá un Access-Control-Allow-Origin .

Usé un complemento de Chrome llamado DHC para probar mi solicitud GET. Me permitió agregar el encabezado Origin fácilmente.

Encontré esta pregunta porque tenía problemas con la solicitud de OPCIONES que la mayoría de los navegadores enviaban. Mi aplicación enrutaba las solicitudes OPTIONS y usaba mi IoC para construir muchos objetos y algunos lanzaban excepciones en este tipo de solicitud extraña por varias razones.

Básicamente pon una ruta de ignorar para todas las solicitudes OPTIONS si te están causando problemas:

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

Más información: Detener el procesamiento de API web OPCIONES

Espero que esto ayude a alguien en el futuro. Mi problema era que estaba siguiendo el mismo tutorial que el OP para habilitar CORS global. Sin embargo, también establecí una regla CORS específica de Acción en mi archivo AccountController.cs:

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

y estaba recibiendo errores sobre el origen no puede ser una cadena vacía o nula. PERO el error estaba sucediendo en el archivo Global.asax.cs de todos los lugares. La solución es cambiarlo a:

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

nota el * en los orígenes? Faltando eso era lo que estaba causando el error en el archivo Global.asax.cs.

Espero que esto ayude a alguien.