我有一些基本代码来确定我的MVC应用程序中的错误。目前在我的项目中,我有一个名为Error
的控制器,它具有动作方法HTTPError404()
、HTTPError500()
和General()
。它们都接受字符串参数error
。使用或修改下面的代码。将数据传递到错误控制器进行处理的最佳/适当方法是什么?我希望有一个尽可能健壮的解决方案。
protected void Application_Error(object sender, EventArgs e)
{
Exception exception = Server.GetLastError();
Response.Clear();
HttpException httpException = exception as HttpException;
if (httpException != null)
{
RouteData routeData = new RouteData();
routeData.Values.Add("controller", "Error");
switch (httpException.GetHttpCode())
{
case 404:
// page not found
routeData.Values.Add("action", "HttpError404");
break;
case 500:
// server error
routeData.Values.Add("action", "HttpError500");
break;
default:
routeData.Values.Add("action", "General");
break;
}
routeData.Values.Add("error", exception);
// clear error on server
Server.ClearError();
// at this point how to properly pass route data to error controller?
}
}
发布于 2009-07-23 13:40:28
不需要为此创建新的路由,您只需重定向到您的控制器/操作并通过querystring传递信息即可。例如:
protected void Application_Error(object sender, EventArgs e) {
Exception exception = Server.GetLastError();
Response.Clear();
HttpException httpException = exception as HttpException;
if (httpException != null) {
string action;
switch (httpException.GetHttpCode()) {
case 404:
// page not found
action = "HttpError404";
break;
case 500:
// server error
action = "HttpError500";
break;
default:
action = "General";
break;
}
// clear error on server
Server.ClearError();
Response.Redirect(String.Format("~/Error/{0}/?message={1}", action, exception.Message));
}
然后你的控制器会收到你想要的任何东西:
// GET: /Error/HttpError404
public ActionResult HttpError404(string message) {
return View("SomeView", message);
}
你的方法有一些权衡。在这种错误处理中,要非常非常小心地使用循环。另一件事是,由于您要通过asp.net管道来处理404,因此您将为所有这些命中创建一个会话对象。对于频繁使用的系统,这可能是一个问题(性能)。
发布于 2010-01-12 21:55:11
要回答最初的问题“如何正确地将routedata传递给错误控制器?”:
IController errorController = new ErrorController();
errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
然后在您的ErrorController类中,实现如下函数:
[AcceptVerbs(HttpVerbs.Get)]
public ViewResult Error(Exception exception)
{
return View("Error", exception);
}
这会将异常推送到视图中。视图页应声明如下:
<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<System.Exception>" %>
以及显示错误的代码:
<% if(Model != null) { %> <p><b>Detailed error:</b><br /> <span class="error"><%= Helpers.General.GetErrorMessage((Exception)Model, false) %></span></p> <% } %>
下面是从异常树中收集所有异常消息的函数:
public static string GetErrorMessage(Exception ex, bool includeStackTrace)
{
StringBuilder msg = new StringBuilder();
BuildErrorMessage(ex, ref msg);
if (includeStackTrace)
{
msg.Append("\n");
msg.Append(ex.StackTrace);
}
return msg.ToString();
}
private static void BuildErrorMessage(Exception ex, ref StringBuilder msg)
{
if (ex != null)
{
msg.Append(ex.Message);
msg.Append("\n");
if (ex.InnerException != null)
{
BuildErrorMessage(ex.InnerException, ref msg);
}
}
}
发布于 2011-05-10 23:45:39
我找到了Lion_cl提到的ajax问题的解决方案。
global.asax:
protected void Application_Error()
{
if (HttpContext.Current.Request.IsAjaxRequest())
{
HttpContext ctx = HttpContext.Current;
ctx.Response.Clear();
RequestContext rc = ((MvcHandler)ctx.CurrentHandler).RequestContext;
rc.RouteData.Values["action"] = "AjaxGlobalError";
// TODO: distinguish between 404 and other errors if needed
rc.RouteData.Values["newActionName"] = "WrongRequest";
rc.RouteData.Values["controller"] = "ErrorPages";
IControllerFactory factory = ControllerBuilder.Current.GetControllerFactory();
IController controller = factory.CreateController(rc, "ErrorPages");
controller.Execute(rc);
ctx.Server.ClearError();
}
}
ErrorPagesController
public ActionResult AjaxGlobalError(string newActionName)
{
return new AjaxRedirectResult(Url.Action(newActionName), this.ControllerContext);
}
AjaxRedirectResult
public class AjaxRedirectResult : RedirectResult
{
public AjaxRedirectResult(string url, ControllerContext controllerContext)
: base(url)
{
ExecuteResult(controllerContext);
}
public override void ExecuteResult(ControllerContext context)
{
if (context.RequestContext.HttpContext.Request.IsAjaxRequest())
{
JavaScriptResult result = new JavaScriptResult()
{
Script = "try{history.pushState(null,null,window.location.href);}catch(err){}window.location.replace('" + UrlHelper.GenerateContentUrl(this.Url, context.HttpContext) + "');"
};
result.ExecuteResult(context);
}
else
{
base.ExecuteResult(context);
}
}
}
AjaxRequestExtension
public static class AjaxRequestExtension
{
public static bool IsAjaxRequest(this HttpRequest request)
{
return (request.Headers["X-Requested-With"] != null && request.Headers["X-Requested-With"] == "XMLHttpRequest");
}
}
https://stackoverflow.com/questions/1171035
复制相似问题