2011-05-19 87 views
31

如果缺少部分URL,如何將ASP.NET MVC中的請求重定向到正確的規範版本?向ASP.NET MVC中的URL slugs添加標識和標題

以堆棧溢出爲例,該站點將問題標題添加到其路徑的末尾,但在路徑中使用問題標識來實際查找問題。如果標題被忽略,您將被重定向到正確的URL。

例如,訪問的網址:

stackoverflow.com/questions/9033 

會重定向到

stackoverflow.com/questions/9033/hidden-features-of-c 

這是如何工作的?

+4

看到這個相關的問題和答案http://stackoverflow.com/questions/2174820/how-to-add-page-title-in-url-in-asp-net-mvc-url-generation和http:/ /stackoverflow.com/questions/677158/stackoverover-question-routing – jao 2011-05-19 07:51:15

回答

38

首先創建一個路由:

routes.MapRoute( 
    "ViewProduct", 
    "Products/{id}/{productName}", 
    new { controller = "Product", action = "Details", id = "", productName = "" } 
); 

然後創建操作方法如下所示:

public ActionResult Details(int? id, string productName) 
{ 
    Product product = ProductRepository.Fetch(id); 

    string realTitle = UrlEncoder.ToFriendlyUrl(product.Title); 
    string urlTitle = (productName ?? "").Trim().ToLower(); 

    if (realTitle != urlTitle) 
    { 
     string url = "/Products/" + product.Id + "/" + realTitle; 
     return new PermanentRedirectResult(url); 
    } 

    return View(product); 
} 

你基本上在URL與一個存儲在數據庫中比較實體名稱,如果它們不匹配,則執行301永久重定向。確保它是一個'永久'重定向(301狀態碼),而不是臨時重定向(302)。這樣,搜索引擎會將其視爲網址的永久變更,並相應地更新其索引,如果實體的標題在搜索引擎編入索引後發生變化(例如,某人更改了產品名稱),則可能會發生這種情況。

另一件需要注意的事情是,如果您的標題允許任何自由文本,您需要刪除任何對URL無效的字符,並使其對人類和搜索引擎更具可讀性,因此UrlEncoder.ToFriendlyUrl在上面的代碼方法,實現的過程如下:

public static class UrlEncoder 
{ 
    public static string ToFriendlyUrl (this UrlHelper helper, 
     string urlToEncode) 
    { 
     urlToEncode = (urlToEncode ?? "").Trim().ToLower(); 

     StringBuilder url = new StringBuilder(); 

     foreach (char ch in urlToEncode) 
     { 
      switch (ch) 
      { 
       case ' ': 
        url.Append('-'); 
        break; 
       case '&': 
        url.Append("and"); 
        break; 
       case '\'': 
        break; 
       default: 
        if ((ch >= '0' && ch <= '9') || 
         (ch >= 'a' && ch <= 'z')) 
        { 
         url.Append(ch); 
        } 
        else 
        { 
         url.Append('-'); 
        } 
        break; 
      } 
     } 

     return url.ToString(); 
    } 
} 

所以,當你寫出來的網址進入查看時,一定要使用這種方法如編碼標題

<a href="/Products/@Model.Id/@Url.ToFriendlyUrl(Model.Title)">@Model.Title</a> 

我寫這個博客張貼在這裏http://www.dominicpettifer.co.uk/Blog/34/asp-net-mvc-and-clean-seo-friendly-urls

+3

Stackoverflow的創建者在這裏顯示他的'ToFriendlyUrl'的實現:[http://stackoverflow.com/questions/25259/how-do-you-包括-A-網頁標題-AS-部分對的一網頁的URL/25486#25486](http://stackoverflow.com/questions/25259/how-do-you-include-a-webpage-title -as-part-of-a-page-url/25486#25486) – wycleffsean 2011-11-07 19:12:01

+1

URL中UTF-8字符的標準已更改。根據[Wikipedia](http://en.wikipedia.org/wiki/Internationalized_domain_name),Mozilla 1.4,Netscape 7.1,Opera 7.11是首批支持IDNA的應用程序之一。瀏覽器插件可用於Internet Explorer 6以提供IDN支持。 Internet Explorer 7.0和Windows Vista的URL API爲IDN提供本機支持。聽起來像刪除UTF-8字符是浪費時間。萬歲UTF-8 !!! – 2015-04-24 14:18:25

+1

我用小提琴手,注意到Stackoverflow.com做一個'302' - 臨時重定向從'stackoverflow.com/questions/9033'到'stackoverflow.com/questions/9033/hidden-features-of-c'如何解釋那是因爲你說重定向應該是'301' - 永久重定向? – Shiva 2017-05-09 05:21:48

3

雖然我不知道StackOverflow如何管理它的任何細節,但下面概述瞭如何實現做到這一點

  • 使用的ID從數據庫中檢索的問題
  • 轉換存儲問題的標題爲URL兼容塞
  • 如果轉換的標題塞不匹配的URL通過了塞然後重定向使用轉換後的標題slu。。

這將確保URL是永遠正確的,避免possible embarrassing fake URLs

+0

更新的答案突出顯示,slug實際上是由問題標題以及爲什麼重要的是檢查URL中傳遞的slu is實際上是正確的slu slu。 – 2011-05-19 09:19:42

0

這裏是他們如何可能做到這一點,但我相信你問它是如何做,這應該工作的例子。

第一階段是建立2路在Global.asax

routes.MapRoute("WithQuestion", "questions/{id}/{name}", new { controller = "Questions", action = "Question", id = "1" }); 
routes.MapRoute("WithoutQuestion", "questions/{id}", new { controller = "Questions", action = "WithoutQuestion", id="1"}); 

現在我們的問題控制器,

public ActionResult Question(int id) 
    { 
     //Load the question as we have the name appended. 
     // We could actually do a little validation here as well 
     return View(); 
    } 

    public ActionResult WithoutQuestion(int id) 
    { 
     //Load the question object 
     //Generate the full URL and redirect 
     return Redirect(FullURL) 
    } 

這是一個非常基本的例子,但說明了如何能做到它。

+1

您的示例並不完全正確,如果使用不正確的slug,則StackOverflow將始終重定向到正確的slug,例如http://stackoverflow.com/questions/6055415/totally-made-up-slug所以因此需要檢查URL中傳遞的slu is實際上是存儲在數據庫中的正確slu slu。 – 2011-05-19 09:08:07

+0

@David //我們實際上也可以在這裏做一些驗證;) – LiamB 2011-05-19 12:46:39

0

@sunday我已經嘗試過了,但我仍然面臨着問題。我需要給URL作爲

產品?ID = 4 &產品名稱=新博客

然後我得到了解決。 This幫了我。我們需要確保CUSTOM路線高於默認路線

現在它工作正常。