2010-01-20 10 views
5

Estoy buscando una solución de mejores prácticas que tenga como objetivo reducir la cantidad de URL que están codificadas en una aplicación ASP.NET.ASP.NET - Evite las rutas de codificación rígida

Por ejemplo, cuando se visualiza una pantalla de detalles del producto, se realiza una edición de estos detalles y luego se envían los cambios, el usuario se redirige a la pantalla de lista de productos. En lugar de codificar el siguiente:

Response.Redirect("~/products/list.aspx?category=books"); 

me gustaría tener una solución en el lugar que me permite hacer algo como esto:

Pages.GotoProductList("books"); 

donde Pages es un miembro de la clase base común.

Simplemente estoy escupiendo aquí, y me encantaría escuchar cualquier otra forma en la que cualquiera haya logrado redirigir su aplicación.

EDITAR

que acabó creando la siguiente solución: Yo ya tenía una clase base común, a la que añadí una enumeración de páginas (gracias Mark), con cada elemento tiene un atributo System.ComponentModel.DescriptionAttribute que contiene la dirección URL de la página :

public enum Pages 
{ 
    [Description("~/secure/default.aspx")] 
    Landing, 
    [Description("~/secure/modelling/default.aspx")] 
    ModellingHome, 
    [Description("~/secure/reports/default.aspx")] 
    ReportsHome, 
    [Description("~/error.aspx")] 
    Error 
} 

Luego creé algunos métodos sobrecargados para manejar diferentes escenarios. Solía ​​reflexión para obtener la URL de la página a través de su Description atributo, y paso los parámetros de cadena de consulta como un tipo anónimo (también utilizando la reflexión de añadir cada propiedad como un parámetro de cadena de consulta):

private string GetEnumDescription(Enum value) 
{ 
    Type type = value.GetType(); 
    string name = Enum.GetName(type, value); 

    if (name != null) 
    { 
     FieldInfo field = type.GetField(name); 
     if (field != null) 
     { 
      DescriptionAttribute attr = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)) as DescriptionAttribute; 

      if (attr != null) 
       return attr.Description; 
     } 
    } 

    return null; 
} 

protected string GetPageUrl(Enums.Pages target, object variables) 
{ 
    var sb = new StringBuilder(); 
    sb.Append(UrlHelper.ResolveUrl(Helper.GetEnumDescription(target))); 

    if (variables != null) 
    { 
     sb.Append("?"); 
     var properties = (variables.GetType()).GetProperties(); 

     foreach (var property in properties) 
      sb.Append(string.Format("{0}={1}&", property.Name, property.GetValue(variables, null))); 
    } 

    return sb.ToString(); 
} 

protected void GotoPage(Enums.Pages target, object variables, bool useTransfer) 
{ 
    if(useTransfer) 
     HttpContext.Current.Server.Transfer(GetPageUrl(target, variables)); 
    else 
     HttpContext.Current.Response.Redirect(GetPageUrl(target, variables)); 
} 

Un la llamada típica se vería así:

GotoPage(Enums.Pages.Landing, new {id = 12, category = "books"}); 

Comentarios?

Respuesta

4

me gustaría sugerir que usted deriva su propia clase ("MyPageClass") de la clase Page e incluir este método no:

public class MyPageClass : Page 
{ 
    private const string productListPagePath = "~/products/list.aspx?category="; 
    protected void GotoProductList(string category) 
    { 
     Response.Redirect(productListPagePath + category); 
    } 
} 

Luego, en el código subyacente, asegúrese de que su página deriva de este clase:

public partial class Default : MyPageClass 
{ 
     ... 
} 

dentro de eso, se puede redirigir simplemente mediante el uso de:

GotoProductList("Books"); 

Ahora, esto es un poco limitado ya que sin dudas tendrá una variedad de otras páginas como la página ProductList. Usted podría dar a cada uno de ellos su propio método en su clase de página, pero esto es algo desagradable y no extensible fácilmente.

Resuelvo un problema como este manteniendo una tabla db con una asignación de nombre de página/nombre de archivo (estoy llamando a archivos HTML externos, dinámicamente agregados, no a archivos ASPX, por lo que mis necesidades son un poco diferentes, pero Creo que los principios se aplican).Su llamada se use una cadena o, mejor aún, una enumeración para redirigir:

protected void GoToPage(PageTypeEnum pgType, string category) 
{ 
     //Get the enum-to-page mapping from a table or a dictionary object stored in the Application space on startup 
     Response.Redirect(GetPageString(pgType) + category); // *something* like this 
} 

Desde la página de su llamada sería: GOTOPAGE (enumProductList, "Libros");

Lo bueno es que la llamada es a una función definida en una clase ancestro (no es necesario pasar o crear objetos de administrador) y la ruta es bastante obvia (intellisense limitará sus rangos si usa una enumeración).

¡Buena suerte!

+0

Terminé haciendo algo similar a esto (ver la edición anterior), y lo marcaré como aceptado porque utilicé la idea de páginas enum. Gracias Mark. – staterium

1

Tiene una gran cantidad de opciones disponibles, y todas comienzan con la creación de un diccionario de mapas, mientras que puede hacer referencia a una palabra clave a una URL difícil. Ya sea que elija almacenarlo en un archivo de configuración o en una tabla de búsqueda de base de datos, sus opciones son infinitas.

1

Tienes una gran cantidad de opciones disponibles aquí. La tabla de la base de datos o el archivo XML son probablemente los ejemplos más comúnmente utilizados.

// Please note i have not included any error handling code. 
public class RoutingHelper 
{ 
    private NameValueCollecton routes; 

    private void LoadRoutes() 
    { 
     //Get your routes from db or config file 
     routes = /* what ever your source is*/ 
    } 

    public void RedirectToSection(string section) 
    { 
     if(routes == null) LoadRoutes(); 

     Response.Redirect(routes[section]); 
    } 
} 

Este es solo un código de muestra, y se puede implementar de la manera que desee. La pregunta principal en la que debe pensar es dónde desea almacenar las asignaciones. Un simple archivo xml podría hacerlo:

`<mappings> 
    <map name="Books" value="/products.aspx/section=books"/> 
    ... 
</mappings>` 

y luego simplemente cargue eso en su colección de rutas.

Cuestiones relacionadas