2010-01-20 115 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>` 

然後只是加載到您的路線集合。