WebAPI traffic with period in end parameter is not working

Problem

Using WebAPI where the final parameter in the request includes period / full stop / '.'

  • For a "simple" route such as /api/values/dog.cat

    this is routed normally.
  • For a more complex route like /api/values/mammal/dog.cat

    404 is returned

My questions are, how can I get a more difficult route?


Background

All of the tests below used new projects generated from Visual Studio WebAPI templates.

I understand that my request looks like it has a file extension, so set:

<modules runAllManagedModulesForAllRequests="true">

      

So, after the StaticFile handler doesn't find an element, it will pass it to the managed handlers.

If I request /api/values/mamal/dog.cat/

(with a trailing slash) it works fine, but unfortunately we are stuck with the API contract and I cannot do it.

.NET versions

When targeting .NET4.0 and using the Visual Studio WebAPI template, the more complex route works fine.

When targeting .NET4.5 with the default WebAPI template, the more complex route returns 404.

In some production code we are targeting .NET4.5 in the .csproj file, but <compilation targetFramework="4.0"

in the web.config element (and not <httpRuntime>

), and seem to handle more complex routes, with a period in the trailing parameter.

Two scenarios

Using the default route:

config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional }
);

      

And a simple action on ValuesController

:

public string Get(string id)
{
    return string.Format("Param id: '{0}'", id);
}

      

Request /api/values/dog.cat

and routing will take you to action.

Now change the route to add an additional category parameter:

config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{category}/{id}",
    defaults: new { id = RouteParameter.Optional }
);

      

And change the endpoint to ValuesController

:

public string Get(string category, string id)
{
    return string.Format("category: {0}, id: {1}", category, id);
}

      

Request /api/values/mamal/dog.cat

and you will receive 404 not found

.

Request /api/values/mamal/dog.cat/

and action are called.

Other questions using stackoverflow

There are various similar questions on stackoverflow that have answers that look like they address this, but are not really relevant (in case you were thinking of repeating this question as a duplicate!).

For example:

This handler only processes requests that end with a period, for example /api/values/dog.cat.

, and does not account for the period inside the parameter:

<system.webServer>
  <handlers>
    <remove name="ExtensionlessUrlHandler-Integrated-4.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> 

      

In addition, the following display only deals with reserved words, not the period in the URL:

<httpRuntime relaxedUrlToFileSystemMapping="true" />

      

Possible workarounds

May upgrade to .NET4.0 which seems to work. But you don't want to do this because of the use of async / await functions.

I could presumably use something like the IIS URL Rewriter module to add a trailing slash to requests that are missing it, but I would rather get a solution based on understanding why the binding is "failing".

+3


source to share


1 answer


Having solved that by changing the web.config handlers section and the path attribute, change it from path = "*." on the path = "*"



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

+5


source







All Articles