自动URL参数编码失败

Tim*_*lds 1 c# asp.net-mvc asp.net-mvc-routing

背景

HomeController.cs我有:

[HttpGet]
public GetPerson(string name)
{
    return View(new PersonModel { ... });
}
Run Code Online (Sandbox Code Playgroud)

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" });
}
Run Code Online (Sandbox Code Playgroud)

SomePage.cshtml我有,有效的做法是:

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

问题

如果单击Winston S. Churchill的链接,则会被定向到URL http://localhost/person/Winston%20S.%20Churchill,该URL 产生标准的404页面:

HTTP错误404.0-找不到

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

仅当name变量包含一个.(句点)时,才会发生这种情况。例如,名称为时,我的所有代码都可以正常工作Winston Churchill

如何使ASP.NET MVC 3编码.URL中的(句点)?

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

不可接受的解决方法(如果没有理由提出)

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

routes.MapRoute(
    "Word", "person",
     new { controller = "Home", action = "GetPerson" });
Run Code Online (Sandbox Code Playgroud)

但是,URL变成了http://localhost/person?name=Winston%20S.%20Churchill,这不是我想要的。我想要nameURL的路径部分,而不是查询。

Jam*_*mes 5

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

您可以通过将ASP.NET添加到来强制ASP.NET处理所有请求web.config

<system.webServer>
  <modules runAllManagedModulesForAllRequests="true" />
</system.webServer>
Run Code Online (Sandbox Code Playgroud)

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

<system.web>
    <httpRuntime relaxedUrlToFileSystemMapping="true" />
</system.web>
Run Code Online (Sandbox Code Playgroud)

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

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

name.Replace(".","--")
Run Code Online (Sandbox Code Playgroud)

  • 同样,尽管这对于`Winston S. Churchill`(我刚刚尝试过)有效,但对于`Albert Gore Jr.`(注末结尾)却失败了。 (2认同)
  • 没有安全问题,但这意味着ASP.NET将尝试处理所有请求,以便实际上是静态文件(图像,CSS等)的加载时间要短一点。实际上,您不太可能会注意到差异。要解决终止期的问题,请尝试在&lt;system.web&gt;中添加`&lt;httpRuntime RelaxedUrlToFileSystemMapping =“ true” /&gt;`。 (2认同)