Wenn ich einen put an meine API senden, bekomme ich zuerst die Methode OPTIONS und einen Fehler. Es trifft dann wieder meine ausgewählte Aktionsmethode und es enthält die Put-Info.CORS Ausgabe auf Put
public HttpActionDescriptor SelectAction(HttpControllerContext controllerContext)
{
var request = controllerContext.Request;
if (request.IsInspectRequest())
{
var simulate = new ActionSelectSimulator();
request.Properties[RequestHelper.ActionCache] = simulate.Simulate(controllerContext);
}
var selectedAction = _innerSelector.SelectAction(controllerContext);
return selectedAction;
}
Ich habe eine Klasse, die meine Preflight-Anfrage behandelt.
public class XHttpMethodOverrideHandler : DelegatingHandler
{
static readonly string[] httpOverrideMethods = { "PUT", "DELETE" };
static readonly string[] accessControlAllowMethods = { "POST", "PUT", "DELETE" };
static readonly string httpMethodOverrideHeader = "X-HTTP-Method-Override";
static readonly string ORIGIN_HEADER = "ORIGIN";
static readonly string accessControlAllowOriginHeader = "Access-Control-Allow-Origin";
static readonly string accessControlAllowMethodsHeader = "Access-Control-Allow-Methods";
static readonly string accessControlAllowHeadersHeader = "Access-Control-Allow-Headers";
protected override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
{
try
{
if (request.Method == HttpMethod.Post && request.Headers.Contains(httpMethodOverrideHeader))
{
var httpMethod = request.Headers.GetValues(httpMethodOverrideHeader).FirstOrDefault();
if (httpOverrideMethods.Contains(httpMethod, StringComparer.InvariantCultureIgnoreCase))
request.Method = new HttpMethod(httpMethod);
}
var httpResponseMessage = base.SendAsync(request, cancellationToken);
if (request.Method == HttpMethod.Options && request.Headers.Contains(ORIGIN_HEADER))
{
httpResponseMessage.Result.Headers.Add(accessControlAllowOriginHeader, request.Headers.GetValues(ORIGIN_HEADER).FirstOrDefault());
httpResponseMessage.Result.Headers.Add(accessControlAllowMethodsHeader, String.Join(", ", accessControlAllowMethods));
httpResponseMessage.Result.Headers.Add(accessControlAllowHeadersHeader, httpMethodOverrideHeader);
httpResponseMessage.Result.StatusCode = HttpStatusCode.OK;
}
else if (request.Headers.Contains(ORIGIN_HEADER))
httpResponseMessage.Result.Headers.Add(accessControlAllowOriginHeader, request.Headers.GetValues(ORIGIN_HEADER).FirstOrDefault());
return httpResponseMessage;
}
catch (Exception ex)
{
ILoggerService logger = IocContainer.Container.TryGetInstance<ILoggerService>();
if (logger != null)
{
logger.Error(ex);
}
return Task.FromResult<HttpResponseMessage>(request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex));
}
Ich habe auch meinen webconfig hinzugefügt
<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>
Wenn ich meine Put Ajax-Aufruf senden erhalte ich einen Fehler. Es trifft meine Methode und führt meine Aktion aus, aber es sendet einen Fehler. Wenn ich die Put-Anfrage per Postbote abschicke, habe ich kein Problem. Wenn ich es vom Client sende, erhalte ich einen Fehler, weil die erste Methode {OPTIONS} ist. Was vermisse ich? Hier ist mein Ajax
setzen$.ajax({
url: "http://localhost:61148/api/mycontroller",
contentType: "application/x-www-form-urlencoded; charset=UTF-8",
async: true,
type: "PUT",
data: sendData,
datatype: 'json',
crossDomain: true,
success: function() {