Подтвердить что ты не робот

Добавление идентификатора и заголовка в пулы URL-адресов в ASP.NET MVC

Как вы перенаправляете запрос в ASP.NET MVC в его правильную каноническую версию, если отсутствует часть URL-адреса?

Используя пример, сайт добавляет заголовок вопроса в конец его маршрутов, но использует идентификатор вопроса в маршруте для фактического поиска вопроса. Если заголовок будет опущен, вы будете перенаправлены на правильный URL.

Например, посетив URL-адрес:

stackoverflow.com/info/9033 

будет перенаправлен на

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

Как это работает?

4b9b3361

Ответ 1

Сначала создайте маршрут:

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

Затем создайте метод Action следующим образом:

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-адреса и соответственно обновят свои индексы, это может произойти, если заголовок вашего объекта изменится после того, как поисковая система проиндексировала его (например, кто-то изменил название продукта).

Еще одна вещь, о которой нужно знать, если ваш заголовок позволяет использовать любой бесплатный текст, вам нужно вычеркнуть любые недопустимые для 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(); 
    } 
}

Поэтому, когда вы выписываете URL-адреса в представлении, обязательно закодируйте заголовки с помощью этого метода, например.

<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

Ответ 2

Пока я не знаю каких-либо особенностей того, как StackOverflow управляет им, вот обзор того, как вы могли это сделать

  • Извлеките вопрос из базы данных с помощью идентификатора
  • Преобразование сохраненного заголовка вопроса в совместимый с URL-адрес slug
  • Если преобразованный заголовок заголовка не совпадает с пропуском, переданным в URL-адресе, затем перенаправляет его с помощью преобразованного заголовка.

Это гарантирует, что URL всегда правильный и избегает возможных смущающих поддельных URL

Ответ 4

Вот пример того, как они могут это сделать, но я считаю, что вы спрашиваете, как это можно сделать, и это должно работать.

Первый этап - настроить 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)
    }

Это очень простой пример, но показывает, как вы могли это сделать.