Как выполнить действие контроллера из HttpModule в ASP.NET MVC? - PullRequest
1 голос
/ 07 августа 2011

У меня есть следующее IHttpModule, и я пытаюсь выяснить, как выполнить действие из контроллера для данного абсолютного или относительного URL.

public class CustomErrorHandlingModule : IHttpModule
{
    #region Implementation of IHttpModule

    public void Init(HttpApplication context)
    {
        context.Error += (sender, e) => 
            OnError(new HttpContextWrapper(((HttpApplication)sender).Context));
    }

    public void Dispose()
    {}

    public void OnError(HttpContextBase context)
    {
        // Determine error resource to display, based on HttpStatus code, etc.
        // For brevity, i'll hardcode it for this SO question.
        const string errorPage = @"/Error/NotFound";

        // Now somehow execute the correct controller for that route.
        // Return the html response.
    }
}

Как это можно сделать?

Ответы [ 4 ]

7 голосов
/ 07 августа 2011

Что-то в этом роде должно делать работу:

public void OnError(HttpContextBase context)
{
    context.ClearError();
    context.Response.StatusCode = 404;

    var rd = new RouteData();
    rd.Values["controller"] = "error";
    rd.Values["action"] = "notfound";
    IController controller = new ErrorController();
    var rc = new RequestContext(context, rd);
    controller.Execute(rc);
}

Вы также можете найти следующий связанный ответ полезным.

1 голос
/ 07 августа 2011

Я думаю, вам нужно использовать HttpContext.Current.RewritePath

Это позволяет вам изменить путь к файлу, который вы хотите использовать.Это то, что делает default.aspx, созданный в проектах MVC 2.

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

0 голосов
/ 07 августа 2011

Привет, используйте это, чтобы инфраструктура могла выполнить код для этого пути, используя маршрутизацию и все компоненты:

    // MVC 3 running on IIS 7+
    if (HttpRuntime.UsingIntegratedPipeline)
    {
        context.Server.TransferRequest(url, true);
    }
    else
    {
        // Pre MVC 3
        context.RewritePath(url, false);

        IHttpHandler httpHandler = new MvcHttpHandler();
        httpHandler.ProcessRequest(httpContext);
    }

И в идеале обработка запросов на этом завершена.Если это не так, и если запрос обрабатывается далее по конвейеру http asp.net, используйте это, чтобы остановить запрос на этом этапе и сообщить asp.net, что мы закончили с этим запросом:

HttpApplication app = (HttpApplication) context.Application;
app.CompleteRequest();;

Я не уверен, что у контекста есть Приложение (сейчас я не рядом с VS), но при необходимости использую его для остановки запроса в этом модуле.

0 голосов
/ 07 августа 2011

Вы можете использовать HttpContext:

System.Web.HttpContext.Current.Response.Redirect("/Error/NotFound");
...