[英]HTTP PUT and DELETE not allowed by default on ASP.NET web API
[英]HTTP PUT not allowed in ASP.NET Web API
在我的Web API項目中,我無法對我的資源執行HTTP PUT
。 我已經閱讀了一些 關於 這個 問題的 類似 問題 ,並且我遵循了建議的建議。
首先,我在我的機器上完全卸載了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無擴展URL處理程序(32位和64位)並將我的應用程序從集成管道應用程序池更改為經典應用程序池。
<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
任何子類型中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'."}
我究竟做錯了什么?
顯然, 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
操作響應。 刪除默認操作可解決問題。
對我有用的是添加一個Route屬性,因為我已經為一個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);
}
我認為情況已經不是這樣了,也許這個問題現在已經解決了。 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 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” );
如果沒有設置,會出現各種奇怪的行為。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.