2010-03-18 3 views
0

У меня есть сайт, где часть является WebForms (Umbraco CMS), а часть MVC Это HttpHandler иметь дело с функциональностью MVC:Использование пользовательского MvcHttpHandler v2.0 Ломающееся изменение от 1.0 до 2.0?

public class Mvc : MvcHttpHandler 
{ 
    protected override void ProcessRequest(HttpContext httpContext) 
    { 
     httpContext.Trace.Write("Mvc.ashx", "Begin ProcessRequest"); 
     string originalPath = httpContext.Request.Path; 
     string newPath = httpContext.Request.QueryString["mvcRoute"]; 
     if (string.IsNullOrEmpty(newPath)) 
      newPath = "/"; 

     httpContext.Trace.Write("Mvc.ashx", "newPath = "+newPath); 

     HttpContext.Current.RewritePath(newPath, false); 
     base.ProcessRequest(HttpContext.Current); 
     HttpContext.Current.RewritePath(originalPath, false); 
     } 
} 

Все подробности о том, как это реализовано here Этот метод хорошо работает на веб-сайте MVC 1.0. Однако, когда я обновляю этот сайт до MVC 2.0, следуя инструкциям в Microsoft's upgrade documentation; все компилируется, кроме как во время выполнения. Я получаю это исключение:

Ошибка сервера в приложении «/».
Ресурс не найден.
Описание: HTTP 404. Ресурс вы ищете (или один из его зависимостей ) могли быть удалены, было изменено его имя или временно недоступна. Пожалуйста, просмотрите следующий URL-адрес и убедитесь, что правильно написано.

Запрошенный URL: /mvc.ashx

Информация о версии: Microsoft .NET Framework Версия: 2.0.50727.4927; ASP.NET версии: 2.0.50727.4927

Этот ресурс, и это зависимостей найдены штраф в MVC 1.0, но не в MVC 2.0, есть дополнительная зависимость мне нужно добавить? Есть ли что-то, что мне не хватает? Есть ли изменения в способе работы MVC 2.0?

ответ

3

Слово предостережения - типы MvcHandler и MvcHttpHandler не должны подклассифицироваться кодом пользователя. Эти обработчики будут меняться с будущими версиями фреймворка, поэтому любые типы, подклассы которых подлежат разбивке. Имея это в виду ..

В MVC 2, тип MvcHttpHandler является IHttpAsyncHandler, а не просто IHttpHandler. Это изменяет семантику того, как ASP.NET выполняет обработчик. Если вы подклассифицируете MvcHttpHandler, вам необходимо переопределить методы BeginProcessRequest и EndProcessRequest в дополнение к методу ProcessRequest.

Более безопасный механизм заключается в том, чтобы обернуть MvcHttpHandler, а не подклассифицировать его. То есть сделайте свой собственный IHttpHandler, чей метод ProcessRequest() просто делегирует новый MvcHttpHandler.ProcessRequest(). Таким образом, изменения в работе MvcHttpHandler не должны приводить к разрыву обработчика обертки.

+0

Примечание: «более безопасный механизм» не работает, потому что ProcessRequest() защищена. – Myster

+1

Передайте его в IHttpHandler, затем вызовите явный метод IHttpHandler.ProcessRequest(). – Levi

+0

как бы вы это сделали? я сделал это, но все равно получаю тот же результат IHttpHandler ihh = (IHttpHandler) (новый MvcHttpHandler()); ihh.ProcessRequest (HttpContext.Текущий); это все равно возвращает не найденный ресурс. У меня есть HomeController и представления для Home Home.aspx/Index Home.aspx/О , поэтому mvc.ashx? mvcRoute =/home.aspx должен работать – Sander

3

Это то, что я сделал, и это работает ...

public class mvc : IHttpHandler, System.Web.SessionState.IRequiresSessionState 
{ 

    public bool IsReusable 
    { 
     get { return true; } 
    } 

    public void ProcessRequest(HttpContext httpContext) 
    { 
     string originalPath = httpContext.Request.Path; 
     HttpContext.Current.RewritePath(httpContext.Request.ApplicationPath, false); 
     IHttpHandler httpHandler = new MvcHttpHandler(); 
     httpHandler.ProcessRequest(HttpContext.Current); 
     HttpContext.Current.RewritePath(originalPath, false); 
    } 

} 
+0

Ницца, этот пример показывает, как его создать, как описывает Леви. – Myster