zoukankan      html  css  js  c++  java
  • ASP.NET MVC HttpVerbs.Delete/Put Routes not firing

    原文地址: https://weblog.west-wind.com/posts/2015/Apr/09/ASPNET-MVC-HttpVerbsDeletePut-Routes-not-firing?utm_source=tuicool&utm_medium=referral

    国内:http://www.tuicool.com/articles/Zv2EbmY

    A few times in the last weeks I’ve run into a problem where I found that DELETE operations would not fire in ASP.NET MVC controllers. I’ve been building APIs mostly with Web API until recently, but started using MVC instead with current projects in light of vNext which essentially uses the MVC model for ‘APIs’. And I ran into trouble each time with PUT and DELETE verbs not firing.

    What’s the Problem?

    To demonstrate here’s a simple action method on an MVC controller that uses Attribute routing for a delete operation:

    [Route("albums/{id}")]
    [AcceptVerbs(HttpVerbs.Delete)]
    public ActionResult DeleteAlbum(int id)
    {
        var albumBus = new AlbumBusiness();
        if (!albumBus.Delete(id, saveChanges: true, useTransaction: true))
            throw new CallbackException("Couldn't delete album: " + albumBus.ErrorMessage);
        return Json(true, JsonRequestBehavior.AllowGet);
    }

    When this route is fired I’m getting a 404 error from IIS – it’s not finding the route. However, if I change the route to a HttpVerbs.Get it runs just fine.

    What the heck is happening here?

    Missing Verbs on ExtensionlessUrlHandler

    The main culprit is the ExtensionlessUrlHandler Http handler that’s responsible for handling MVC’s Controller and Attribute routing. The default entry for this handler is defined in ApplicationHost.config doesn’t include the DELETE or PUT verb.

    Here’s what’s in my ApplicationHost.config which determines the default handler settings:

    <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." 
         verb="GET,HEAD,POST,DEBUG" 
         type="System.Web.Handlers.TransferRequestHandler"
         preCondition="integratedMode,runtimeVersionv4.0" 
         responseBufferLimit="0" />

    Note that PUT and DELETE are not among the supported verbs.

    To fix this you can add the following to your application’s web.config file:

     <configuration>
       <system.webServer>
          <handlers>
            <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
            <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." 
                 verb="GET,HEAD,POST,DEBUG,PUT,DELETE,OPTIONS" 
                 type="System.Web.Handlers.TransferRequestHandler" 
                 preCondition="integratedMode,runtimeVersionv4.0" />
          </handlers>
        </system.webServer>
    </configuration>

    And voila, PUT and DELETE now work. Yay!

    ASP.NET MVC doesn’t, Web API does

    It’s interesting to note that the problem above applies specifically to ASP.NET MVC projects. When you create a new MVC project there’s no custom handler registration made. So for MVC project or any project other than an API project you’ll have to manually add the handler – even if you add WebAPI features later.

    If you create an ASP.NET WebAPI project you do get the following in the default web.config created by the new project template:

    <system.webServer>
      <handlers>
        <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
       <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" 
             type="System.Web.Handlers.TransferRequestHandler" 
             preCondition="integratedMode,runtimeVersionv4.0" />
      </handlers>
    </system.webServer>

    For me this was probably the main reason for confusion – I expected it to ‘just work’ since I never had an issue with WebAPI. But clearly different default configuration settings are made for API vs MVC applications (so much for ‘One ASP.NET’).

    In a way I suppose this makes sense – if you’re not building API applications PUT and DELETE are unlikely to be something needed, but still it’s confusing to have things work sometimes and not others.

    Additional Issues: WebDav

    If you’re running an MVC application and you run into this issue, most likely the ExtensionlessUrlHandler is the culprit. However, if that does not resolve the issue, there are a few other things to check:

    If you have WebDav installed on your server/site, that causes a more restrictive URL/routing rules to be applied including removing the DELETE verb by default.

    < system.webServer > < security > < requestFiltering > < verbs applyToWebDAV = " false " > <add verb = " DELETE " allowed = " true "

    />

    < add verb = " PUT " allowed = " true " /> </ verbs > </ requestFiltering > </ security > </system.webServer >

    If you are using WebDav as part of your application or it’s defined at the server root, you can add additional verbs to the RequestFiltering section to explicitly allow the verbs you’re interested in through.

    Alternately if you want to disable WebDav in your specific application:

    <system.webServer>
      <modules runAllManagedModulesForAllRequests="false">
        <remove name="WebDAVModule" />
      </modules>
    </system.webServer>

    If you’re not using WebDav as part of your application (but it’s defined at the server root) you can just remove the module and the restrictions should actually go away.

    记忆力下降,日常日志
  • 相关阅读:
    剑指Offer(Java版)第五十题:牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志, 写些句子在本子上。同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看, 但却读不懂它的意思。例如,“student. a am I”
    剑指Offer(Java版)第四十九题:汇编语言中有一种移位指令叫做循环左移(ROL), 现在有个简单的任务,就是用字符串模拟这个指令的运算结果。 对于一个给定的字符序列S,请你把其循环左移K位后的序列输出。 例如,字符序列S=”abcXYZdef”,要求输出循环左移3位后的结果, 即“XYZdefabc”。是不是很简单?OK,搞定它!
    【转载】Java 内存分配全面浅析
    【记】Linux下安装JDK1.7
    【ZooKeeper】典型应用场景概览
    正则表达式工具RegexBuddy
    【基础】RandomAccess
    【JNDI】Java Naming and Directory Interface
    【AOP】Cglib动态代理实现方式
    【事务】分布式事物原理
  • 原文地址:https://www.cnblogs.com/yushuo/p/6431903.html
Copyright © 2011-2022 走看看