使用WebForms的System.Web.Routing - 在目标页面中拾取变量

时间:2009-02-03 22:14:01

标签: asp.net asp.net-mvc routing

我通过路由设置了User / {domain} / {username}模式。除了一件事,一切都有效。我无法弄清楚如何将域和用户名变量传递给我的重定向页面。下面是我的IRouteHandler实现中的GetHttpHandler方法。

    public IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        string basePath;
        basePath = "~/UserPage.aspx";
        string domain = requestContext.RouteData.GetRequiredString("domain");
        string username = requestContext.RouteData.GetRequiredString("username");

        string virtualPath =
            string.Format(basePath + "?domain={0}&username={1}", domain, username);
        return (Page)BuildManager.CreateInstanceFromVirtualPath(virtualPath, typeof(Page));

    }

我从最后一行代码中得到错误: UserPage.aspx?domain = SOMEDOMAIN& username = SOMEUSER不是有效的虚拟路径。

那么你应该如何将变量传递给目标页面?我错过了什么?

4 个答案:

答案 0 :(得分:1)

我想我自己解决了这个问题。 找到了这个循环

  foreach (KeyValuePair<string, object> token in requestContext.RouteData.Values)  
     {                  
         requestContext.HttpContext.Items.Add(token.Key, token.Value);  
     }  
来自http://www.codethinked.com/post/2008/08/20/Exploring-SystemWebRouting.aspx

它就像第四个代码样本一样。

<强>更新
不确定这是否有效... requestContext.HttpContext似乎是“只读”。回到绘图板。

更新2:
如果您添加对System.Web.Abstractions

的引用,这看起来会起作用

答案 1 :(得分:1)

开始乱搞东西,看到IHttpHandler接口为GetHttpHandler方法提供了RequestContext。

所以,我修改了我的基页类(我总是在System.Web.UI.Page和我自己的页面之间放一个层,只为此目的调用它为BasePage或类似的)。所以我在PVBasePage上添加了一个公共属性来接收RequestContext对象。

public RequestContext RequestContext { get; set; }

然后,我的路由类代码如下:

IHttpHandler IRouteHandler.GetHttpHandler(RequestContext requestContext)
{
    // create the page object as my own page...
    var page = BuildManager.CreateInstanceFromVirtualPath(VirtualPath
        , typeof(PVBasePage)) as PVBasePage;
    // pass in the request context
    page.RequestContext = requestContext;
    // return this page in the form of a IHttpHandler
    return page as IHttpHandler;
}

因此,不像在示例代码中那样直接创建实例作为IHttpHandler,而是将其创建为我自己的页面。设置请求上下文属性,然后将页面返回给调用者AS IHttpHandler。

经过测试,确实有效。 WOO HOO!

然后在实例页面中,您可以点击RequestContext.GetValues集合来读出传入的参数。

HTH

答案 2 :(得分:1)

@ B.Tyndall

我只是使用类似于你的解决方案。

发现于:http://msmvps.com/blogs/luisabreu/archive/2008/03/12/using-the-routing-mvc-api-with-classic-asp-net.aspx

foreach (var aux in requestContext.RouteData.Values)
{
    HttpContext.Current.Items[aux.Key] = aux.Value;
}

所以实际上你不再使用Request.QueryString而是使用Context.Items集合

HttpContext.Current.Items["RouteName"]

Context.Items["RouteName"]

答案 3 :(得分:1)

似乎其他人也在将参数放入上下文Items集合中的路线(没有双关语)。

http://bbits.co.uk/blog/archive/2008/05/19/using-asp.net-routing-independent-of-mvc---passing-parameters-to.aspx

我为具有特定参数的页面组合了几种方法,我为接受该类型参数的页面创建了UserNameRouteHandler。在我的PageBase类中,我检查了该参数的上下文项,然后设置了一个属性,以便从PageBase继承的页面可以使用它。

public class UserNameRouteHandler : IRouteHandler
{
    #region Implementation of IRouteHandler

    public IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        string pageName = requestContext.RouteData.GetRequiredString("PageName");

        string employeeUserName = requestContext.RouteData.GetRequiredString("UserName");

        if(!string.IsNullOrEmpty(employeeUserName))
        {
            requestContext.HttpContext.Items["UserName"] = employeeUserName;
        }

        pageName = pageName.ToLower() == "home" ? "default" : pageName;

        string virtualPath = string.Format("~/{0}.aspx", pageName);

        return (Page)BuildManager.CreateInstanceFromVirtualPath(virtualPath, typeof(Page));

    }

    #endregion
}

在我的PageBase的OnLoad中,我将属性设置为需要它的页面......但是肯定会寻找更优雅的解决方案。

protected override void OnLoad(EventArgs e)
{
    if (!IsPostBack)
    {
        if (Context.Items["UserName"] != null)
        {
            EmployeeUserName = Context.Items["UserName"].ToString();
        }
    }

    base.OnLoad(e);
}