ASP.NET - 避免硬编码路径

时间:2010-01-20 14:35:25

标签: asp.net url response.redirect

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

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

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

我想有一个解决方案,允许我做这样的事情:

Pages.GotoProductList("books");

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

我只是在这里吐痰,并且很想听到任何人管理他们的应用程序重定向的任何其他方式。

修改

我最终创建了以下解决方案:我已经有了一个公共基类,我添加了一个Pages枚举(感谢Mark),每个项目都有System.ComponentModel.DescriptionAttribute属性,包含页面的URL:

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

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

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 个答案:

答案 0 :(得分: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页面。你可以在你的页面类中为每个人提供自己的方法,但这有点粗鲁,而且不能顺利扩展。

我通过在其中保存带有页面名称/文件名映射的db表来解决类似的问题(我正在调用外部,动态添加的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,“Books”);

好处是调用是在祖先类中定义的函数(不需要传递或创建管理器对象),并且路径非常明显(如果使用枚举,intellisense将限制范围)。 / p> 祝你好运!

答案 1 :(得分:1)

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

答案 2 :(得分: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>`

然后将其加载到您的路线集合中。

答案 3 :(得分:0)

public class BasePage : Page
{
    public virtual string GetVirtualUrl()
    {
        throw new NotImplementedException();
    }

    public void PageRedirect<T>() where T : BasePage, new()
    {
        T page = new T();
        Response.Redirect(page.GetVirtualUrl());
    }
}

public partial class SomePage1 : BasePage
{
    protected void Page_Load()
    {
        // Redirect to SomePage2.aspx
        PageRedirect<SomePage2>();
    }
}

public partial class SomePage2 : BasePage
{
    public override string GetVirtualUrl()
    {
        return "~/Folder/SomePage2.aspx";
    }
}
相关问题