ASP.NET MVC - Routing - an action with file extension

19,090

Solution 1

You need to map requests for your XML files to TransferRequestHandler in web.config. Otherwise IIS will handle the request.

Jon Galloway explains how to do this here.

In summary, you add this element to location/system.webServer/handlers in your web.config:

<add name="XmlFileHandler" path="*.xml" verb="GET" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />

Solution 2

The problem is that IIS will handle the .xml file as a static file and will by default not route the XML file through your MVC application. IIS handles the request and your MVC code never gets a change to route to this file. There are a few ways around this.

I've found the easiest way to handle this by using the IIS Rewrite module to rewrite the URL from static file URL(s) to an MVC route:

<system.webServer>
  <rewrite>
    <rules>
      <rule name="Live Writer Manifest">
        <match url="*.xml"/>
        <action type="Rewrite" url="route/xmlfilehandler"/>
      </rule>
    </rules>
  </rewrite>
</system.webServer>

Make sure you have the IIS Rewrite Module installed (separate install from the Platform Installer). If you already are using the Rewrite handler this is the most efficient solution.

As pointed out above by Ben Foster and Jon Galloway's post, you can also map the TransferRequestHandler at your specific path you want to route. For compactness here's what you need to add to your web.config:

<system.webServer>
  <handlers>
     <add name="Windows Live Writer Xml File Handler"
       path="wlwmanfest.xml"
       verb="GET" type="System.Web.Handlers.TransferRequestHandler"
       preCondition="integratedMode,runtimeVersionv4.0" responseBufferLimit="0" 
     />
  </handlers>
</system.webServer>

You can then use an Attribute Route to handle .xml file Urls. For example:

[Route("blog/wlwmanifest.xml")]
public ActionResult LiveWriterManifest() {... }

More info in this blog post: http://weblog.west-wind.com/posts/2015/Nov/13/Serving-URLs-with-File-Extensions-in-an-ASPNET-MVC-Application

Share:
19,090
Jakub Holovsky
Author by

Jakub Holovsky

My LinkedIn profile.

Updated on June 05, 2022

Comments

  • Jakub Holovsky
    Jakub Holovsky almost 2 years

    is there a way to achieve calling URL http://mywebsite/myarea/mycontroller/myaction.xml This would basically "fake" requesting a file but the result would be an action operation that would serve a file created dynamically?

    I tried this:

    context.MapRoute(
                    "Xml_filename",
                    "Xml/{controller}/{action}.xml"
                );
    

    but whenever there is a filextension in the URL the routing fails and behaves as I was requesting a file directly.

    I suspect this might be because of using extension less url handler.

    <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" />
    

    Thank you for any suggestions.

    Jakub

  • Jakub Holovsky
    Jakub Holovsky about 10 years
    Hey, the file doesn't exist on the file server. We are serving the XML output dynamically on a view.
  • justisb
    justisb over 8 years
    Relevant snippet: <add name="XmlFileHandler" path="*.xml" verb="GET" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
  • Adam Marshall
    Adam Marshall over 5 years
    Just for clarity, Jon Galloway's article instructs you to add a route to the RouteCollection, but you can use Attribute Routing solely instead, as Rick Strahl states in his answer
  • eri0o
    eri0o about 4 years
    Links disappear from time to time, please add the relevant info in the answer.
  • The Red Pea
    The Red Pea almost 3 years
    Rick Strahl describes a similar approach (adding a handler of type TransferRequestHandler) here (oops I realized Rick Strahl actually posted this answer below!)