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

ASP.NET MVC Route Value ID with Period

我有一个 MVC5 网络应用程序,其中某些 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

这里有类似的问题:

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

  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"/>

由于用户只会通过菜单和网页中的 link 浏览到这些 url,我希望 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 路由值。 这可以针对默认路由、特定控制器或特定 controller/action.

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

更新我找不到任何参数来强制 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 路由值。这可以为默认路由、特定控制器或特定 controller/action.

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

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

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

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