asp.net-web-api - net - enable cors web config
mvc webapi cross domain post (2)
Respuestas a sus preguntas, respectivamente:
- El estado 204 no es un error, lo que significa que no hay contenido que devolver, pero todo está bien. Aquí está la definición de 204 en RFC2616
10.2.5 204 Sin contenido
El servidor ha cumplido la solicitud pero no necesita devolver un cuerpo de entidad, y puede querer devolver metainformación actualizada. La respuesta PUEDE incluir metainformación nueva o actualizada en forma de encabezados de entidad, que de estar presentes DEBERÍAN asociarse con la variante solicitada.
Si el cliente es un agente de usuario, NO DEBERÍA cambiar su vista del documento de la que provocó el envío de la solicitud. Esta respuesta está principalmente destinada a permitir la entrada de acciones sin provocar un cambio en la vista del documento activo del usuario del usuario, aunque cualquier metainformación nueva o actualizada DEBERÍA aplicarse al documento que se encuentra actualmente en la vista activa del agente del usuario.
La respuesta 204 NO DEBE incluir un cuerpo de mensaje, y por lo tanto siempre termina con la primera línea vacía después de los campos de encabezado.
¿Podrías expresar cuál es el error que conociste? ASP.NET Web API actualmente no tiene un formateador JSONP fuera de la caja. Aquí hay una tercera parte de implementación:
En la API web, la forma en que se refiere a una Respuesta no es a través de HttpContext. Hay múltiples formas de acceder.
La primera opción es definir la acción return HttpResponse directamente.
public HttpResponseMessage Get(int id)
{
var response = this.Request.CreateResponse();
response.StatusCode = HttpStatusCode.OK;
response.Headers.Add("Access-Control-Allow-Origin", "*");
return response;
}
La segunda opción es usar ActionFilter:
// define action filter for cross domain
public class CrossDomainActionFilter : ActionFilterAttribute
{
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
bool needCrossDomain = true;
if (needCrossDomain)
{
actionExecutedContext.Response.Headers.Add("Access-Control-Allow-Origin", "*");
}
base.OnActionExecuted(actionExecutedContext);
}
}
// At Controller
// GET api/values/5
[CrossDomainActionFilter]
public string Get(int id)
{
return "value";
}
La última opción es usar MessageHandler :
public class CrossDomainMessageHandler : DelegatingHandler
{
protected async override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request,
CancellationToken cancellationToken)
{
var response = await base.SendAsync(request, cancellationToken);
response.Headers.Add("Access-Control-Allow-Origin", "*");
return response;
}
}
Posible duplicado:
CORS con WebAPI para XmlHttpRequest
Estoy tratando de implementar la publicación de ajax de dominios cruzados en mi proyecto webApi. Tuve algunos problemas con eso:
1. Siempre recibí un error de 204 hasta que cambié mi acción webapi de
public void submit(Submission model)
a
public bool submit(Submission model)
no sé por qué, pero ahora 200 OK
estado 200 OK
2. Aún mi devolución de llamada de error de ajax.
3. Hace mucho tiempo resolví este tipo de error de publicación entre dominios al agregar
HttpContext.Response.AddHeader("Access-Control-Allow-Origin", "*");
a mi controlador. Pero ahora en webApi soy inherente a : ApiController
y este truco no funciona. Me muestra el Error an object reference is required for the non-static field, method, or property"System.Web.HttpContext.Response.get"
compilador. Error an object reference is required for the non-static field, method, or property"System.Web.HttpContext.Response.get"
He intentado publicar a través de dataType: ''JSONP''
pero obtengo el modelo nulo.
Aquí va la solicitud de Javascript:
var model = { "type": $("#model-type").val(), "subject": $("#subject-text").val(), "body": $("#body-text").val() }; $.ajax({ type: "POST", dataType: ''JSONP'', url: $("#submit-url").val(), data: model, success: function () { alert("Succesfully submitted"); }, error: function () { alert("Error..."); } });
¿Qué estoy haciendo mal?
SOLUCIONADO
Gracias a todos por ayudarme. Encontré una solución en uno de los enlaces de comentarios. Utilicé el siguiente enfoque, que me parece bastante simple.
Fuente:
Implementación de soporte CORS en ASP.NET Web APIs
Lo que hice:
1. Creé una nueva Clase en mi proyecto: CorsHandler.cs
y simplemente CorsHandler.cs
y pegué el siguiente código:
public class CorsHandler : DelegatingHandler
{
const string Origin = "Origin";
const string AccessControlRequestMethod = "Access-Control-Request-Method";
const string AccessControlRequestHeaders = "Access-Control-Request-Headers";
const string AccessControlAllowOrigin = "Access-Control-Allow-Origin";
const string AccessControlAllowMethods = "Access-Control-Allow-Methods";
const string AccessControlAllowHeaders = "Access-Control-Allow-Headers";
protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
bool isCorsRequest = request.Headers.Contains(Origin);
bool isPreflightRequest = request.Method == HttpMethod.Options;
if (isCorsRequest)
{
if (isPreflightRequest)
{
return Task.Factory.StartNew(() =>
{
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
response.Headers.Add(AccessControlAllowOrigin, request.Headers.GetValues(Origin).First());
string accessControlRequestMethod = request.Headers.GetValues(AccessControlRequestMethod).FirstOrDefault();
if (accessControlRequestMethod != null)
{
response.Headers.Add(AccessControlAllowMethods, accessControlRequestMethod);
}
string requestedHeaders = string.Join(", ", request.Headers.GetValues(AccessControlRequestHeaders));
if (!string.IsNullOrEmpty(requestedHeaders))
{
response.Headers.Add(AccessControlAllowHeaders, requestedHeaders);
}
return response;
}, cancellationToken);
}
else
{
return base.SendAsync(request, cancellationToken).ContinueWith(t =>
{
HttpResponseMessage resp = t.Result;
resp.Headers.Add(AccessControlAllowOrigin, request.Headers.GetValues(Origin).First());
return resp;
});
}
}
else
{
return base.SendAsync(request, cancellationToken);
}
}
}
- Abrí mi
Global.asax
y modifiquéApplication_Start
:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
GlobalConfiguration.Configuration.MessageHandlers.Add(new CorsHandler());
}
Presta atención a la última línea en acción.
Este enfoque es compatible con MVC3 y .NET 4.0. Funciona muy bien, ahora puedo manejar callbacks de "éxito" y "error" en ajax.
Si desea enviar información a otro dominio desde ajax, entonces necesita usar jsonp (tenga en cuenta que esto solo funciona con solicitudes de solicitud, no solicitudes de publicación). Otra alternativa (si tiene el control de ambos dominios) es usar ARR (enrutamiento de solicitud de aplicaciones) para engañar al navegador y hacerle pensar que la solicitud es local y luego usar ARR para reescribir la solicitud a otro dominio. Usando esta técnica puedes usar simples ajax get y posts como normal.