带有句点的ASP.NET MVC路由值ID

时间:2015-01-20 10:19:40

标签: asp.net-mvc-5

我有一个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"/>

  3. 由于用户只会通过网页中的菜单和链接浏览这些网址,我希望ActionLink html帮助程序可以足够聪明地呈现?id = 123.45,当它识别出Id包含不安全的字符时Id路线值。

    或者有没有办法强制ActionLink html帮助器始终在查询字符串中呈现Id路由值?

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

    解决方案1 ​​

    创建一个html帮助器来生成url。 任何有关此代码改进的意见将不胜感激。

            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 route值。 这可以针对默认路由,特定控制器或特定控制器/操作完成。

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

2 个答案:

答案 0 :(得分:5)

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

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

我认为这样做的原因是IIS试图将点后的所有内容解释为扩展名。通过添加/表示不应该这样对待。

答案 1 :(得分:0)

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

解决方案1 ​​

创建一个html帮助器来生成url。任何有关此代码改进的意见将不胜感激。

    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 route值。这可以针对默认路由,特定控制器或特定控制器/操作完成。

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