我正在使用基本的CRUD操作的ASP.NET WebAPI项目.该项目在本地运行,并有一个样本数据库生活在
Windows Azure中.
到目前为止,Http GET和POST工作正常,给了我200和201.但是我正在努力使用DELETE和POST.我改变了Web.config中的处理程序,删除了WebDav,但没有一个有效.还允许CORS和各种属性,如[AcceptVerbs]不起作用.
任何想法我做错了什么?
Fiddler原始输出:
HTTP/1.1 405 Method Not Allowed Cache-Control: no-cache Pragma: no-cache Allow: GET Content-Type: application/json; charset=utf-8 Expires: -1 Server: Microsoft-IIS/8.0 X-AspNet-Version: 4.0.30319 X-SourceFiles: =?UTF-8?B?QzpcVXNlcnNcTWFyY1xPbmVEcml2ZVxEb2t1bWVudGVcRmlcVnNQcm9qZWt0ZVxONTIwMTQwODI1XE41XE41XGFwaVxwcm9kdWN0XDEwODM=?= X-Powered-By: ASP.NET Date: Sun,14 Sep 2014 15:00:43 GMT Content-Length: 75 {"Message":"The requested resource does not support http method 'DELETE'."}
Web.config文件:
<system.webServer> <validation validateIntegratedModeConfiguration="false" /> <modules runAllManagedModulesForAllRequests="true"> <remove name="WebDAVModule" /> </modules> <handlers> <remove name="WebDAV" /> <remove name="ExtensionlessUrlHandler-Integrated-4.0" /> <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT" type="System.Web.Handlers.TransferRequestHandler" resourceType="Unspecified" requireAccess="Script" preCondition="integratedMode,runtimeVersionv4.0" /> </handlers> </system.webServer>
控制器:
public class ProductController : BaseApiController { public ProductController(IRepository<Product> repo) : base(repo) { } [HttpGet] public IEnumerable<Product> Get() { //... } [HttpGet] public Product Get(int id) { //... } [HttpPost] public HttpResponseMessage Post([FromBody] Product product) { //... } [HttpPut] public HttpResponseMessage Put(int productId,[FromBody] Product product) { //.. } [HttpDelete] public HttpResponseMessage Delete(int productId) { //.. } }
路由&格式化程序:
public static void Register(HttpConfiguration config) { // Web API configuration and services // Configure Web API to use only bearer token authentication. config.SuppressDefaultHostAuthentication(); config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType)); config.Routes.MapHttpRoute( name: "Product",routeTemplate: "api/product/{id}",defaults: new {controller = "product",id = RouteParameter.Optional } ); // Custom Formatters: config.Formatters.XmlFormatter.SupportedMediaTypes.Remove( config.Formatters.XmlFormatter.SupportedMediaTypes.FirstOrDefault(t => t.MediaType == "application/xml")); var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().First(); jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); } }
解决方法
最后我发现我搞砸了控制器方法(Post和Put)中的Id(productId)的命名必须与定制路由(id)中的相同.当我将它从productId更改为id时,POST和PUT在fiddler中工作.之后,我将Web.config设置切换到默认设置.这是我改变的:
控制器:
[HttpPut] public HttpResponseMessage Put(int id,[FromBody] Product product) { //.. } [HttpDelete] public HttpResponseMessage Delete(int id) { //.. }
Web.config文件:
<system.webServer> <modules> <remove name="FormsAuthentication" /> </modules> <handlers> <remove name="ExtensionlessUrlHandler-Integrated-4.0" /> <remove name="OPTIONSVerbHandler" /> <remove name="TRACEVerbHandler" /> <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /> </handlers>