Como fazer ASP.NET MVC Reconhecer IHttpAsyncHandler de IRouteHandler.GetHttpHandler ()?
-
07-07-2019 - |
Pergunta
Neste perguntas e respostas , eu encontrei um maneira de fazer ASP.NET MVC suportar o processamento assíncrono. No entanto, não posso fazê-lo funcionar.
Basicamente, a idéia é criar uma nova implementação do IRouteHandler que tem apenas um método GetHttpHandler . O GetHttpHandler método deve retornar uma implementação IHttpAsyncHandler em vez de apenas IHttpHandler, porque IHttpAsyncHandler tem Begin / EndXXXX padrão API.
public class AsyncMvcRouteHandler : IRouteHandler
{
public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
return new AsyncMvcHandler(requestContext);
}
class AsyncMvcHandler : IHttpAsyncHandler, IRequiresSessionState
{
public AsyncMvcHandler(RequestContext context)
{
}
// IHttpHandler members
public bool IsReusable { get { return false; } }
public void ProcessRequest(HttpContext httpContext) { throw new NotImplementedException(); }
// IHttpAsyncHandler members
public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
{
throw new NotImplementedException();
}
public void EndProcessRequest(IAsyncResult result)
{
throw new NotImplementedException();
}
}
}
Em seguida, no método RegisterRoutes de arquivo Global.asax.cs, cadastre-se esta classe AsyncMvcRouteHandler . RegisterRoutes public static void (rotas RouteCollection) { routes.IgnoreRoute ( "{recurso} .axd / {* pathInfo}");
routes.Add(new Route("{controller}/{action}/{id}", new AsyncMvcRouteHandler())
{
Defaults = new RouteValueDictionary(new { controller = "Home", action = "Index", id = "" }),
});
}
I ponto de interrupção definido em ProcessRequest , BeginProcessRequest e EndProcessRequest . Só ProcessRequest é executado. Em outra palavra, mesmo que AsyncMvcHandler implementos IHttpAsyncHandler . O ASP.NET MVC não sabem que e apenas lidar com isso como uma implementação IHttpHandler.
Como fazer ASP.NET MVC deleite AsyncMvcHandler como IHttpAsyncHandler para que possamos ter assíncrona processamento de página?
Solução 2
Depois de horas de aborrecimento com o código, eu descobri o problema.
Na minha Visual Studio 2008, quando eu pressionar Ctrl + F5, o Desenvolvimento Application Server é lançado e IE é apareceu para o acesso " http: // localhost: 3573 / ". Neste caso, a API sync ProcessRequest é invocado. O rastreamento de pilha é assim.
MyMvcApplication.DLL! MyMvcApplication.AsyncMvcRouteHandler.AsyncMvcHandler.ProcessRequest (System.Web.HttpContext httpContext = {System.Web.HttpContext}) Linha 59 C # System.Web.Mvc.dll! System.Web.Mvc.MvcHttpHandler.VerifyAndProcessRequest (System.Web.IHttpHandler httpHandler, System.Web.HttpContextBase httpContext) + 0x19 bytes
System.Web.Routing.dll! System.Web.Routing.UrlRoutingHandler.ProcessRequest (System.Web.HttpContextBase httpContext) + 0x66 bytes
System.Web.Routing.dll! System.Web.Routing.UrlRoutingHandler.ProcessRequest (System.Web.HttpContext httpContext) + 0x28 bytes
System.Web.Routing.dll! System.Web.Routing.UrlRoutingHandler.System.Web.IHttpHandler.ProcessRequest (System.Web.HttpContext contexto) + 0x8 bytes
MyMvcApplication.DLL! MyMvcApplication._Default.Page_Load (object = Remetente {}, ASP.default_aspx System.EventArgs e = {System.EventArgs}) Linha 13 + 0x1a bytes C #
No entanto, quando eu mudar a URL no IE para ser " http: // localhost: 3573 / whatever.mvc ", ela atinge o BeginProcessRequest . O rastreamento de pilha é assim.
MyMvcApplication.DLL! MyMvcApplication.AsyncMvcRouteHandler.AsyncMvcHandler.BeginProcessRequest (System.Web.HttpContext contexto = {} System.Web.HttpContext, System.AsyncCallback cb = {method = {Vazio OnAsyncHandlerCompletion (System.IAsyncResult)}}, objeto extraData = nulo) Linha 66 C # System.Web.dll! System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute () + 0x249 bytes System.Web.dll! System.Web.HttpApplication.ExecuteStep (System.Web.HttpApplication.IExecutionStep etapa = {System.Web.HttpApplication.CallHandlerExecutionStep}, ref bool completedSynchronously = true) + 0x9C bytes
System.Web.dll! System.Web.HttpApplication.ApplicationStepManager.ResumeSteps (System.Exception erro) + 0x133 bytes
System.Web.dll! System.Web.HttpApplication.System.Web.IHttpAsyncHandler.BeginProcessRequest (System.Web.HttpContext contexto, System.AsyncCallback cb, objeto extraData) + 0x7c bytes
System.Web.dll! System.Web.HttpRuntime.ProcessRequestInternal (System.Web.HttpWorkerRequest wr = {Microsoft.VisualStudio.WebHost.Request}) + 0x17c bytes System.Web.dll! System.Web.HttpRuntime.ProcessRequestNoDemand (System.Web.HttpWorkerRequest wr) + 0x63 bytes
System.Web.dll! System.Web.HttpRuntime.ProcessRequest (System.Web.HttpWorkerRequest wr) + 0x47 bytes
WebDev.WebHost.dll! Microsoft.VisualStudio.WebHost.Request.Process () + 0xf1 bytes WebDev.WebHost.dll! Microsoft.VisualStudio.WebHost.Host.ProcessRequest (Microsoft.VisualStudio.WebHost.Connection conn) + 0x4E bytes
Parece que só url com ".mvc" sufixo pode fazer API assíncrona invocada.
Outras dicas
Eu tive o mesmo problema, no entanto, achamos que era porque o meu pegar todos manipulador de rota:
routes.MapRoute(
"Default",
"{controller}/{action}",
new { controller = "Home", action = "Index" }
);
Foi pegar o pedido, não a rota personalizada Acrescentei que lidou com o manipulador de rota assíncrona. Talvez usando a .mvc em sua rota personalizada defintion você criou uma distinção para que ele foi usado em vez do síncrona pega-tudo.
Eu tentei fazer isso no passado, eu conseguir ter tanto o objectivo de render e, em seguida, todas as tarefas assíncronas iria terminar. Ou as tarefas assíncronos para concluir, mas a vista não iria render.
Eu criei um RouteCollectionExtensions baseado no código MVC originais. Na minha AsyncMvcHandler, eu tinha um método vazio (sem exceção) para ProcessMethod.