37

I'm trying to get the following (and similar) urls to work in my ASP.net MVC4/WebApi project:

http://127.0.0.1:81/api/nav/SpotiFire/SpotiFire.dll

The route responsible for this url looks like this:

        config.Routes.MapHttpRoute(
            name: "Nav",
            routeTemplate: "api/nav/{project}/{assembly}/{namespace}/{type}/{member}",
            defaults: new { controller = "Nav", assembly = RouteParameter.Optional, @namespace = RouteParameter.Optional, type = RouteParameter.Optional, member = RouteParameter.Optional }
        );

It works just fine if I remove the . in the file-name, or if I add a slash behind the URL, but that also means I can't use the Url.Route-methods etc. The error I get is a generic 404-error (image below).

enter image description here

I've tried adding <httpRuntime targetFramework="4.5" relaxedUrlToFileSystemMapping="true" /> to my web.config, and I've also tried adding

<compilation debug="true" targetFramework="4.5">
  <buildProviders>
    <remove extension=".dll"/>
    <remove extension=".exe"/>
  </buildProviders>
</compilation>

And none of it seems to work. So my question is basically, how can I get this URL to work, and map correctly?

3
  • Only the last portion of a route can be optional. In the example you have shown you have made all the route parameters except project optional which obviously is not possible. Also in the url you have shown you are missing namespace and type portions of the url. Only the member portion can be optional because it is defined at the end of the route. Commented Feb 2, 2013 at 17:46
  • This is not true, and it's proven to work without problems. You can have as many parts optional as you want to. For instance, even before the change I just made in my answer, the url /api/nav/SpotiFire worked as a charm. Commented Feb 2, 2013 at 17:48
  • This also works for ASP.NET Web API 2. Commented Dec 22, 2022 at 19:46

3 Answers 3

52

You could add the following handler to the <handlers> section of your <system.webServer>:

<add 
    name="ManagedDllExtension" 
    path="api/nav/*/*.dll" 
    verb="GET" 
    type="System.Web.Handlers.TransferRequestHandler" 
    preCondition="integratedMode,runtimeVersionv4.0" 
/>

This will make all requests containing .dll be served through the managed pipeline. Also notice how I have limited them only to the GET verb to limit the performance impact.

Sign up to request clarification or add additional context in comments.

4 Comments

Brilliant, thought shouldn't this <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" /> cover that already? I'm not sure what's covered by "*.".
No, it's not covering it. You need to specify the extension. If there's an extension in the url, IIS will take over thinking that it is a static file.
This is such a fantastic answer.
@DarinDimitrov, what if we use this: path="*.*"? It works, for any kind of file, but I'm wondering if it can create side problems. Kind regards.
13

Found it. What's needed is this (and maybe some of the things I've added above in the original post):

<system.webServer>
  <modules runAllManagedModulesForAllRequests="true" />
</system.webServer>

3 Comments

I wouldn't recommend you adding this because it will have a bad side effect => all requests will now go through the managed pipeline which will have a negative impact on the performance of your application.
True, I might find a better solution in time, however, already more than 90% of requests are managed requests, so I don't think the performance-hit will be too big at all... The only thing that isn't loaded through the managed pipeline are images, and I have about 2 of them on my entire page...
Checkout my answer for the correct way to make this without activating the runAllManagedModulesForAllRequests="true".
5

My trade off was to append /end to the end of route. .'s are ignored before the last /.

The equivalent URL would be http://127.0.0.1:81/api/nav/SpotiFire/SpotiFire.dll/end.

The benefit being that you don't get a performance hit on your assets.

1 Comment

This worked for me and was the simplest solution, though I just added a / at the end.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.