Как заставить ASP.NET MVC распознавать IHttpAsyncHandler из IRouteHandler.GetHttpHandler()?

StackOverflow https://stackoverflow.com/questions/276867

Вопрос

В этом вопрос ответ, я нашел один способ заставить ASP.NET MVC поддерживать асинхронную обработку.Однако я не могу заставить это работать.

По сути, идея состоит в том, чтобы создать новую реализацию IRouteHandler, имеющую только один метод. GetHttpHandlerGetHttpHandler Метод должен возвращать реализацию IHttpAsyncHandler вместо просто IHttpHandler, поскольку IHttpAsyncHandler имеет API шаблона Begin/EndXXXX.

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();
        }
    }
}

Затем в методе RegisterRoutes файла Global.asax.cs зарегистрируйте этот класс. Асинкмвкрутхандлер.public static void registerroutes (routecollection routs) {routes.ignoreroute ("{resource} .axd/{*pathinfo}");

        routes.Add(new Route("{controller}/{action}/{id}", new AsyncMvcRouteHandler())
        {
            Defaults = new RouteValueDictionary(new { controller = "Home", action = "Index", id = "" }),
        });
    }

Я установил точку останова в ПроцессЗапрос, Бегинпроцессреквест и EndProcessRequest.Только ПроцессЗапрос выполняется.Другими словами, хотя Асинкмвкхандлер реализует IHttpAsyncHandler.ASP.NET MVC этого не знает и просто обрабатывает это как реализацию IHttpHandler.

Как заставить ASP.NET MVC лечить Асинкмвкхандлер как IHttpAsyncHandler чтобы мы могли иметь асинхронную обработку страниц?

Это было полезно?

Решение 2

После нескольких часов возни с кодом я обнаружил проблему.

В моей Visual Studio 2008, когда я нажимаю Ctrl+F5, запускается сервер разработки приложений и появляется IE для доступа к "http://локальный хост:3573/".В этом случае API синхронизации ПроцессЗапрос вызывается.Трассировка стека выглядит следующим образом.

Mymvcapplication.dll! Mymvcapplication.asyncmvcroutehandler.asyncmvchandler.processRequest (System.Web.httpContext httpContext = {System.Web.httpContext}) line 59 CS# System.web.Wemv. Система Web.ihttphandler httphandler, system.web.httpcontextbase httpcontext) + 0x19 байт
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 Context) + 0x8 Bytes
Mymvcapplication.dll! Mymvcapplication._default.page_load (Object Sender = {asp.default_aspx}, System.eventargs e = {System.eventargs}) строка 13 + 0x1a Bytes c#

Однако, когда я меняю URL-адрес в IE на «http://localhost:3573/whatever.mvc", оно попадает в Бегинпроцессреквест.Трассировка стека выглядит следующим образом.

Mymvcapplication.dll! Mymvcapplication.asyncmvcroutehandler.asyncmvchandler.beginProcessRequest (System.Web.httpContext context = {System.Web.httpContext}, System.Asynccallback cb = {method = {void onAsyNCHANDLER (System.Comlate. ata = null ) Line 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 step = {system.web.httpapplication.callhandlerexecutionstep}, ref bool
System.web.dll! System.web.httpapplication.applicationStepManager.Resumesteps (System.Exception Error) + 0x133 Bytes
System.web.dll! System.web.httpapplication.system.web.ihttpasynchandler.beginProcessRequest (System.Web.httpContext Context, System.Asynccallback CB, Object Extradata) + 0x7c Bytes
System.web.dll! System.web.httpruntime.processrequestinternal (System.Web.httpWorkerRequest wr = {microsoft.visualstudio.webhost.request}) + 0x17c Bytes System.web.dll! Web.httpworkerRequest wr) + 0x63 байт
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.connect

Кажется, что только URL-адрес с суффиксом «.mvc» может вызывать асинхронный API.

Другие советы

У меня была та же проблема, но я обнаружил, что это потому, что мой обработчик перехвата всех маршрутов:

routes.MapRoute(
    "Default",                                                  
    "{controller}/{action}",                           
    new { controller = "Home", action = "Index" }  
);

Получал запрос, а не пользовательский маршрут, который я добавил, который имел дело с обработчиком асинхронных маршрутов. Возможно, используя .mvc в своем пользовательском определении маршрута, вы создали различие, чтобы оно использовалось, а не как синхронный универсальный элемент.

Я пытался сделать это в прошлом, мне удается либо отобразить представление, и тогда все асинхронные задачи завершатся. Или асинхронные задачи для завершения, но представление не будет отображаться.

Я создал RouteCollectionExtensions на основе исходного кода MVC. В моем AsyncMvcHandler у меня был пустой метод (без исключения) для ProcessMethod.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top