当我向我的Api发送一个put我首先得到方法OPTIONS和一个错误。然后它再次点击我的选择操作方法,它包含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;
}
我有一个处理我的预检请求的班级。
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));
}
我也加入了我的webconfig
<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>
当我发送我的Put Ajax电话时,我收到一个错误。它命中我的方法并执行我的操作,但它发送错误。如果我通过邮递员发送放置请求,那么我没有问题。如果我从客户端发送它我得到一个错误,因为它得到的第一个方法是{OPTIONS}。我错过了什么? 这是我的Ajax put
$.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 () {
答案 0 :(得分:1)
我在其他几个问题中找到了答案。解决方案很简单,很痛。如果您遇到此问题,请在控制器中添加选项方法。
public HttpResponseMessage Options()
{
var response = new HttpResponseMessage
{
StatusCode = HttpStatusCode.OK
};
return response;
}