gpt4 book ai didi

c# - ASP.MVC HandleError 属性不起作用

转载 作者:太空狗 更新时间:2023-10-29 19:53:41 27 4
gpt4 key购买 nike

我知道这是一个常见问题,但我已经抓取了很多讨论但没有结果。

我正在尝试使用 HandleError ASP.MVC 属性处理错误。我正在使用 MVC 4。

我的错误页面位于 Views/Shared/Error.cshtml 中,看起来像这样:

Test error page
<hgroup class="title">
<h1 class="error">Error.</h1>
<h2 class="error">An error occurred while processing your request.</h2>
</hgroup>

我在 App-Start 文件夹中的 FilterConfig.cs 是:

public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
}
}

我的 Controller :

public class TestController : Controller
{
[HandleError(View = "Error")]
public ActionResult Index()
{
throw new Exception("oops");
}
}

最后我的 Web.config 中有以下节点:

<customErrors mode="On" defaultRedirect="Error">
</customErrors>

当我调用 Controller 操作时,我得到一个带有以下文本的白屏:

Server Error in '/' Application.

Runtime Error Description: An exception occurred while processing your request. Additionally, another exception occurred while executing the custom error page for the first exception. The request has been terminated.

如果 defaultRedirect="Error"没有在 Web.config 中设置,那么我会得到带有以下文本的黄色屏幕:

Server Error in '/' Application.

Runtime Error Description: An application error occurred on the server. The current custom error settings for this application prevent the details of the application error from being viewed.

Details: To enable the details of this specific error message to be viewable on the local server machine, please create a tag within a "web.config" configuration file located in the root directory of the current web application. This tag should then have its "mode" attribute set to "RemoteOnly". To enable the details to be viewable on remote machines, please set "mode" to "Off".

Notes: The current error page you are seeing can be replaced by a custom error page by modifying the "defaultRedirect" attribute of the application's configuration tag to point to a custom error page URL.

有谁知道哪里出了问题?

编辑:

错误是由使用强类型布局引起的。当抛出错误时,MVC 的错误处理机制正在创建传递给错误 View 的 HandleErrorInfo 对象。但是,如果我们使用强类型布局,则类型不匹配。

在我的案例中,解决方案是使用 Global.asax 中的 Application_Error 方法,下面的 SBirthare 对此进行了完美描述。

最佳答案

多年来,我一直在努力顺利地在 ASP.NET MVC 中实现“处理自定义错误”。

我之前曾成功使用过 Elmah,但对需要以不同方式处理和测试的众多案例(即本地与 IIS)感到不知所措。

最近在我的一个正在运行的项目中,我使用了以下方法(似乎在本地和生产环境中运行良好)。

我根本没有指定 customErrors 或 web.config 中的任何设置。

我重写 Application_Error 并在那里处理所有情况,调用 ErrorController 中的特定操作。

如果它有帮助,我会分享它并获得反馈(尽管一切正常,但您永远不知道它何时开始崩溃;))

Global.asax.cs

public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();

WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
AuthConfig.RegisterAuth();
}

protected void Application_Error(object sender, EventArgs e)
{
System.Diagnostics.Trace.WriteLine("Enter - Application_Error");

var httpContext = ((MvcApplication)sender).Context;

var currentRouteData = RouteTable.Routes.GetRouteData(new HttpContextWrapper(httpContext));
var currentController = " ";
var currentAction = " ";

if (currentRouteData != null)
{
if (currentRouteData.Values["controller"] != null &&
!String.IsNullOrEmpty(currentRouteData.Values["controller"].ToString()))
{
currentController = currentRouteData.Values["controller"].ToString();
}

if (currentRouteData.Values["action"] != null &&
!String.IsNullOrEmpty(currentRouteData.Values["action"].ToString()))
{
currentAction = currentRouteData.Values["action"].ToString();
}
}

var ex = Server.GetLastError();

if (ex != null)
{
System.Diagnostics.Trace.WriteLine(ex.Message);

if (ex.InnerException != null)
{
System.Diagnostics.Trace.WriteLine(ex.InnerException);
System.Diagnostics.Trace.WriteLine(ex.InnerException.Message);
}
}

var controller = new ErrorController();
var routeData = new RouteData();
var action = "CustomError";
var statusCode = 500;

if (ex is HttpException)
{
var httpEx = ex as HttpException;
statusCode = httpEx.GetHttpCode();

switch (httpEx.GetHttpCode())
{
case 400:
action = "BadRequest";
break;

case 401:
action = "Unauthorized";
break;

case 403:
action = "Forbidden";
break;

case 404:
action = "PageNotFound";
break;

case 500:
action = "CustomError";
break;

default:
action = "CustomError";
break;
}
}
else if (ex is AuthenticationException)
{
action = "Forbidden";
statusCode = 403;
}

httpContext.ClearError();
httpContext.Response.Clear();
httpContext.Response.StatusCode = statusCode;
httpContext.Response.TrySkipIisCustomErrors = true;
routeData.Values["controller"] = "Error";
routeData.Values["action"] = action;

controller.ViewData.Model = new HandleErrorInfo(ex, currentController, currentAction);
((IController)controller).Execute(new RequestContext(new HttpContextWrapper(httpContext), routeData));
}

}

ErrorController.cs

public class ErrorController : Controller
{
public ActionResult PageNotFound()
{
Response.StatusCode = (int)HttpStatusCode.NotFound;
return View();
}

public ActionResult CustomError()
{
Response.StatusCode = (int)HttpStatusCode.InternalServerError;
return View();
}
}

这就是我的全部。没有注册 HandleErrorAttribute

我发现这种方法不那么令人困惑,而且易于扩展。希望这对某人有帮助。

关于c# - ASP.MVC HandleError 属性不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26357340/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com