【问题标题】:Consistent way to access route value parameters passed through querystring访问通过查询字符串传递的路由值参数的一致方式
【发布时间】:2016-02-04 18:30:34
【问题描述】:

我在 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 是否缺少路由参数和如果找到就添加它们。

【问题讨论】:

  • 看起来编写自定义路由将允许我通过覆盖 GetRouteData 将缺失值添加到 RouteData;测试完我会发布源代码。

标签: model-view-controller querystringparameter routedata


【解决方案1】:

你可以使用

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

【讨论】:

    【解决方案2】:

    试试这个解决方案

      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]));
            }
    

    【讨论】:

      【解决方案3】:

      Extending Route 最终成为满足我需求的最简单的解决方案;感谢你的建议!如果我的解决方案有任何明显的问题(除了类名),请告诉我。

      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 }));
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-07-28
        • 2018-04-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-01-01
        • 1970-01-01
        • 2013-12-17
        相关资源
        最近更新 更多