HttpClient POST 到 WEB API 方法 returns 405(方法不允许)
HttpClient POST to WEB API method returns 405 (Method not allowed)
在调试会话中使用 IIS Express 和 VS 2015 中的 Postman(浏览器)时,以下请求完美运行:
POST http://localhost:51072/api/cs/processor/process
{
'code':'TEST',
'mode':0
}
这是我的网络 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);
}
虽然当我尝试使用完全相同的请求数据访问此方法时它 returns 一个 405。在深入挖掘之后我发现它在内部完成了重定向 (302)。但是无法在 IIS 日志中找到有关发生的情况和原因的任何信息。
到目前为止我所做的是删除了WebDAV,属性是Http而不是Mvc,路由配置的所有星座(belkow是我现在的)
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
真的不知道该怎么办...现在挣扎了 2 天,我不知道该往哪里看。
这里是 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; }
}
有趣的是,当我 POST 通过 HttpClient 时,它似乎没有到达 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\root50863f\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).
将 FormsAuth 和 SessionProvider 模块中的 cookieless="AutoDetect" 更改为 cookieless="UseCookies" 并且一切正常。
在调试会话中使用 IIS Express 和 VS 2015 中的 Postman(浏览器)时,以下请求完美运行:
POST http://localhost:51072/api/cs/processor/process
{
'code':'TEST',
'mode':0
}
这是我的网络 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);
}
虽然当我尝试使用完全相同的请求数据访问此方法时它 returns 一个 405。在深入挖掘之后我发现它在内部完成了重定向 (302)。但是无法在 IIS 日志中找到有关发生的情况和原因的任何信息。
到目前为止我所做的是删除了WebDAV,属性是Http而不是Mvc,路由配置的所有星座(belkow是我现在的)
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
真的不知道该怎么办...现在挣扎了 2 天,我不知道该往哪里看。
这里是 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; }
}
有趣的是,当我 POST 通过 HttpClient 时,它似乎没有到达 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\root50863f\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).
将 FormsAuth 和 SessionProvider 模块中的 cookieless="AutoDetect" 更改为 cookieless="UseCookies" 并且一切正常。