2012-01-19 57 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"))