【发布时间】:2015-02-20 07:49:49
【问题描述】:
我正在开发 ASP.NET MVC 应用程序,为了处理错误,我遵循了这个tutorial。所以,FilterConfig.cs中的代码:
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
filters.Add(new CustomHandleErrorAttribute());
}
我在 Controllers 文件夹中添加了一个 ErrorController:
public class ErrorController : Controller
{
// GET: Error
public ActionResult Index()
{
return View();
}
}
我还创建了 View 以在 Views/Error 中显示错误:
@model System.Web.Mvc.HandleErrorInfo
@{
ViewBag.Title = "Index";
}
<h1 class="text-danger">Custom Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2>
<h2>Exception details</h2>
<p>
Controller: @Model.ControllerName <br />
Action: @Model.ActionName<br />
Message: @Model.Exception.Message <br />
StackTrace: <br />
</p>
<pre>Exception: @Model.Exception.StackTrace</pre>
然后我创建了 Admin Area 并将所有管理员的视图移动到 Admin 文件夹。管理区有自己的布局,与主布局不同。
为了处理管理区域中的错误,我还在~/Areas/Admin/Controllers 中创建了ErrorController.cs 并在~/Areas/Admin/Views/Error 中创建了它的视图,以在管理员的布局中显示错误,但是当错误发生在管理员页面时。它将在主布局中显示消息(~/Views/Error)
如何处理MVC中各个区域的错误?
CustomErrorHandlerAttribute.cs
public class CustomHandleErrorAttribute : HandleErrorAttribute
{
public override void OnException(ExceptionContext filterContext)
{
//base.OnException(filterContext);
// Log the error using Elmah & NLog
if (filterContext.Exception is DbEntityValidationException)
{
DbEntityValidationException dbevex = filterContext.Exception as DbEntityValidationException;
var errorMessages = (from eve in dbevex.EntityValidationErrors
let entity = eve.Entry.Entity.GetType().Name
from ev in eve.ValidationErrors
select new
{
Entity = entity,
PropertyName = ev.PropertyName,
ErrorMessage = ev.ErrorMessage
});
var fullErrorMessage = string.Join("; ", errorMessages.Select(e => string.Format("[Entity: {0}, Property: {1}] {2}", e.Entity, e.PropertyName, e.ErrorMessage)));
var exceptionMessage = string.Concat(dbevex.Message, " The validation errors are: ", fullErrorMessage);
LogUtility.logger.Error(exceptionMessage);
ErrorSignal.FromCurrentContext().Raise(new DbEntityValidationException(exceptionMessage, dbevex.EntityValidationErrors));
}
else
{
LogUtility.logger.Error(filterContext.Exception.Message, filterContext.Exception);
}
if (filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled)
{
return;
}
if (new HttpException(null, filterContext.Exception).GetHttpCode() != 500)
{
return;
}
if (!ExceptionType.IsInstanceOfType(filterContext.Exception))
{
return;
}
// If the request is AJAX return JSON else view
if (filterContext.HttpContext.Request.IsAjaxRequest()) //if (filterContext.HttpContext.Request.Headers["X-Requested-With"] == "XMLHttpRequest")
{
// Because it's exception raised after ajax invocation, return Json
filterContext.Result = new JsonResult
{
Data = new
{
error = true,
message = filterContext.Exception.Message
},
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
else
{
var controllerName = (string)filterContext.RouteData.Values["controller"];
var actionName = (string)filterContext.RouteData.Values["action"];
var model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName);
filterContext.Result = new ViewResult()
{
ViewName = View,
MasterName = Master,
ViewData = new ViewDataDictionary<HandleErrorInfo>(model),
TempData = filterContext.Controller.TempData
};
}
filterContext.ExceptionHandled = true;
filterContext.HttpContext.Response.Clear();
filterContext.HttpContext.Response.StatusCode = 500;
filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
}
}
RouteConfig.cs
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
// Visual Studio 2013 Browser Link caused
// "The controller for path '/9ac086a69364466a841e03e001f946fd/arterySignalR/ping' could not be found."
#if DEBUG
routes.IgnoreRoute("{*browserlink}", new { browserlink = @".*/arterySignalR/ping" });
#endif
// with code above, we can still use Browser Link feature without getting error
routes.MapRoute(
"AxCustomer",
"AxCustomer/{action}/{id}",
new { controller = "AX_CUSTTABLE", action = "Index", id = UrlParameter.Optional },
namespaces: new[] { "SalesSupportSystem.Controllers" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new[] { "SalesSupportSystem.Controllers" }
);
}
}
【问题讨论】:
-
你能把
HandleErrorAttribute.cs和CustomHandleErrorAttribute.cs的代码贴出来吗? -
@JoeMighty 我更新了问题,HandleErrorAttribute 是 MVC 的默认值
-
这个问题在这里得到解答:stackoverflow.com/questions/15935069/…
标签: c# asp.net asp.net-mvc asp.net-mvc-5