1

同样有多篇文章说明了如何在重定向后访问数据。但不符合我的目的。

我有错误控制器,它有索引操作方法和错误索引视图。

如果应用程序中有任何错误,它将在 Application_Error 事件中捕获。

在 Application_Error 事件中,我记录了错误并像这样重定向到错误索引页面 -

protected new void Application_Error(object sender, EventArgs e)
{
     Exception error = Server.GetLastError();
     log.error(error.Message);
     HttpContext.Current.Response.Redirect("~/Error/Index");
}

现在在错误索引视图中,我想显示错误消息。在可以通过错误索引视图访问的 Application_Error 事件中我应该做什么?

更新:我不想使用 Session 因为会话对象在 Application_Error 事件中可能不可用。这取决于错误发生的时间。

4

2 回答 2

2

方法 - 1

据我所知,您可以使用 TempData 来存储发布的数据。它就像一个 DataReader 类,一旦读取,数据就会丢失。这样 TempData 中存储的数据就会变为空。

var Value = TempData["keyName"] //Once read, data will be lost

因此,即使在读取数据后也要保留数据,您可以像下面这样活着

var Value = TempData["keyName"];
TempData.Keep();                   //Data will not be lost for all Keys
TempData.Keep("keyName");          //Data will not be lost for this Key

TempData 也可以在新选项卡/Windows 中工作,就像 Session 变量一样。

您也可以使用会话变量,唯一的主要问题是会话变量与 TempData 相比非常重。最后,您还可以跨控制器/区域保留数据。

方法 - 2

这对我有用。这非常简单,无需考虑 Web.Config 中的任何更改或在 Global.asax 文件中注册操作过滤器。

好的。所以,首先我要创建一个简单的Action Filter。这将处理 Ajax 和非 Ajax 请求。

public class MyCustomErrorAttribute : HandleErrorAttribute
{
    public override void OnException(ExceptionContext filterContext)
    {
        filterContext.ExceptionHandled = true;
        var debugModeMsg = filterContext.HttpContext.IsDebuggingEnabled
                               ? filterContext.Exception.Message +
                                 "\n" +
                                 filterContext.Exception.StackTrace
                               : "Your error message";

//这是需要处理 Ajax 请求时的情况

        if (filterContext.HttpContext.Request.IsAjaxRequest())
        {
            filterContext.Result = new JsonResult
            {
                JsonRequestBehavior = JsonRequestBehavior.AllowGet,
                Data = new
                {
                    error = true,
                    message = debugModeMsg
                }
            };
        }

//这是处理非 Ajax 请求时的情况

        else
        {
            var routeData = new RouteData();
            routeData.Values["controller"] = "Error";
            routeData.Values["action"] = "Error";
            routeData.DataTokens["area"] = "app";
            routeData.Values["exception"] = debugModeMsg;
            IController errorsController = new ErrorController();
            var exception = HttpContext.Current.Server.GetLastError();
            var httpException = exception as HttpException;
            if (httpException != null)
            {
                Response.StatusCode = httpException.GetHttpCode();
                switch (System.Web.HttpContext.Current.Response.StatusCode)
                {
                    case 504:
                        routeData.Values["action"] = "Http404";
                        break;
                }
            }

            var rc = new RequestContext
                         (
                             new HttpContextWrapper(HttpContext.Current),
                             routeData
                         );
            errorsController.Execute(rc);
        }
        base.OnException(filterContext);
    }
}

现在您可以在控制器上以及仅在动作上实现此动作过滤器。示例:

在此处输入图像描述

我有点跑题了。我认为解释这一点很重要。

如果你注意上面突出显示的部分。我已经指定了动作过滤器的顺序。这基本上描述了Action Filter的执行顺序。这是当您通过控制器/动作方法实现多个动作过滤器时的情况

在此处输入图像描述

这张图片只是表明假设您有两个动作过滤器。OnActionExecution将开始按优先级执行,OnActionExecuted将从下到上开始。这意味着在OnActionExecuted具有最高顺序的动作过滤器的情况下将首先执行,而在OnActionExecuting具有最低顺序的动作过滤器的情况下将首先执行。下面的例子。

public class Filter1 : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {

//执行将从这里开始 - 1

        base.OnActionExecuting(filterContext);
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {

//执行将移到这里 - 5

        base.OnActionExecuted(filterContext);
    }
}

public class Filter2 : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {

//执行会移到这里 - 2

        base.OnActionExecuting(filterContext);
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {

//执行会移到这里 - 4

        base.OnActionExecuted(filterContext);
    }
}

[HandleError]
public class HomeController : Controller
{
    [Filter1(Order = 1)]
    [Filter2(Order = 2)]
    public ActionResult Index()
    {

//执行会移到这里 - 3

        ViewData["Message"] = "Welcome to ASP.NET MVC!";

        return View();
    }
}

您可能已经知道 MVC 框架中有不同类型的过滤器。它们在下面列出。

  1. 授权过滤器

  2. 动作过滤器

  3. 响应/结果过滤器

  4. 异常过滤器

在每个过滤器中,您可以指定 Order 属性。这基本上描述了动作过滤器的执行顺序。

于 2013-07-24T05:37:33.187 回答
1

用于TempData获取价值。

关于的一些功能TempData

  • TempData是一个字典对象,它派生自 TempDataDictionary 类并存储在短期会话中。
  • TempData用于将数据从当前请求传递到后续请求,以防重定向。
  • 它的生命很短,直到目标视图完全加载。

  • 需要对复杂数据类型进行类型转换并检查空值以避免错误。

  • 它仅用于存储一次消息,如错误消息、验证消息。

于 2013-07-24T05:32:47.150 回答