2012-01-19 58 views
2

我有一个显示项目列表的局部视图,我在几个不同的地方使用了这个局部视图。这里面局部视图我使用分页程序 -根据当前URL生成URL并维护QueryString

@Html.PagedListPager(Model, page => Url.Action(null, new { page = page })) 

这将导致分页程序显示的网页网址为任何行动和查看我已经在看。

问题是,在我的搜索页面上,我使用查询字符串作为搜索字符串,而Url.Action方法不包括现有查询字符串参数。

而不是/搜索?S =喇嘛&页= 3我结束了/搜索页→= 3

我怎样才能利用现有的查询字符串生成一个URL?

编辑:

这里是我的代码

public static void RegisterRoutes(RouteCollection routes) 
    { 
     routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 


     routes.Add(
     "Search", 
     new SearchRoute("Search", new MvcRouteHandler()) 
     { 
      Defaults = new RouteValueDictionary(
       new { controller = "Search", action = "Index" }) 
     }); 


     routes.MapRoute(
      "Default", 
      "{controller}/{action}/{id}", 
      new { controller = "Call", action = "Index", id = UrlParameter.Optional } 


     ); 



    } 

    public class SearchRoute : Route 
    { 
     public SearchRoute(string url, IRouteHandler routeHandler) 
      : base(url, routeHandler) 
     { 
     } 

     public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values) 
     { 

      System.Diagnostics.Debug.WriteLine(Url); 

      if (HttpContext.Current != null) 
      { 

       string s = HttpContext.Current.Request.QueryString["s"]; 

       if (!string.IsNullOrEmpty(s)) 
        values.Add("s", s); 

      } 

      return base.GetVirtualPath(requestContext, values); 
     } 
    } 

回答

3

使用定制的路线,你可以因为大多数URL生成逻辑使用路由生成URL保存查询字符串。在这种情况下,我正在检查Request对象,查找名为XXX的查询字符串并将其添加到路由中(如果存在),如果您愿意,可以使其更通用。

using System.Web; 
using System.Web.Routing; 

public class PreserveQueryStringRoute : Route 
{ 
    public PreserveQueryStringRoute(string url, IRouteHandler routeHandler) 
     : base(url, routeHandler) 
    { 
    } 

    public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values) 
    { 
     if(HttpContext.Current != null) 
     { 
      values = new RouteValueDictionary(values); //this is the bug fix! 

      if (!string.IsNullOrEmpty(HttpContext.Current.Request.QueryString["XXX"])) 
       values.Add("XXX", HttpContext.Current.Request.QueryString["XXX"]); 

     } 

     var path = base.GetVirtualPath(requestContext, values); 
     return path; 
    } 
} 

注册按正常路线在global.ascx(尽管可能不是这样一个普通的比赛,因为我有如下)

 routes.Add(
      "Default", 
      new PreserveQueryStringRoute("{controller}/{action}/{id}", new MvcRouteHandler()) 
      { 
       Defaults = new RouteValueDictionary(
        new { controller = "Home", action = "Index", id = UrlParameter.Optional }) 
      }); 

编辑:

好吧,这里是一个更新..它的一个错误修复,以及如何注册路线的示例(请参阅上述错误修复的更正代码)

以下是如何注册它:

routes.Add(  
    "Search",  
    new SearchRoute("Search", new MvcRouteHandler())  
    {  
     Constraints = new RouteValueDictionary(  
      new { controller = "Search", action = "Index" })  
    }); 
+0

神奇。你达人。如果有其他人使用此项,请记住将呼叫路由添加到默认路由上方。 – NoPyGod 2012-01-19 01:44:44

+0

嗯等一下..这可能不能正常工作 – NoPyGod 2012-01-19 01:57:06

+0

它将查询字符串放在我的搜索页面上生成的所有url上。这可以修复吗?我只需要搜索网址上的查询字符串。 – NoPyGod 2012-01-19 02:00:38

0

这里是我如何做到这一点:

,我实现了几个扩展方法查询字符串转换为RouteValueDictionary,并设置不同的物品,在它:

public static class RouteValueDictionaryExtensions 
{ 
    public static RouteValueDictionary ToRouteValues(this NameValueCollection queryString) 
    { 
     if (queryString == null || queryString.HasKeys() == false) 
      return new RouteValueDictionary(); 

     var routeValues = new RouteValueDictionary(); 
     foreach (string key in queryString.AllKeys) 
      routeValues.Add(key, queryString[key]); 

     return routeValues; 
    } 

    public static RouteValueDictionary Set(this RouteValueDictionary routeValues, string key, string value) 
    { 
     routeValues[key] = value; 
     return routeValues; 
    } 

    public static RouteValueDictionary Merge(this RouteValueDictionary primary, RouteValueDictionary secondary) 
    { 
     if (primary == null || primary.Count == 0) 
     { 
      return secondary ?? new RouteValueDictionary(); 
     } 

     if (secondary == null || secondary.Count == 0) 
      return primary; 

     foreach (var pair in secondary) 
      primary[pair.Key] = pair.Value; 

     return primary; 
    } 

    public static RouteValueDictionary Merge(this RouteValueDictionary primary, object secondary) 
    { 
     return Merge(primary, new RouteValueDictionary(secondary)); 
    } 
} 

这使得有可能创造链接,如:

Url.RouteUrl(Request.QueryString.ToRouteValues().Set("Key", "Value")) 

或者这样:

Url.RouteUrl(Request.QueryString.ToRouteValues().Merge(new {key = "value"})) 

我也可以连接这些扩展方法来实现更大的灵活性:

Url.RouteUrl(Request.QueryString.ToRouteValues().Set("Key", "Value").Set("AnotherKey", "AnotherValue"))