ASP.NET Web API中不允许HTTP PUT
在我的Web API项目中,我无法对我的资源执行HTTP PUT
。 我已经阅读了一些 关于 这个 问题的 类似 问题 ,并且我遵循了建议的建议。
首先,我在我的机器上完全卸载了WebDAV(Windows 7 64位),然后重新启动了我的机器。
其次,WebDAV处理程序在我的web.config
被指定为已删除,并且HTTP PUT
动词被指定为允许无扩展URL处理程序。
我甚至尝试添加ISAPI无扩展URL处理程序(32位和64位)并将我的应用程序从集成管道应用程序池更改为经典应用程序池。
我目前正在使用Thinktecture IdentityModel来启用跨源资源共享(CORS)支持。 为了我的理智,我已经选择了启用所有内容的核选项,以确保实际允许HTTP PUT
。
config.RegisterGlobal(httpConfig); config.ForAllResources() .ForAllOrigins() .AllowAllMethods() .AllowAllRequestHeaders();
Attribute Routing NuGet包配置为从当前程序集和ApiController
任何子类型中ApiController
所有路由。
config.AddRoutesFromAssembly(Assembly.GetExecutingAssembly()); config.AddRoutesFromControllersOfType();
我的资源也正确指定了PUT
属性。
[PUT("/API/Authenticate/Link/{key}/{identifier}")] public Boolean LinkUser(Guid key, String identifier) { ... }
我在这个问题上查看的每个资源都推荐了相同的东西:卸载WebDAV,禁用WebDAV处理程序并确保正确配置了Extensionless URL处理程序。 我已经做了所有这些,但它仍然无效。
在小提琴手中,我得到以下内容:
PUT https://localhost/Test/API/Authenticate/Link/Foo/Bar {"Message":"The requested resource does not support http method 'PUT'."}
我究竟做错了什么?
显然, AttributeRouting
存在一个已知问题,其中HttpPut
方法目前在ASP.NET Web API中不起作用。
当前接受的解决方法是在路由上添加适当的动词,直到出现正确的修复:
Web API RC密封了底层框架进行路由检测的重要接口。 虽然界面现已公开,但直到vNext才会发布更改。 所以这里有一些解决方法:
- 将AR属性与System.Web.Http中的HttpGet,HttpPost,HttpPut或HttpDelete属性结合使用:
[GET("some/url"), HttpGet] public string Method1() {} [PUT("some/url"), HttpPut] public string Method2() {} [POST("some/url"), HttpPost] public string Method3() {} [DELETE("some/url"), HttpDelete] public string Method4() {}
仔细检查您是否正在使用System.Web.Http中的 [HttpPut] 。
在某些情况下,您最终可以使用System.Web.Mvc中的属性。
这导致我们405s。
我有同样的错误,并将其追溯到我定义的自定义路由,如下所示:
config.Routes.MapHttpRoute( name: "SomeCall", routeTemplate: "api/somecall/{id}", defaults: new { controller = "SomeCall", action = "Get" } );
这里的问题是action = "Get"
,它阻止了相同URI的PUT
操作响应。 删除默认操作可解决问题。
对我有用的是添加一个路由属性,因为我已经为一个被重载的GET请求定义了一个,如下所示:
// GET api/Transactions/5 [Route("api/Transactions/{id:int}")] public Transaction Get(int id) { return _transactionRepository.GetById(id); } [Route("api/Transactions/{code}")] public Transaction Get(string code) { try { return _transactionRepository.Search(p => p.Code == code).Single(); } catch (Exception Ex) { System.IO.File.WriteAllText(@"C:\Users\Public\ErrorLog\Log.txt", Ex.Message + Ex.StackTrace + Ex.Source + Ex.InnerException.InnerException.Message); } return null; }
所以我为PUT添加了:
// PUT api/Transactions/5 [Route("api/Transactions/{id:int}")] public HttpResponseMessage Put(int id, Transaction transaction) { try { if (_transactionRepository.Save(transaction)) { return Request.CreateResponse(HttpStatusCode.Created, transaction); } } catch (Exception Ex) { System.IO.File.WriteAllText(@"C:\Users\Public\ErrorLog\Log.txt", Ex.Message + Ex.StackTrace + Ex.Source + Ex.InnerException.InnerException.Message); } return Request.CreateResponse (HttpStatusCode.InternalServerError, transaction); }
我认为情况已经不是这样了,也许这个问题现在已经解决了。 ASP.NET MVC Web API现在允许$ http.put,这里是要测试的代码。
AngularJS脚本代码
$scope.UpdateData = function () { var data = $.param({ firstName: $scope.firstName, lastName: $scope.lastName, age: $scope.age }); $http.put('/api/Default?'+ data) .success(function (data, status, headers) { $scope.ServerResponse = data; }) .error(function (data, status, header, config) { $scope.ServerResponse = htmlDecode("Data: " + data + "\n\n\n\nstatus: " + status + "\n\n\n\nheaders: " + header + "\n\n\n\nconfig: " + config); }); };
Html代码
AngularJS Put request
ASP.NET MVC Web API Controller操作方法
public class DefaultController : ApiController { public HttpResponseMessage PutDataResponse(string firstName, string lastName, int age) { string msg = "Updated: First name: " + firstName + " | Last name: " + lastName + " | Age: " + age; return Request.CreateResponse(HttpStatusCode.OK, msg); } }
(更改要发送请求的URL)当我们单击Submit按钮时,它会将HttpPut请求发送到’/ api / default’(DefaultController),其中声明了PutDataResponse操作方法。 将调用此方法,用户将获得其响应。
这个解决方案最初写在这里
对我来说,这是因为我没有在我的http客户端请求的json内容字符串中设置媒体类型:
new StringContent(json,Encoding.UTF32, “application / json” );
如果没有设置,会出现各种奇怪的行为。