在我的Web API项目中,我无法对我的资源执行HTTP PUT
。我通读了some similar questions on this problem并且我遵循了建议的建议。
首先,我在我的机器上完全卸载了WebDAV(Windows 7 64位),然后重新启动了我的机器。
其次,WebDAV处理程序在我的web.config
中被指定为已删除,并且HTTP PUT
动词被指定为允许无扩展URL处理程序。
<modules runAllManagedModulesForAllRequests="false">
<remove name="WebDAVModule"/>
</modules>
<handlers>
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="WebDAV"/>
<add name="ExtensionlessUrlHandler-Integrated-4.0"
path="*."
verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS"
type="System.Web.Handlers.TransferRequestHandler"
resourceType="Unspecified"
requireAccess="Script"
preCondition="integratedMode,runtimeVersionv4.0" />
<add name="AttributeRouting" path="routes.axd" verb="*" type="AttributeRouting.Web.Logging.LogRoutesHandler, AttributeRouting.Web" />
</handlers>
我甚至尝试添加ISAPI Extensionless URL Handler(32位和64位)并将我的应用程序从集成管道App Pool更改为经典App Pool。
<add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit"
path="*."
verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS"
modules="IsapiModule"
scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll"
preCondition="classicMode,runtimeVersionv4.0,bitness32"
responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit"
path="*."
verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS"
modules="IsapiModule"
scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll"
preCondition="classicMode,runtimeVersionv4.0,bitness64"
responseBufferLimit="0" />
我目前正在使用Thinktecture IdentityModel来启用跨源资源共享(CORS)支持。为了我的理智,我选择了启用所有内容的核选项,以确保实际允许HTTP PUT
。
config.RegisterGlobal(httpConfig);
config.ForAllResources()
.ForAllOrigins()
.AllowAllMethods()
.AllowAllRequestHeaders();
Attribute Routing NuGet包配置为从当前程序集和ApiController
的任何子类型中选取所有路由。
config.AddRoutesFromAssembly(Assembly.GetExecutingAssembly());
config.AddRoutesFromControllersOfType<ApiController>();
我的资源也正确指定了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'."}
我做错了什么?
答案 0 :(得分:19)
显然,AttributeRouting
中存在一个已知问题,其中HttpPut
方法目前在ASP.NET Web API中不起作用。
currently accepted workaround是将适当的动词添加到路线上,直到出现正确的修复:
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() {}
答案 1 :(得分:12)
仔细检查您使用的是 [HttpPut] System.Web.Http 。
在某些情况下,您最终可以使用System.Web.Mvc。
中的属性这导致了我们的405s。
答案 2 :(得分:4)
我遇到了同样的错误,并将其追溯到我定义的自定义路线:
config.Routes.MapHttpRoute(
name: "SomeCall",
routeTemplate: "api/somecall/{id}",
defaults: new { controller = "SomeCall", action = "Get" }
);
此处的问题是 action = "Get"
,它阻止同一URI的PUT
操作作出响应。删除默认操作可解决问题。
答案 3 :(得分:3)
对我来说有用的是添加一个路由属性,因为我已经为一个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<Transaction>(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<Transaction>(HttpStatusCode.InternalServerError, transaction);
}
答案 4 :(得分:0)
我认为情况已经不是这样了,也许这个问题现在已经解决了。 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代码
<div ng-app="myApp" ng-controller="HttpPutController">
<h2>AngularJS Put request </h2>
<form ng-submit="UpdateData()">
<p>First Name: <input type="text" name="firstName" ng-model="firstName" required /></p>
<p>Last Name: <input type="text" name="lastName" ng-model="lastName" required /></p>
<p>Age : <input type="number" name="age" ng-model="age" required /></p>
<input type="submit" value="Submit" />
<hr />
{{ ServerResponse }}
</form></div>
ASP.NET MVC Web API控制器操作方法
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);
}
}
(更改要发送请求的网址) 当我们点击“提交”按钮时,它会将HttpPut请求发送到&#39; / api / default&#39; (DefaultController)声明了PutDataResponse操作方法。将调用此方法,用户将获得其响应。
此解决方案最初编写为here
答案 5 :(得分:0)
对我来说,这是因为我没有在我的http客户端请求的json内容字符串中设置媒体类型:
new StringContent(json,Encoding.UTF32,&#34; application / json&#34; );
如果没有设置,会出现各种奇怪的行为。
答案 6 :(得分:-1)
就我而言,我在邮递员中放入了一个参数 ID:
http://localhost:55038/api/documento/pruebadetallecatalogo?id=100
但是,我将 url 请求更改为:
http://localhost:55038/api/documento/pruebadetallecatalogo/100
这对我有用!!!