0

我在asp.net mvc網站中有一個表單,它有三種用途:分頁,排序和搜索。這些項目都應該以相同的形式呈現,因爲返回正確的搜索結果取決於來自所有3個方面的變量。我想要做的是將參數從查詢字符串中移出並放入規範URL中。需要幫助在asp.net中規範化HTTP GET表單mvc

我幾乎沒有,這裏有我的3個路由配置到目前爲止(使用T4MVC的區域,控制器和動作名):

context.MapRoute(null, 
    "my-area/my-widgets/search/{size}-results-max/page-{page}/order-by-{sort}", 
    new 
    { 
     area = MVC.MyArea.Name, 
     controller = MVC.MyArea.MyWidgets.Name, 
     action = MVC.MyArea.MyWidgets.ActionNames.Search, 
     page = UrlParameter.Optional, 
     size = UrlParameter.Optional, 
     sort = UrlParameter.Optional, 
    } 
); 

context.MapRoute(null, 
    "my-area/my-widgets/canonicalize-search", 
    new 
    { 
     area = MVC.MyArea.Name, 
     controller = MVC.MyArea.MyWidgets.Name, 
     action = MVC.MyArea.MyWidgets.ActionNames.CanonicalizeSearch, 
    } 
); 

context.MapRoute(null, 
    "my-area/my-widgets", 
    new 
    { 
     area = MVC.MyArea.Name, 
     controller = MVC.MyArea.MyWidgets.Name, 
     action = MVC.MyArea.MyWidgets.ActionNames.CanonicalizeSearch, 
    } 
); 

視圖中的形式提交給CanonicalizeSearch路線,使用此語法:

@using (Html.BeginForm(MVC.MyArea.MyWidgets.CanonicalizeSearch(), 
    FormMethod.Get)) 

在MyWidgetsController,有2點動作的方法:

[ActionName("canonicalize-search")] 
public virtual RedirectToRouteResult CanonicalizeSearch(string keyword, 
    int page = 1, int size = 10, string sort = "Title-Ascending") 
{ 
    var result = RedirectToRoutePermanent(new 
    { 
     area = MVC.MyArea.Name, 
     controller = MVC.MyArea.MyWidgets.Name, 
     action = MVC.MyArea.MyWidgets.ActionNames.Search, 
     page = page, 
     size = size, 
     sort = sort, 
     keyword = keyword, 
    }); 
    return result; 
} 

[ActionName("search")] 
public virtual ViewResult Search(string keyword, 
    int page = 1, int size = 10, string sort = "Title-Ascending") 
{ 
    // code to perform query 
    return View(model); 
} 

這適用於將所有查詢字符串變量移至標準化路線,但關鍵字除外。如果我向第一個路由添加關鍵字參數,那麼當關鍵字不爲空,空或空格時,CanonicalizeSearch操作只會重定向到搜索操作。這是不好的,因爲當沒有輸入關鍵字時,它使瀏覽頁面結果變得不可能。

我想我已經嘗試了一切 - 給控制器中的關鍵字一個默認值,添加第4條路線,將關鍵字添加到其他3個參數等。但是,我看起來得到這個工作的唯一途徑是通過將關鍵字保留爲查詢字符串參數。 (實際上,我可以通過在CanonicalizeSearch中將關鍵字預先加下劃線並在Search中將其剝離來實現,但這很不合理)。

任何幫助?

+0

發現爲什麼它沒有傳遞參數 - 因爲當我添加關鍵字時,我設置了這樣的網址:「my-area/my-widgets/search/{size} -results-max/page- { PAGE} /順序逐{}排序/關鍵字定位{}關鍵字」。如果我將url設置爲「my-area/my-widgets/search/{size} -results-max/page- {page}/order-by- {sort}/{keyword}」,關鍵字== null。 – danludwig 2011-01-20 06:06:41

回答

1

我想我嘗試解決另一個問題時,偶然發現了一個更好的解決方案。

說某人在關鍵字框中鍵入「我的搜索字詞」。提交導致CanonicalizeSearch方法路由到路徑:

/my-area/my-widgets/search/10-results-per-page/page-1/ 
    order-by-Title-Ascending/my%20search%20terms 

那些%20符號很煩人。我寧願網址是這樣的:

[ActionName("canonicalize-search")] 
public virtual RedirectToRouteResult CanonicalizeSearch(string keyword, 
    int page = 1, int size = 10, string sort = "Title-Ascending") 
{ 
    var result = RedirectToRoute(new 
    { 
     area = MVC.MyArea.Name, 
     controller = MVC.MyArea.MyWidgets.Name, 
     action = MVC.MyArea.MyWidgets.ActionNames.Search, 
     page = page, 
     size = size, 
     sort = sort, 
     keyword = (string.IsNullOrWhiteSpace(keyword)) 
      ? "no-keywords" : keyword.Replace(' ', '-'), 
    }); 
    TempData["keyword"] = keyword; 
    return result; 
} 

[ActionName("search")] 
public virtual ViewResult Search(string keyword, 
    int page = 1, int size = 10, string sort = "Title-Ascending") 
{ 
    keyword = TempData["keyword"] as string ?? keyword; 
    // code to perform query 
    return View(model); 
} 

這解決了這兩個我張貼的問題:

/my-area/my-widgets/search/10-results-per-page/page-1/ 
    order-by-Title-Ascending/my-search-terms 

我可以用下面(注意臨時重定向從一個永久性的變化)做到這一點這裏和去除%20符號。每當關鍵字爲空或空白時,它將呈現URL

/my-area/my-widgets/search/10-results-per-page/page-1/ 
    order-by-Title-Ascending/no-keywords 

...並且路線將始終匹配。

1

您是否嘗試在第一條路線的keyword參數上設置UrlParameter.Optional?聽起來很明顯和愚蠢,但你從來沒有排除它。

+0

謝謝...是啊有很多的事情,我排除了,當我寫的帖子,我試圖保持它的簡潔。我花了大約10個小時在這上面,這就是爲什麼我說「我認爲我已經嘗試了所有的東西......」,在關鍵字上設置UrlParameter.Optional就是其中之一。我發現爲什麼 - 當我將關鍵字添加到路徑url路徑時,我將它添加爲「/ keyword- {keyword}」。如果我把它寫成{keyword},一切都很好。我將很快更新。 – danludwig 2011-01-20 06:04:32