Adr*_*ila 64 asp.net-mvc exception
如何正确处理ASP.NET MVC中从控制器抛出的异常?该HandleError属性似乎只处理由MVC基础结构抛出的异常,而不是我自己的代码抛出的异常.
使用此web.config
<customErrors mode="On">
<error statusCode="401" redirect="/Errors/Http401" />
</customErrors>
Run Code Online (Sandbox Code Playgroud)
使用以下代码
namespace MvcApplication1.Controllers
{
[HandleError]
public class HomeController : Controller
{
public ActionResult Index()
{
// Force a 401 exception for testing
throw new HttpException(401, "Unauthorized");
}
}
}
Run Code Online (Sandbox Code Playgroud)
不会导致我所希望的.相反,我得到通用的ASP.NET错误页面,告诉我修改我的web.config以查看实际的错误信息.但是,如果不是抛出异常而是返回无效的View,我会得到/Shared/Views/Error.aspx页面:
return View("DoesNotExist");
Run Code Online (Sandbox Code Playgroud)
像我上面所做的那样在控制器中抛出异常似乎绕过了所有HandleError功能,那么创建错误页面的正确方法是什么,以及如何在MVC基础架构中发挥良好作用?
小智 63
Controller.OnException(ExceptionContext context).覆盖它.
protected override void OnException(ExceptionContext filterContext)
{
// Bail if we can't do anything; app will crash.
if (filterContext == null)
return;
// since we're handling this, log to elmah
var ex = filterContext.Exception ?? new Exception("No further information exists.");
LogException(ex);
filterContext.ExceptionHandled = true;
var data = new ErrorPresentation
{
ErrorMessage = HttpUtility.HtmlEncode(ex.Message),
TheException = ex,
ShowMessage = !(filterContext.Exception == null),
ShowLink = false
};
filterContext.Result = View("ErrorPage", data);
}
Run Code Online (Sandbox Code Playgroud)
Adr*_*ila 21
感谢kazimanzurrashaid,这是我在Global.asax.cs做的事情:
protected void Application_Error()
{
Exception unhandledException = Server.GetLastError();
HttpException httpException = unhandledException as HttpException;
if (httpException == null)
{
Exception innerException = unhandledException.InnerException;
httpException = innerException as HttpException;
}
if (httpException != null)
{
int httpCode = httpException.GetHttpCode();
switch (httpCode)
{
case (int) HttpStatusCode.Unauthorized:
Response.Redirect("/Http/Error401");
break;
}
}
}
Run Code Online (Sandbox Code Playgroud)
我将能够根据我需要支持的任何其他HTTP错误代码向HttpContoller添加更多页面.
Cra*_*ntz 13
HandleError属性似乎只处理MVC基础结构抛出的异常,而不是我自己的代码抛出的异常.
那是错的.实际上,HandleError只会"处理"您自己的代码或您自己的代码调用的代码中抛出的异常.换句话说,只有您的操作在调用堆栈中的异常.
您所看到的行为的真实解释是您抛出的特定异常.HandleError与HttpException的行为不同.从源代码:
// If this is not an HTTP 500 (for example, if somebody throws an HTTP 404 from an action method),
// ignore it.
if (new HttpException(null, exception).GetHttpCode() != 500) {
return;
}
Run Code Online (Sandbox Code Playgroud)
我不认为您将能够基于具有HandleError属性的HttpCode显示特定的ErrorPage,我更倾向于使用HttpModule来实现此目的.假设我有文件夹"ErrorPages",其中存在针对每个特定错误的不同页面,并且在web.config中指定映射与常规Web表单应用程序相同.以下是用于显示错误页面的代码:
public class ErrorHandler : BaseHttpModule{
public override void OnError(HttpContextBase context)
{
Exception e = context.Server.GetLastError().GetBaseException();
HttpException httpException = e as HttpException;
int statusCode = (int) HttpStatusCode.InternalServerError;
// Skip Page Not Found and Service not unavailable from logging
if (httpException != null)
{
statusCode = httpException.GetHttpCode();
if ((statusCode != (int) HttpStatusCode.NotFound) && (statusCode != (int) HttpStatusCode.ServiceUnavailable))
{
Log.Exception(e);
}
}
string redirectUrl = null;
if (context.IsCustomErrorEnabled)
{
CustomErrorsSection section = IoC.Resolve<IConfigurationManager>().GetSection<CustomErrorsSection>("system.web/customErrors");
if (section != null)
{
redirectUrl = section.DefaultRedirect;
if (httpException != null)
{
if (section.Errors.Count > 0)
{
CustomError item = section.Errors[statusCode.ToString(Constants.CurrentCulture)];
if (item != null)
{
redirectUrl = item.Redirect;
}
}
}
}
}
context.Response.Clear();
context.Response.StatusCode = statusCode;
context.Response.TrySkipIisCustomErrors = true;
context.ClearError();
if (!string.IsNullOrEmpty(redirectUrl))
{
context.Server.Transfer(redirectUrl);
}
}
Run Code Online (Sandbox Code Playgroud)
}
| 归档时间: |
|
| 查看次数: |
48773 次 |
| 最近记录: |