net issue enable asp allow c# rest cors asp.net-web-api2

c# - issue - Asp.Net WebApi2 Enable CORS no funciona con AspNet.WebApi.Cors 5.2.3



enable cors web config (11)

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 cruzado (CORS habilitado). No funciona a menos que modifique 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<ILogManager>())); config.Services.Add(typeof(IExceptionLogger), new SimpleExceptionLogger(WebContainerManager.Get<ILogManager>())); config.Services.Replace(typeof(IExceptionHandler), new GlobalExceptionHandler()); } }

pero después de eso ejecuto 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 algún paso? He intentado con la siguiente anotación en el controlador:

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

Mismo resultado, no CORS habilitado.

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

<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>

Cualquier ayuda sería muy apreciada!

Gracias.


Acabo de agregar encabezados personalizados a Web.config y funcionó de maravilla.

En la configuración - system.webServer:

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

Tengo la aplicación 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 probado con nada más.


Acabo de experimentar este mismo problema, tratando de habilitar CORS a nivel mundial . Sin embargo, descubrí que funciona, 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 .

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


Después de algunas modificaciones en mi Web.config, CORS dejó de funcionar repentinamente en mi proyecto Web API 2 (al menos para la solicitud de OPTIONS durante la verificación previa). Parece que necesita tener la sección mencionada a continuación en su Web.config o, de lo contrario, EnableCorsAttribute (global) no funcionará en las solicitudes de OPTIONS. Tenga en cuenta que esta es exactamente la misma sección que Visual Studio agregará en un nuevo proyecto 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>


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 al usuario la confirmación 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í estamos simplemente pasando el cheque verificando el verbo OPTIONS.


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

Básicamente, coloque una ruta de ignorar para todas las solicitudes de OPCIONES si le están causando problemas:

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

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


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 nula o vacía. PERO el error estaba ocurriendo en el archivo Global.asax.cs de todos los lugares. La solución es cambiarlo a:

public IHttpActionResult Get() { System.Web.HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*"); return Ok("value"); }

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

Espero que esto ayude a alguien.


He creado un proyecto de demostración reducido 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 de alcance 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 método Another anula los EnableCors globales.

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

No necesita agregar nada especial a 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"?> <configuration> </configuration>

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

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


Nadie de la solución segura funciona para mí, así que para estar más seguro que Neeraj y más fácil que Matthew simplemente agregue: System.Web.HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");

En el método de tu controlador. Eso funciona para mi.

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


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

Si desea una forma rápida y sucia de permitir solicitudes de sitios cruzados a una API web, es realmente mucho más fácil 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); } }

Luego, úsalo en la acción de tu 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 configurar los encabezados en la web.config ya que de esta manera puede aplicarlos tan específicamente como los necesite.

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


Solo necesita cambiar algunos archivos. Esto funciona para mi.

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

Algún controlador

Nada que cambiar

Web.config

Necesita agregar controladores en su 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>


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

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

En el explorador de soluciones, haga clic con el botón derecho en api-project. En la ventana de propiedades, configure ''Autenticación anónima'' en Activado.

Espero que esto ayude a alguien en el futuro.