如何从ASP.NET MVC中的HttpModule执行控制器操作?

时间:2011-08-07 11:34:57

标签: c# .net asp.net-mvc httpmodule

我有以下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 个答案:

答案 0 :(得分:7)

有些事情应该可以胜任:

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

您可能还会发现以下related answer有用。

答案 1 :(得分:1)

我认为您需要使用HttpContext.Current.RewritePath

这使您可以更改要使用的文件的路径。这是MVC 2项目中创建的default.aspx

我使用它的方式与你一样,在没有302的情况下进行错误处理但是现在无法访问我的代码。我将在周一发布一些代码。

答案 2 :(得分:0)

您可以使用HttpContext:

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

答案 3 :(得分:0)

您可以使用此框架让框架使用路由和所有组件执行该路径的代码:

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

理想情况下,请求处理在此时完成。如果不是这种情况,并且如果请求是在asp.net http管道上进一步处理的,那么在此时使用它来停止请求,并告诉asp.net我们已经完成了这个请求:

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

我不确定上下文是否有应用程序(我现在不在VS附近),但如果需要,可以使用它来停止此模块中的请求。