HttpClient POST到WEB API方法返回405(方法不允许)

3
在使用IIS Express和VS 2015调试会话中,当在Postman(浏览器)中发送以下请求时,一切都工作得很完美:
POST http://localhost:51072/api/cs/processor/process

{
'code':'TEST',
  'mode':0
}

这是我的 Web API 控制器方法。
[RoutePrefix("api/cs")]
public class ProcessorController : UmbracoApiController
{...

[AllowAnonymous]
[Route("processor/process")]
[HttpPost()]
public IHttpActionResult Process([FromBody] ProcessSurvey dto)
{
    if (!HttpContext.Current.Request.IsLocal)
    {
        return Content(HttpStatusCode.Forbidden, "Not allowed to start survey from remote host.");
    }
    ProcessSurveyResponse resp = new ProcessSurveyResponse();
    switch (dto.Code)
    {
        case "ITS":
            resp = Execute(dto.Mode);
            break;
        default:
            resp.Message = "Test successful!";
            break;
    }
    return Content(HttpStatusCode.Created, resp);
}

尽管我使用完全相同的请求数据访问此方法,但它返回405。深入挖掘后,我发现内部进行了重定向(302)。但在IIS日志中找不到任何有关正在发生什么以及为什么的信息。
到目前为止,我所做的是删除WebDAV,将属性设置为Http而不是Mvc,以及所有路由配置的组合(下面是我当前的配置)。
    public static void Register(HttpConfiguration config)
    {
        // Attribute routing.
        config.MapHttpAttributeRoutes();


    config.Routes.MapHttpRoute(
        name: "DefaultApiFull",
        routeTemplate: "api/{controller}/{action}/{id}",
        defaults: new { id = RouteParameter.Optional });

    config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }

这是我的初始化方法

    GlobalConfiguration.Configure(WebApiConfig.Register); //WebApi 2 Register method

我真的不知道该怎么办...已经苦苦挣扎了两天,但我不知道还要往哪里找。

这是 HttpClient 的调用:

using (var client = new HttpClient())
            {
                client.DefaultRequestHeaders.Clear();
                client.DefaultRequestHeaders.ExpectContinue = false;
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("*/*"));
                var json = JsonConvert.SerializeObject(dto);
                StringContent content = new StringContent(json, Encoding.UTF8, "application/json");
                log.Debug("Call " + baseUrl);
                HttpResponseMessage response = await client.PostAsync("http://localhost:51072/api/cs/surveyprocessor/process/", content);
                string data = await response.Content.ReadAsStringAsync();
                if (response.IsSuccessStatusCode)
                {
                    result = JsonConvert.DeserializeObject<ProcessSurveyResponse>(data);
                }
                else
                {
                    result.Message = data;
                }
                return result;
            }

这是我的数据传输对象(DTO)

public class ProcessSurvey
{
    [JsonProperty(PropertyName = "mode")]
    public int Mode { get; set; }
    [JsonProperty(PropertyName = "code")]
    public string Code { get; set; }
    [JsonProperty(PropertyName = "customers")]
    public IList<int> Customers { get; set; }
}

有趣的是,当我通过HttpClient进行POST请求时,似乎没有到达WebApi模块...
> iisexpress.exe Information: 0 : Request, Method=GET,
> Url=http://localhost:51072/api/cs/surveyprocessor/process/?AspxAutoDetectCookieSupport=1,
> Message='http://localhost:51072/api/cs/surveyprocessor/process/?AspxAutoDetectCookieSupport=1'
> iisexpress.exe Information: 0 : Message='SurveyProcessor',
> Operation=NamespaceHttpControllerSelector.SelectController
> iisexpress.exe Information: 0 :
> Message='SSI.CSS.Serviceportal.CS.Controller.SurveyProcessorController',
> Operation=DefaultHttpControllerActivator.Create iisexpress.exe
> Information: 0 :
> Message='SSI.CSS.Serviceportal.CS.Controller.SurveyProcessorController',
> Operation=HttpControllerDescriptor.CreateController iisexpress.exe
> Information: 0 : Message='Will use same 'JsonMediaTypeFormatter'
> formatter',
> Operation=JsonMediaTypeFormatter.GetPerRequestFormatterInstance
> iisexpress.exe Information: 0 : Message='Selected
> formatter='JsonMediaTypeFormatter', content-type='application/json;
> charset=utf-8'', Operation=DefaultContentNegotiator.Negotiate
> iisexpress.exe Warning: 0 : Message='UserMessage='The requested
> resource does not support http method 'GET'.'',
> Operation=ApiControllerActionSelector.SelectAction, Status=405
> (MethodNotAllowed), Exception=System.Web.Http.HttpResponseException:
> Processing of the HTTP request resulted in an exception. Please see
> the HTTP response returned by the 'Response' property of this
> exception for details.    bei
> System.Web.Http.Controllers.ApiControllerActionSelector.ActionSelectorCacheItem.SelectAction(HttpControllerContext
> controllerContext)    bei
> System.Web.Http.Controllers.ApiControllerActionSelector.SelectAction(HttpControllerContext
> controllerContext)    bei
> System.Web.Http.Tracing.Tracers.HttpActionSelectorTracer.<>c__DisplayClass2.<System.Web.Http.Controllers.IHttpActionSelector.SelectAction>b__0()    bei
> System.Web.Http.Tracing.ITraceWriterExtensions.TraceBeginEnd(ITraceWriter
> traceWriter, HttpRequestMessage request, String category, TraceLevel
> level, String operatorName, String operationName, Action`1 beginTrace,
> Action execute, Action`1 endTrace, Action`1 errorTrace) iisexpress.exe
> Warning: 0 : Message='UserMessage='The requested resource does not
> support http method 'GET'.'',
> Operation=SurveyProcessorController.ExecuteAsync, Status=405
> (MethodNotAllowed), Exception=System.Web.Http.HttpResponseException:
> Processing of the HTTP request resulted in an exception. Please see
> the HTTP response returned by the 'Response' property of this
> exception for details.    bei
> System.Web.Http.Controllers.ApiControllerActionSelector.ActionSelectorCacheItem.SelectAction(HttpControllerContext
> controllerContext)    bei
> System.Web.Http.Controllers.ApiControllerActionSelector.SelectAction(HttpControllerContext
> controllerContext)    bei
> System.Web.Http.Tracing.Tracers.HttpActionSelectorTracer.<>c__DisplayClass2.<System.Web.Http.Controllers.IHttpActionSelector.SelectAction>b__0()    bei
> System.Web.Http.Tracing.ITraceWriterExtensions.TraceBeginEnd(ITraceWriter
> traceWriter, HttpRequestMessage request, String category, TraceLevel
> level, String operatorName, String operationName, Action`1 beginTrace,
> Action execute, Action`1 endTrace, Action`1 errorTrace)    bei
> System.Web.Http.Tracing.Tracers.HttpActionSelectorTracer.System.Web.Http.Controllers.IHttpActionSelector.SelectAction(HttpControllerContext
> controllerContext)    bei
> System.Web.Http.ApiController.ExecuteAsync(HttpControllerContext
> controllerContext, CancellationToken cancellationToken)    bei
> System.Web.Http.Tracing.Tracers.HttpControllerTracer.<ExecuteAsyncCore>d__5.MoveNext()
> --- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde ---    bei
> System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task
> task)    bei
> System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
> task)    bei
> System.Web.Http.Tracing.ITraceWriterExtensions.<TraceBeginEndAsyncCore>d__18`1.MoveNext()
> iisexpress.exe Information: 0 : Response, Status=405
> (MethodNotAllowed), Method=GET,
> Url=http://localhost:51072/api/cs/surveyprocessor/process/?AspxAutoDetectCookieSupport=1,
> Message='Content-type='application/json; charset=utf-8',
> content-length=unknown' iisexpress.exe Information: 0 :
> Operation=JsonMediaTypeFormatter.WriteToStreamAsync iisexpress.exe
> Information: 0 : Operation=SurveyProcessorController.Dispose
> 'iisexpress.exe' (CLR v4.0.30319:
> /LM/W3SVC/2/ROOT-1-131394088034503203): Loaded
> 'C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET
> Files\root\4650863f\f01d951b\App_Web_ping.aspx.5f2dec3.f9ui73ad.dll'. 
> The thread 0x2830 has exited with code 0 (0x0). The thread 0x3f10 has
> exited with code 0 (0x0). The thread 0x2104 has exited with code 0
> (0x0).

当返回状态码 405 时,如何“尝试使用完全相同的请求数据访问此方法”?这一点不清楚。展示如何使用 [mcve] 中的 HTTP 客户端来复现问题。 - Nkosi
我已经编辑了我的帖子。 - nhaberl
我在被调用的URL中看到了“surveyprocessor”,但在控制器代码中却是“processor”。这是打字错误吗?还是你调用了错误的URL? - Nkosi
抱歉,打错了...我想先缩短它。 - nhaberl
1个回答

1

在FormsAuth和SessionProvider模块中,将cookieless属性从"AutoDetect"更改为 "UseCookies",一切都按预期工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接