C#HttpClient PostAsync将204变为404
鉴于此WebApi服务:
[ActionName("KillPerson")] [HttpPost] public void KillPerson([FromBody] long id) { // Kill }
而这个HttpClient PostAsync调用:
var httpClient = new HttpClient { BaseAddress = new Uri(ClientConfiguration.ApiUrl) }; httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); var serializerSettings = new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.Objects, Formatting = Formatting.Indented, ReferenceLoopHandling = ReferenceLoopHandling.Serialize }; var serializedParameter = JsonConvert.SerializeObject(parameter, serializerSettings); var httpContent = new StringContent(serializedParameter, Encoding.UTF8, "application/json"); var response = await httpClient.PostAsync(serviceUrl, httpContent).ConfigureAwait(false); response.EnsureSuccessStatusCode();
我希望response.EnsureSuccessStatusCode(); 成功,但它会抛出404。 有趣的是,fiddler告诉med,webapi服务按预期返回204,当我调试它时,KillPerson运行没有问题。
更新:我已确定只有在客户端代码位于PCL或Silverlight 5项目中时才会发生这种情况。 如果我在Windows窗体应用程序中复制它,完全相同的代码将给出预期的204。 如果我将Windows窗体应用程序指向PCL中包含的客户端代码,它会给我404 Again。
Update2:这解决了这个问题(尽管让我感到烦恼,我不应该这样做):
[ActionName("KillPerson")] [HttpPost] public HttpResponseMessage KillPerson([FromBody] long id) { return this.Request.CreateResponse(HttpStatusCode.OK); }
这重新推出了404(小提琴手仍称204和非银光客户端运行良好)
[ActionName("KillPerson")] [HttpPost] public HttpResponseMessage KillPerson([FromBody] long id) { return this.Request.CreateResponse(HttpStatusCode.NoContent); }
更新3(已解决):最后想出来了。 似乎您可以选择在Silverlight中使用浏览器或客户端HTTP处理。 使用浏览器HTTP处理时,许多内容都不受支持 – 包括各种响应代码和标头。 在调用HttpClient之前添加这些行修复它:
WebRequest.RegisterPrefix("http://", WebRequestCreator.ClientHttp); WebRequest.RegisterPrefix("https://", WebRequestCreator.ClientHttp);
终于搞清楚了。 似乎您可以选择在Silverlight中使用浏览器或客户端HTTP处理。 使用浏览器HTTP处理时,许多内容都不受支持 – 包括各种响应代码和标头。 在调用HttpClient之前添加这些行修复它:
WebRequest.RegisterPrefix("http://", WebRequestCreator.ClientHttp); WebRequest.RegisterPrefix("https://", WebRequestCreator.ClientHttp);
将HttpResponseMessage返回类型添加到方法中是记录的方法,因此您找到的解决方案确实是最好的。
但是如果你不想以这种方式改变所有的void方法,另一种方法是添加一个委托处理程序来动态更改响应代码 – 如下所示:
public class ResponseHandler : DelegatingHandler { protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { var response = base.SendAsync(request, cancellationToken); if (request.Method == HttpMethod.Post) { response.Result.StatusCode = response.Result.IsSuccessStatusCode ? System.Net.HttpStatusCode.OK : response.Result.StatusCode; } return response; } }
注意:这将更改所有发布方法的状态代码(成功时)。 如果您只想为特定的路径/方法完成某些代码,则必须添加一些代码(如果您需要不同的后处理方法)。
- 从Javascript将文件对象传递给Web API
- ApiController可以返回带有其他对象集合的对象吗?
- 使用MultipartFormDataStreamProvider和ReadAsMultipartAsync
- 如何在ASP.NET WebApi的每个请求上对JWT令牌应用自定义validation?
- 为什么只有在我打开Fiddler时才能在ASP.NET中调用API?
- 任何人都可以使用示例客户端应用程序解释IExceptionHandler的工作流程
- 从Web APIurl中删除“api”前缀
- 用于generics类型的ASP.NET Web API模型绑定器
- 如何使用Web API Get方法返回图像