Доступ к System.Web.Routing.RequestContext из статического контекста в MVC 2.0

#c# #asp.net-mvc-2

#c# #asp.net-mvc-2

Вопрос:

Мне нужно использовать System.Web.Routing.RequestContext в модели представления для вызова HtmlHelper.GenerateLink() .

В MVC 1.0 было возможно получить контекст статически, приведя текущий IHttpHandler :

  var context = ((MvcHandler) HttpContext.Current.CurrentHandler).RequestContext;
  

Теперь проект обновлен до MVC 2.0, и это исключение генерируется при приведении:

Не удалось преобразовать объект типа ‘ServerExecuteHttpHandlerWrapper’ в тип ‘System.Web.Mvc.MvcHandler’.

Я не уверен, что это актуально, но это выполняется в .NET 4.0 на IIS6.

Ответ №1:

Мне нужно использовать System.Web.Routing.RequestContext в модели представления для вызова HtmlHelper.GenerateLink().

Хотя теоретически вы могли бы написать:

 var rc = HttpContext.Current.Request.RequestContext;
  

на практике вы абсолютно никогда не должны делать что-то подобное в модели представления. Это то, что должны делать помощники HTML:

 public static MvcHtmlString GenerateMyLink<MyViewModel>(this HtmlHelper<MyViewModel> html)
{
    MyViewModel model = html.ViewData.Model;
    RequestContext rc = html.ViewContext.RequestContext;
    //TODO: use your view model and the HttpContext to generate whatever link is needed
    ...
}
  

и в вашем строго типизированном представлении MyViewModel просто:

 <%= Html.GenerateMyLink() %>
  

Комментарии:

1. Спасибо, Дарин — это я пытаюсь избежать рефакторинга устаревшего кода 🙂

2. @Дэвид Нил, ASP.NET MVC 1.0 уже считается устаревшим кодом? лол. Мне это нравится.

3. Все, что было написано до того, как я начал работу, является для меня наследием! 😀

4. @Дэвид Нил, ооооооооооол, отлично. В этом случае я боюсь, что это не только устаревший код, но и плохой код, поскольку даже в ASP.NET Модели представления MVC 1.0 не должны зависеть от RequestContext.

Ответ №2:

Я не знаю, что ты хочешь сделать с System.Web.Routing.RequestContext ? проверьте:

 var context = new HttpContextWrapper(System.Web.HttpContext.Current);
var routeData = RouteTable.Routes.GetRouteData(context);

// Use RouteData directly:
var controller = routeData.Values["controller"];

// Or with via your RequestContext:
var requestContext = new RequestContext(context, routeData);
controller = requestContext.RouteData.Values["controller"]
  

Комментарии:

1. Спасибо Бену — принимаю это, потому что это напрямую отвечает на мой вопрос, но я бы посоветовал всем будущим читателям принять к сведению ответ Дарина.