自动URL参数编码失败

时间:2013-08-10 01:22:47

标签: c# asp.net-mvc asp.net-mvc-routing

背景

HomeController.cs我有:

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

Global.asax.cs我有:

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" });
}

SomePage.cshtml中,我实际上有:

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

问题

如果我点击Winston S. Churchill的链接,我将被路由到网址http://localhost/person/Winston%20S.%20Churchill,这会产生标准的404页面:

  
    
      

HTTP错误404.0 - 未找到

             

您要查找的资源已被删除,名称已更改或暂时不可用。

    
  

仅当name变量包含.(句号)时才会发生这种情况。例如,{{1}名称时,我的所有代码都可以正常运行}。

如何让ASP.NET MVC对URL中的Winston Churchill(句点)进行3%编码?

或者,如何在没有.(句号)百分比编码的情况下使路由工作?

不可接受的解决方法(如无正当理由)

如果我将路线更改为以下内容,一切正常。

.

但是,网址变为routes.MapRoute( "Word", "person", new { controller = "Home", action = "GetPerson" }); ,这不是我想要的。我想在URL的路径部分中使用http://localhost/person?name=Winston%20S.%20Churchill,而不是查询。

1 个答案:

答案 0 :(得分:4)

包含句点和未知扩展名的路由被IIS解释为静态文件,而不是通过.NET管道发送。例如,您引用的网址被解释为具有%20Churchill扩展名的静态文件。

您可以强制ASP.NET处理所有请求,方法是将其添加到web.config

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

您还需要这个,以处理以句点结尾的name值(而不是只包含一个):

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

然后,您的ASP.NET代码将获取所有/person/{name}个网址。

如果您不想使用此设置,最简单的解决方法是使用自定义编码:

name.Replace(".","--")