在 catch 块中设置时 TempData 为空,我们重新抛出
TempData is empty when set in a catch block and we rethrow
我正在使用自定义错误 (web.config
) 将未处理的异常发送到我的 ErrorController
。
在我的主控制器中,我抛出一个异常,在 catch
块中捕获它并设置 TempData
以显示一些用户友好的消息。我然后 throw
然后发送到 ErrorController
.
当我在这里检查 TempData
时,它是空的(Session
也是空的,但应该是,不是吗?)。
我确定它不应该是空的,这是在控制器之间发送数据的正确方式...但它不起作用!我是不是理解错了?
HomeController
:
catch (Exception ex)
{
TempData["MsgForUser"] = "useful message to show";
// Do some logging...
throw;
}
ErrorController
:
public ActionResult DisplayError(int id)
{
ViewBag.MsgForUser = TempData["MsgForUser"];
return View();
}
Web.config
:
<system.web>
<customErrors mode="On" defaultRedirect="~/ErrorPage/DisplayError">
<error redirect="~/Error/DisplayError/403" statusCode="403" />
<error redirect="~/Error/DisplayError/404" statusCode="404" />
<error redirect="~/Error/DisplayError/500" statusCode="500" />
</customErrors>
使用 RedirectToAction() 方法时 TempData 是稳定的,在异常处理中 ASP.net 是否使用此方法?也许不吧 !!
为什么不使用 Exception.Message 设置用户友好消息?在您的 catch 块中设置 ex.Message
,然后在您的错误视图中您可以访问它。您的错误视图模型必须是 @model HandleErrorInfo
,并且 @Model.Exception.Message
已设置您的消息!
我发现会话在顶层 catch
块中执行 throw
时被销毁,因为请求错误控制器。
但是我确实发现返回的 RedirectToAction()
保留了它。
所以,我创建了自己的异常类型:
public class MyApplicationException : Exception
{
/// <summary>
/// A message that can be shown to the user i.e. not technical
/// </summary>
public string MessageForUser { get; set; }
public MyApplicationException()
{
}
public MyApplicationException(string message, string messageForUser="")
: base(message)
{
MessageForUser = messageForUser;
}
public MyApplicationException(string message, Exception inner, string messageForUser = "")
: base(message, inner)
{
MessageForUser = messageForUser;
}
}
然后,当我遇到预期的问题并最终将用户发送到一般错误页面时,我会这样使用它:
if (MyList.Count > 14)
{
throw new MyApplicationException("More than 14 records received: " + MyList.Count.ToString(), "There is a maximum limit of 14 records that can be processed at a time. Please call us to discuss your requirement to process in greater quantities.");
}
捕捉到它后,我为用户挑选消息,记录错误,然后 return RedirectToAction()
转到错误页面而不丢失 TempData
。
catch (MyApplicationException myAppEx)
{
// If there is a user-friendly message then store it for DisplayError to show
if (String.IsNullOrEmpty(myAppEx.MessageForUser) == false)
{
TempData["MsgForUser"] = myAppEx.MessageForUser;
}
// Do some logging to elmah or a custom logger
util.LogError(myAppEx, "MyFunc() threw an exception", args);
//
// We cannot throw here because we lose the Session & TempData. we have to do a manual redirect.
//
return RedirectToAction("DisplayError", "ErrorPage", new { id = 500 });
}
最后在我看来,我寻找它并显示它是否存在:
<p>
An error occurred. Please check & try again later.
</p>
@if (String.IsNullOrEmpty(ViewBag.MsgForUser) == false)
{
<p class="more-info">Details: @ViewBag.MsgForUser</p>
}
我正在使用自定义错误 (web.config
) 将未处理的异常发送到我的 ErrorController
。
在我的主控制器中,我抛出一个异常,在 catch
块中捕获它并设置 TempData
以显示一些用户友好的消息。我然后 throw
然后发送到 ErrorController
.
当我在这里检查 TempData
时,它是空的(Session
也是空的,但应该是,不是吗?)。
我确定它不应该是空的,这是在控制器之间发送数据的正确方式...但它不起作用!我是不是理解错了?
HomeController
:
catch (Exception ex)
{
TempData["MsgForUser"] = "useful message to show";
// Do some logging...
throw;
}
ErrorController
:
public ActionResult DisplayError(int id)
{
ViewBag.MsgForUser = TempData["MsgForUser"];
return View();
}
Web.config
:
<system.web>
<customErrors mode="On" defaultRedirect="~/ErrorPage/DisplayError">
<error redirect="~/Error/DisplayError/403" statusCode="403" />
<error redirect="~/Error/DisplayError/404" statusCode="404" />
<error redirect="~/Error/DisplayError/500" statusCode="500" />
</customErrors>
使用 RedirectToAction() 方法时 TempData 是稳定的,在异常处理中 ASP.net 是否使用此方法?也许不吧 !!
为什么不使用 Exception.Message 设置用户友好消息?在您的 catch 块中设置 ex.Message
,然后在您的错误视图中您可以访问它。您的错误视图模型必须是 @model HandleErrorInfo
,并且 @Model.Exception.Message
已设置您的消息!
我发现会话在顶层 catch
块中执行 throw
时被销毁,因为请求错误控制器。
但是我确实发现返回的 RedirectToAction()
保留了它。
所以,我创建了自己的异常类型:
public class MyApplicationException : Exception
{
/// <summary>
/// A message that can be shown to the user i.e. not technical
/// </summary>
public string MessageForUser { get; set; }
public MyApplicationException()
{
}
public MyApplicationException(string message, string messageForUser="")
: base(message)
{
MessageForUser = messageForUser;
}
public MyApplicationException(string message, Exception inner, string messageForUser = "")
: base(message, inner)
{
MessageForUser = messageForUser;
}
}
然后,当我遇到预期的问题并最终将用户发送到一般错误页面时,我会这样使用它:
if (MyList.Count > 14)
{
throw new MyApplicationException("More than 14 records received: " + MyList.Count.ToString(), "There is a maximum limit of 14 records that can be processed at a time. Please call us to discuss your requirement to process in greater quantities.");
}
捕捉到它后,我为用户挑选消息,记录错误,然后 return RedirectToAction()
转到错误页面而不丢失 TempData
。
catch (MyApplicationException myAppEx)
{
// If there is a user-friendly message then store it for DisplayError to show
if (String.IsNullOrEmpty(myAppEx.MessageForUser) == false)
{
TempData["MsgForUser"] = myAppEx.MessageForUser;
}
// Do some logging to elmah or a custom logger
util.LogError(myAppEx, "MyFunc() threw an exception", args);
//
// We cannot throw here because we lose the Session & TempData. we have to do a manual redirect.
//
return RedirectToAction("DisplayError", "ErrorPage", new { id = 500 });
}
最后在我看来,我寻找它并显示它是否存在:
<p>
An error occurred. Please check & try again later.
</p>
@if (String.IsNullOrEmpty(ViewBag.MsgForUser) == false)
{
<p class="more-info">Details: @ViewBag.MsgForUser</p>
}