1

Background

In HomeController.cs I have:

[HttpGet]
public GetPerson(string name)
{
    return View(new PersonModel { ... });
}

In Global.asax.cs I have:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        "Word", "person/{name}",
         new { controller = "Home", action = "GetPerson" });

    routes.MapRoute(
        "Default", "{controller}/{action}",
        new { controller = "Home", action = "Index" });
}

In SomePage.cshtml I have, effectively, this:

@{ var name = "Winston S. Churchill"; }
<a href="@Url.Action("GetPerson", "Home", new { name })">@name</a>

Problem

If I click the link for Winston S. Churchill, I am routed to the URL http://localhost/person/Winston%20S.%20Churchill, which yields the standard 404 page:

HTTP Error 404.0 - Not Found

The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.

This only happens if the name variable contains a . (period). All my code works perfectly fine when the name is, for example, Winston Churchill.

How can I make ASP.NET MVC 3 percent-encode the . (period) in the URL?

Or, how can I make the routing work without . (period) being percent-encoded?

Unacceptable Workaround (if presented without justification)

If I change the route to the following, everything works.

routes.MapRoute(
    "Word", "person",
     new { controller = "Home", action = "GetPerson" });

However, the URL becomes http://localhost/person?name=Winston%20S.%20Churchill, which isn't what I want. I want the name in the path part of the URL, not the query.

4

1 回答 1

5

Routes which contain a period and unknown extension are interpreted by IIS as static files and not sent through the .NET pipeline. For example, the URL you cite is interpreted as a static file with a %20Churchill extension.

You can force ASP.NET to handle all requests by adding this to web.config:

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

You'll also need this, to handle name values that end with a period (as opposed to just containing one):

<system.web>
    <httpRuntime relaxedUrlToFileSystemMapping="true" />
</system.web>

All /person/{name} URLs will then be picked up by your ASP.NET code.

If you would rather not use this setting, the easiest workaround would be to use a custom encoding:

name.Replace(".","--")
于 2013-08-10T01:42:31.990 回答