【问题标题】:ASP.NET MVC Route Value ID with Period带有句点的 ASP.NET MVC 路由值 ID
【发布时间】:2015-03-18 12:48:12
【问题描述】:

我有一个 MVC5 Web 应用程序,其中一些 ID 可以包含句点字符。

例如

这很好用 http://www.website.com/Employee/Details/123

这将失败 http://www.website.com/Employee/Details/123.45

但这会很好用 http://www.website.com/Employee/Details/?id=123.45

类似的问题:

目前我找到的所有解决方案都在上面的链接中描述。

  1. <httpRuntime relaxedUrlToFileSystemMapping="true" />

  2. <add name="UrlRoutingHandler" type="System.Web.Routing.UrlRoutingHandler, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" path="Remote.mvc/*" verb="GET"/>

由于用户只会通过网页中的菜单和链接浏览到这些 url,我希望 ActionLink html 帮助程序能够足够智能,以便在识别到 Id 包含不安全字符时呈现 ?id=123.45 Id 路由值。

或者有没有办法强制 ActionLink html 助手总是在查询字符串中呈现 Id 路由值?

更新 我找不到任何参数来强制 ActionLink 呈现 ?id= 查询字符串参数,所以我找到了 2 个可能的解决方案。

解决方案 1

创建一个 html 助手来生成 url。 任何改进此代码的 cmets 将不胜感激。

        public static MvcHtmlString ActionLinkSafeId(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName, object routeValues, object htmlAttributes)
    {

        var routeValuesDictionary = new RouteValueDictionary(routeValues);
        MvcHtmlString link = htmlHelper.ActionLink(linkText, actionName, controllerName, routeValues, htmlAttributes);
        if (routeValuesDictionary.ContainsKey("id") && routeValuesDictionary["id"].ToString().Contains('.'))
        {
            if (routeValuesDictionary.Count == 1)
            {
                var searchValue = string.Format("/{0}", routeValuesDictionary["id"]);
                var replaceValue = string.Format("?id={0}", routeValuesDictionary["id"]);
                link = new MvcHtmlString(link.ToString().Replace(searchValue, replaceValue));
            }
            else
            {
                var searchValue = string.Format("/{0}?", routeValuesDictionary["id"]);
                var replaceValue = string.Format("?id={0}&", routeValuesDictionary["id"]);
                link = new MvcHtmlString(link.ToString().Replace(searchValue, replaceValue));
            }
        }

        return link;
    }

解决方案 2

在您的路由配置中禁用 id 路由值。 这可以针对默认路由、特定控制器或特定控制器/动作来完成。

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

【问题讨论】:

    标签: asp.net-mvc-5


    【解决方案1】:

    另一个简单的解决方案是添加尾随 /

    正如你所说,这行不通:
    http://www.website.com/Employee/Details/123.45
    但这会:
    http://www.website.com/Employee/Details/123.45/

    我认为这是因为 IIS 试图将点之后的所有内容解释为扩展名。通过添加 / 表示不应该以这种方式处理。

    【讨论】:

    • 我遇到了同样的问题,我正在处理一个 WebAPI 项目。您的解决方案完美运行。但是,哇,我不会想到这一点。谢谢,@Kevin。
    【解决方案2】:

    更新我找不到任何参数来强制 ActionLink 呈现 ?id= 查询字符串参数,所以我找到了 2 个可能的解决方案。

    解决方案 1

    创建一个 html 助手来生成 url。任何改进此代码的 cmets 将不胜感激。

        public static MvcHtmlString ActionLinkSafeId(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName, object routeValues, object htmlAttributes)
    {
    
        var routeValuesDictionary = new RouteValueDictionary(routeValues);
        MvcHtmlString link = htmlHelper.ActionLink(linkText, actionName, controllerName, routeValues, htmlAttributes);
        if (routeValuesDictionary.ContainsKey("id") && routeValuesDictionary["id"].ToString().Contains('.'))
        {
            if (routeValuesDictionary.Count == 1)
            {
                var searchValue = string.Format("/{0}", routeValuesDictionary["id"]);
                var replaceValue = string.Format("?id={0}", routeValuesDictionary["id"]);
                link = new MvcHtmlString(link.ToString().Replace(searchValue, replaceValue));
            }
            else
            {
                var searchValue = string.Format("/{0}?", routeValuesDictionary["id"]);
                var replaceValue = string.Format("?id={0}&", routeValuesDictionary["id"]);
                link = new MvcHtmlString(link.ToString().Replace(searchValue, replaceValue));
            }
        }
    
        return link;
    }
    

    解决方案 2

    在您的路由配置中禁用 id 路由值。这可以针对默认路由、特定控制器或特定控制器/动作完成。

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

    【讨论】:

      猜你喜欢
      • 2011-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-07
      • 2019-05-10
      • 2011-07-16
      • 2015-09-06
      • 2014-06-18
      相关资源
      最近更新 更多