【问题标题】:Asynchronous error controller in ASP.NET MVCASP.NET MVC 中的异步错误控制器
【发布时间】:2015-02-19 11:23:06
【问题描述】:

谁能帮我获得一个在 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 模板的登录代码相同(不是旧的表单身份验证)。 preserveUser 参数似乎不起作用。

有人弄过这样的异步控制器吗?

有人知道如何解决在 TransferRequest 上丢失 ASP 身份的问题吗?

相关问题包括Application_Error handler isn't fired when use prefix async,它的解决方案比不使用异步(一次使用两个线程)更糟糕。还有另一个已回答的问题similar to mine,但没有 TransferRequest。

【问题讨论】:

  • 你能发布你的控制器方法吗?可能根本就不是async
  • 我可以让控制器在没有异步的情况下工作,但最好让一切都异步。错误控制器需要数据库访问权以建议可能的页面并可能将用户重定向到正确的页面。
  • 如果控制器只显示视图,它不应该是异步的。异步用于 i/o 操作
  • 我在上面的评论中提到错误控制器需要数据库访问。这是检索视图数据和/或重定向到哪个页面所必需的。数据库访问是异步操作非常有用的一个完美示例。
  • 我可能错过了,很高兴你找到了解决方案!

标签: c# asp.net-mvc asp.net-mvc-4 asynchronous error-handling


【解决方案1】:

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

代替代码:

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 标识丢失。

【讨论】:

  • 第二个参数是 preserveForm 在我的情况下设置为 true 很有用 - 值得留意
猜你喜欢
  • 2012-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-05
  • 1970-01-01
  • 1970-01-01
  • 2015-08-24
  • 1970-01-01
相关资源
最近更新 更多