Asp.net mvc 5 带句点的ASP.NET MVC路由值ID

Asp.net mvc 5 带句点的ASP.NET MVC路由值ID,asp.net-mvc-5,Asp.net Mvc 5,我有一个MVC5 web应用程序,其中一些ID可以包含句点字符 比如说 这个很好用 这将失败 但这很管用 类似的问题如下: 目前我找到的所有解决方案都在上面的链接中描述 由于用户只能通过菜单和网页中的链接浏览这些url,我希望ActionLink html帮助程序能够足够智能,在识别出id包含id路由值的不安全字符时,能够呈现?id=123.45 或者有没有办法强制ActionLink html助手始终在查询字符串中呈现Id路由值 更新 我找不到任何参数来强制ActionLin

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

比如说

这个很好用

这将失败

但这很管用

类似的问题如下:

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

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

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

    更新 我找不到任何参数来强制ActionLink呈现?id=query字符串参数,因此我找到了两种可能的解决方案

    解决方案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;
        }
    
        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"}
            );
    
            routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}",
            defaults: new { controller = "Home", action = "Index"}
        );
    

    更新我找不到任何参数来强制ActionLink呈现?id=查询字符串参数,因此我找到了两种可能的解决方案

    解决方案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;
        }
    
        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"}
            );
    
            routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}",
            defaults: new { controller = "Home", action = "Index"}
        );
    

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

    正如您所说,这是行不通的:

    但这将:


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

    对于我正在处理的一个WebAPI项目,我也遇到了同样的问题。你的解决方案非常有效。但是,哇,我不会想到的。谢谢,凯文。