2011-05-19 38 views
31

¿Cómo redirige una solicitud en ASP.NET MVC a su versión canónica correcta si falta parte de la URL?Agregar ID y título a URL slugs en ASP.NET MVC

Utilizando Stack Overflow como ejemplo, el sitio agrega el título de la pregunta al final de sus rutas, pero usa el ID de la pregunta en la ruta para encontrar realmente la pregunta. Si se omite el título, se te redirigirá a la URL correcta.

Por ejemplo, en la siguiente URL:

stackoverflow.com/questions/9033 

se redirigir a

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

¿Cómo funciona esto?

+4

vea esta pregunta y respuestas relacionadas http://stackoverflow.com/questions/2174820/how-to-add-page-title-in-url-in-asp-net-mvc-url-generation y http://stackoverflow.com/questions/677158/stack-overflow-question-routing – jao

Respuesta

38

En primer lugar crear una ruta:

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

A continuación, cree el método de acción, así:

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); 
} 

Básicamente, se está comparando el título de una entidad en la dirección URL con la que está almacenada en la base de datos, si no coinciden, realice una redirección permanente 301. Asegúrese de que sea una redirección 'permanente' (código de estado 301) en lugar de una redirección temporal (302). De esta manera, los motores de búsqueda lo tratarán como un cambio permanente de la URL y actualizarán sus índices en consecuencia, esto podría suceder si el título de su entidad cambia después de que un motor de búsqueda lo haya indexado (por ejemplo, alguien cambia el nombre del producto).

Otra cosa que debe tener en cuenta, si su título permite texto libre, debe eliminar cualquier carácter que no sea válido para una URL y hacerlo más legible para humanos y motores de búsqueda, de ahí el UrlEncoder.ToFriendlyUrl método en el código anterior, la ejecución es el siguiente:

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(); 
    } 
} 

Así que cuando usted escribe las direcciones URL en la vista, asegúrese de codificar los títulos con este método por ejemplo,

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

He escrito un post sobre esto aquí http://www.dominicpettifer.co.uk/Blog/34/asp-net-mvc-and-clean-seo-friendly-urls

+3

el creador de Stackoverflow muestra su implementación de 'ToFriendlyUrl' aquí: [http://stackoverflow.com/questions/25259/how-do-you- include-a-webpage-title-as-part-of-a-webpage-url/25486 # 25486] (http://stackoverflow.com/questions/25259/how-do-you-include-a-webpage-title -as-part-of-a-webpage-url/25486 # 25486) – wycleffsean

+1

Los estándares para los caracteres UTF-8 en las URL han cambiado. Según [Wikipedia] (http://en.wikipedia.org/wiki/Internationalized_domain_name), Mozilla 1.4, Netscape 7.1, Opera 7.11 se encontraban entre las primeras aplicaciones en admitir IDNA. Un plugin de navegador está disponible para Internet Explorer 6 para proporcionar soporte de IDN. Las API de URL de Internet Explorer 7.0 y Windows Vista brindan soporte nativo para IDN. Parece que eliminar los caracteres UTF-8 es una pérdida de tiempo. ¡Larga vida a UTF-8! –

+1

Utilicé el fiddler y noté que Stackoverflow.com hace un '302' - Redirección temporal que va de' stackoverflow.com/questions/9033' a 'stackoverflow.com/questions/9033/hidden-features-of-c' ¿Cómo explico eso, ya que estás diciendo que la redirección debería ser '301' - ¿Redirección permanente? – Shiva

3

Aunque no conozco ningún detalles de cómo Stackoverflow manejarlo, aquí es una visión general de cómo se puede hágalo

  • Recuperar la pregunta de la base de datos utilizando el ID de
  • convertir el título de la pregunta almacenada en una URL compatibles babosa
  • Si la babosa título convertida no coincide con la babosa pasado en la URL, redirigir el uso la babosa de título convertida.

Esto asegura la URL es siempre la correcta y evita possible embarrassing fake URLs

+0

Respuesta actualizada para resaltar que el slug está hecho en realidad del título de la pregunta y por qué es importante comprobar que el slug pasado en el URL sea en realidad el slug correcto. –

0

Aquí está un ejemplo de la forma en que podrían hacerlo, pero creo que su preguntando cómo se puede hacer y esto debería funcionar.

primera etapa es de configurar 2 rutas en el 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"}); 

Ahora en nuestro controlador de Preguntas,

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) 
    } 

Este es un ejemplo muy básico, pero muestra cómo podría hacer eso.

+1

Su ejemplo no es del todo correcto, si se utiliza una barra incorrecta, StackOverflow siempre redirigirá a la barra correcta, p. http://stackoverflow.com/questions/6055415/totally-made-up-slug, por lo tanto, es necesario realizar una comprobación de que el slug pasado en la URL es, de hecho, el slug correcto almacenado en la base de datos. –

+0

@David // Podríamos hacer un poco de validación aquí también;) – LiamB

0

@sunday que he probado, pero aún así me enfrentaba tema. Necesito dar la url como

productos? Id = 4 & productName = new-blog

Luego me dieron solución. This me ayudó. Necesitamos asegurarnos de que la ruta CUSTOM esté POR ENCIMA de la ruta predeterminada

Ahora funciona bien.

Cuestiones relacionadas