访问通过查询字符串传递的路由值参数的一致方法

时间:2016-02-04 18:30:34

标签: model-view-controller querystringparameter routedata

我在global.asax

中定义了以下路由
routes.MapRoute(
    "Default",
    "{controller}/{action}/{id}",
    new { controller = "Portal", action = "Index", id = UrlParameter.Optional }
);

我无法控制用户是否使用“/ useraccount / edit / 1”或“/ useraccount / edit?id = 1”访问该页面。使用UrlHelper Action方法生成url时,如果id作为查询字符串参数传递,则id值不包含在RouteData中。

new UrlHelper(helper.ViewContext.RequestContext).Action(
                            action, helper.ViewContext.RouteData.Values)

我正在寻找一种访问id值的一致方法,无论用于访问页面的URL是什么,或者是一种自定义RouteData对象初始化的方法,以便它检查QueryString是否缺少路由参数和如果找到它们会添加它们。

3 个答案:

答案 0 :(得分:2)

您可以使用

@Url.RouteUrl("Default", new { id = ViewContext.RouteData.Values["id"] != null ? ViewContext.RouteData.Values["id"] : Request.QueryString["id"] })

答案 1 :(得分:0)

尝试此解决方案

  var qs = helper.ViewContext
                .HttpContext.Request.QueryString
                .ToPairs()
                .Union(helper.ViewContext.RouteData.Values)
                .ToDictionary(x => x.Key, x => x.Value);

            var rvd = new RouteValueDictionary(qs);

            return new UrlHelper( helper.ViewContext.RequestContext).Action(action, rvd);

转换NameValueCollection试试这个

public static IEnumerable<KeyValuePair<string, object>> ToPairs(this NameValueCollection collection)
        {
            if (collection == null)
            {
                throw new ArgumentNullException("collection");
            }

            return collection.Cast<string>().Select(key => new KeyValuePair<string, object>(key, collection[key]));
        }

答案 2 :(得分:0)

扩展路线最终成为满足我需求的最简单方案;感谢你的建议!如果我的解决方案中有任何明显的问题(除了班级名称),请告诉我。

<强> FrameworkRoute.cs

public class FrameworkRoute: Route
{
    public FrameworkRoute(string url, object defaults) :
        base(url, new RouteValueDictionary(defaults), new MvcRouteHandler())
    {
    }

    public override RouteData GetRouteData(HttpContextBase httpContext)
    {
        var routeData = base.GetRouteData(httpContext);
        if (routeData != null)
        {
            foreach (var item in routeData.Values.Where(rv => rv.Value == UrlParameter.Optional).ToList())
            {
                var val = httpContext.Request.QueryString[item.Key];
                if (!string.IsNullOrWhiteSpace(val))
                {
                    routeData.Values[item.Key] = val;
                }
            }
        }

        return routeData;
    }
}

<强>的Global.asax.cs

protected override void Application_Start()
{
       // register route
       routes.Add(new FrameworkRoute("{controller}/{action}/{id}", new { controller = "Portal", action = "Index", id = UrlParameter.Optional }));