MVC ASP.NET 中的异步错误控制器

本文关键字:错误 错误控制 控制器 异步 ASP NET MVC | 更新日期: 2023-09-27 18:34:46

谁能帮我让一个异步错误控制器在 ASP MVC 中工作。我让它在没有异步的情况下工作,但这似乎不对。我开始使用的代码如下:

void Application_Error(object sender, EventArgs e)
{
        Exception exception = Server.GetLastError();
        // A good location for any error logging, otherwise, do it inside of the error controller.
        // Clear the error, otherwise, we will always get the default error page.
        Server.ClearError();
        Response.Clear();
        Response.TrySkipIisCustomErrors = true;
        var code = (exception is HttpException) ? (exception as HttpException).GetHttpCode() : 500;
        var routeData = new RouteData();
        routeData.Values.Add("controller", "Error");
        routeData.Values.Add("action", "index");
        IController errorController = ClassFactory.Resolve<ErrorController>();
        errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
}

我的错误控制器的方法签名如下:

    [AllowAnonymous]
    public ActionResult Index(int code = 500)
    {

如果我使错误控制器方法异步,则 Application_Error 中的 Execute 方法会引发异常"异步操作方法'index'返回无法同步执行的任务"。

我最有希望的尝试之一是转移请求。这在 applicaiton_error 方法中使用以下代码:

var code = (exception is HttpException) ? (exception as HttpException).GetHttpCode() : 500;
var headers = new NameValueCollection
{
    {"ErrorUrl", Context.Request.RawUrl},
    {"ErrorCode", code.ToString()}
};
Context.Server.TransferRequest("~/error", false, null, headers, true);

这运行良好且异步,我可以在请求标头中传递错误数据。不幸的是,Server.TransferRequest 调用丢失了有关当前登录用户的详细信息,并且用户将在错误页面上显示为已注销。用户登录代码当前与VS2013模板相同(不是旧表单身份验证(。保留用户参数似乎不起作用。

有没有人让这样的异步控制器工作?

有谁知道如何解决ASP身份在转移请求中丢失的问题?

相关问题包括Application_Error使用前缀异步时处理程序不会触发,其解决方案比不使用异步(一次使用两个线程(更糟糕。还有另一个与我类似的问题,但没有转移请求。

MVC ASP.NET 中的异步错误控制器

Context.Server.TransferRequest 是解决问题的正确方法。此函数通过整个 IIS 管道发送以下请求。我丢失ASP标识的原因是它存储在会话中。会话使用 Cookie 链接到客户端。饼干位于标题中。

而不是代码:

var code = (exception is HttpException) ? (exception as HttpException).GetHttpCode() : 500;
var headers = new NameValueCollection
{
    {"ErrorUrl", Context.Request.RawUrl},
    {"ErrorCode", code.ToString()}
};
Context.Server.TransferRequest("~/error", false, null, headers, true);

我已经让它与:

var code = (exception is HttpException) ? (exception as HttpException).GetHttpCode() : 500;
var headers = Request.Headers;
headers.Add(new NameValueCollection
{
    {"ErrorUrl", Context.Request.RawUrl},
    {"ErrorCode", code.ToString()}
});
Context.Server.TransferRequest("~/error", false, null, headers, true);

主要区别在于我传递了当前请求的标头,其中包含链接到会话的cookie。这可以防止丢失 ASP.NET 标识。