简体   繁体   English

PUT和Delete不能与Windows Azure上的ASP.NET WebAPI和数据库一起使用

[英]PUT and Delete not working with ASP.NET WebAPI and Database on Windows Azure

I'm working on a ASP.NET WebAPI project with basic CRUD operations. 我正在使用基本的CRUD操作开发ASP.NET WebAPI项目。 The project runs locally and has a sample database living inside Windows Azure. 该项目在本地运行,并在Windows Azure中有一个示例数据库。

So far, the Http GET and POST works fine, giving me a 200 and 201. But I'm struggling with DELETE and POST. 到目前为止,Http GET和POST工作正常,给我200和201.但我正在努力与DELETE和POST。 I changed the handlers in the Web.config, removed WebDav, but none of this worked. 我更改了Web.config中的处理程序,删除了WebDav,但这些都没有用。 Also enabling CORS and all sorts of Attributes like [AcceptVerbs] didn't work. 同时启用CORS和[AcceptVerbs]等各种属性也不起作用。

Any idea what I am doing wrong? 知道我做错了什么吗?

Fiddler Raw Output: 提琴手原始输出:

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: 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>

Controller: 控制器:

 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)
        {
            //..
        }

    }

Routing & Formatters: 路由和格式化程序:

 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();
    }
}

Finally I found what I messed up. 最后我发现了我搞砸了什么。 The naming of the Id (productId) in both controller methods (Post and Put) must be the same as in the customized routing (id). 两种控制器方法(Post和Put)中Id(productId)的命名必须与自定义路由(id)中的命名相同。 When I changed it from productId to id both POST and PUT worked in fiddler. 当我将它从productId更改为id时,POST和PUT都在fiddler中工作。 After that I switched back my Web.config settings to the default one. 之后,我将Web.config设置切换回默认设置。 This is what I changed: 这是我改变的:

Controller: 控制器:

    [HttpPut]
    public HttpResponseMessage Put(int id, [FromBody] Product product)
    {
        //..
    }

    [HttpDelete]
    public HttpResponseMessage Delete(int id)
    {
        //..
    }

Web.config: 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>

The "Attribute Routing in ASP.NET Web API 2" (20-Jan-2014) article tells us the following; “ASP.NET Web API 2中的属性路由”(2014年1月20日)文章告诉我们以下内容;

Routing is how Web API matches a URI to an action. 路由是Web API将URI与操作匹配的方式。 Web API 2 supports a new type of routing, called attribute routing. Web API 2支持一种新类型的路由,称为属性路由。

( See: "Attribute Routing in ASP.NET Web API 2" ) (请参阅: “ASP.NET Web API 2中的属性路由”

So, as of Web API 2, you can also fix it by adding the route attribute [to the method in question] with the placeholder named as you wish. 因此,从Web API 2开始,您还可以通过使用您希望命名的占位符添加路径属性[到相关方法]来修复它。

[HttpDelete]
[Route("api/product/{productId}")]
public HttpResponseMessage Delete(int productId)
{
    if (values.Count > productId) {
        values.RemoveAt(productId);
    }
}

Tested this in my own code, because I got hit with the same problem, and it worked like a charm! 在我自己的代码中测试过,因为我遇到了同样的问题,它就像一个魅力!

Try adding this below code in your WebConfig file: 尝试在WebConfig文件中添加以下代码:

<system.webServer>
<handlers>
  <remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
  <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
  <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
  <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" />
  <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>

I also got the same issue, by doing this it got resolved! 我也遇到了同样的问题,通过这样做,它得到了解决!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM