2010-01-20 86 views
5

我正在寻找一种最佳实践解决方案,旨在减少在ASP.NET应用程序中硬编码的URL数量。ASP.NET - 避免硬编码路径

例如,查看产品详细信息屏幕,对这些详细信息执行编辑,然后提交更改时,用户将重定向回产品列表屏幕。相反,编码如下:

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

我想有一个适当的解决方案,可以让我做这样的事情:

Pages.GotoProductList("books"); 

其中Pages是公共基类中的一员。

我只是吐口水在这里,并希望听到任何人都管理其应用程序重定向的其他方式。

编辑

我结束了创建以下解决方案:我已经有一个共同的基类,而我添加了一个页面枚举(感谢马克),与具有含网页的URL一个System.ComponentModel.DescriptionAttribute属性的每个项目:

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

然后,我创建了一些重载的方法来处理不同的情况。我使用反射来获取页面的URL通过它的Description属性,和我通过查询字符串参数作为一个匿名类型(也使用反射来每个属性添加作为查询字符串参数):

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

一典型的呼叫将如下所示:

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

评论?

回答

4

我建议你从Page类派生自己的类(“MyPageClass”),并包括此方法有:

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

然后,在你的代码隐藏,请确保您的页面从这个派生类:

public partial class Default : MyPageClass 
{ 
     ... 
} 

内,你可以通过使用重定向:

GotoProductList("Books"); 

现在,这是有限的,因为你毫无疑问会有许多其他页面,比如ProductList页面。你可能给你的每个人自己的方法在你的网页类,但这是一种浑厚,不能顺利扩展。

我通过保持一个数据库表在它的网页名称/文件名映射(我打电话外,动态添加HTML文件解决的那种像这样的问题,而不是ASPX文件,所以我需要的是一个有点不同,但我认为这些原则适用)。您的电话,然后将使用字符串或者更好的是,一个枚举重定向:

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 
} 

从你的网页你的电话是:GotoPage记述(enumProductList,“书”);

好的是,调用是在祖先类中定义的函数(无需传递或创建管理器对象),路径非常明显(如果使用枚举,智能感知将限制您的范围)。

祝你好运!

+0

我最终做了类似的事情(参见上面的编辑),并将其标记为已接受,因为我使用了页面枚举的想法。谢谢马克。 – staterium 2010-01-23 15:28:38

1

您有丰富的选项可用,它们都以创建映射词典开始,而您可以将关键字引用到硬链接。无论您选择将其存储在配置文件还是数据库查找表中,您的选项都是无穷无尽的。

1

您有大量的选项在这里可用。数据库表或XML文件可能是最常用的示例。

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

这只是示例代码,它可以以您希望的任何方式实现。您需要考虑的主要问题是您想要存储映射的位置。一个简单的XML文件可以做到这一点:

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

然后只是加载到您的路线集合。