System.Web.Routing with WebForms - подбор переменных на целевой странице - PullRequest
1 голос
/ 04 февраля 2009

У меня есть шаблон Пользователь / {домен} / {имя пользователя}, настроенный через Маршрутизацию. Все работает, кроме одной вещи. Я не могу понять, как передать переменные домена и имени пользователя на мою перенаправленную страницу. Ниже мой метод GetHttpHandler из моей реализации IRouteHandler.

    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 ]

1 голос
/ 23 сентября 2010

Похоже, что другие также выбирают маршрут (без каламбура) для помещения параметров в контекстную коллекцию элементов.

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
}

И в моем OnLoad of PageBase я установил свойство для страниц, которым оно может понадобиться, но определенно ищет более элегантное решение.

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

    base.OnLoad(e);
}
1 голос
/ 17 марта 2009

Начал все шутить и увидел, что интерфейс IHttpHandler предоставляет RequestContext методу GetHttpHandler.

Итак, я изменил свой класс базовой страницы (я всегда помещал слой между 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, я создаю его как свою собственную страницу. Установите свойство контекста запроса, а затем верните страницу вызывающей стороне в качестве IHttpHandler.

Проверено и все работает. WOO HOO!

Затем на странице экземпляра вы можете нажать на коллекцию RequestContext.GetValues, чтобы прочитать переданные параметры.

НТН

1 голос
/ 02 декабря 2009

@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"]
1 голос
/ 04 февраля 2009

Я думаю, что решил это сам. Нашел эту петлю

  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 Это как 4-й пример кода вниз.

UPDATE:
Не уверен, что это сработает ... requestContext.HttpContext кажется "только для чтения". Вернуться к чертежной доске.

ОБНОВЛЕНИЕ 2:
Похоже, это будет работать, если вы добавите ссылку на System.Web.Abstractions

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...