c# - 使用 MVC2 的 HandleErrorInfo - 模型为空?

标签 c# asp.net asp.net-mvc asp.net-mvc-2

我有一个即将发布的 MVC 2 网络应用程序。到目前为止,我已经关闭了自定义错误,但我希望它们在我准备好投入生产时正常工作。

我已经使用以下内容设置了我的 web.config:

<customErrors mode="On" defaultRedirect="/Error/">
  <error statusCode="404" redirect="/Error/NotFound "/>
</customErrors>

404 完美运行,NotFound 是一个直接映射到 View 的操作,该 View 仅使用我自己的 Site.Master 文件显示非常标准的 404 页面。

对于除 404 以外的任何情况,我希望用户能够查看异常详细信息。 (这是一个内部应用程序,这样做没有安全风险)。

Error 默认操作 Index 设置为返回我定义的 View()。我想不通的是如何将异常信息传递到 View 中?

这看起来很有希望:

http://devstuffs.wordpress.com/2010/12/12/how-to-use-customerrors-in-asp-net-mvc-2/

但是当我使用 View 时:

<%@ Page Title="" Language="C#" 
    MasterPageFile="~/Views/Shared/Bootstrap.Master"
    Inherits="System.Web.Mvc.ViewPage<System.Web.Mvc.HandleErrorInfo>" %>

错误页面本身会引发错误,因为 HandleErrorInfo 为 null。显然自定义错误中的一个错误导致 MVC2 一大堆问题,结果是蓝屏死机。

我想要么我错过了博客中的一些关键内容,要么它没有解释如何在不为我的每个 Controller /操作设置 Error 属性的情况下将 HandleErrorInfo 设置为 null 以外的任何内容。

此外,我知道 MVC3 可以更好地处理这个问题,而且我知道 Razor 非常好。它尚未用于此项目,也不会更改此项目以使用它。所以请不要回答“使用 MVC3”。

最佳答案

HandleErrorInfo 为空,因为您正在 customErrors 中执行重定向。

这是我在最新项目中尝试的想法,并针对 MVC 2 进行了更新。我没有使用 customErrors,因为我无法在不执行重定向的情况下调用 Controller 操作 (我猜)。

应用程序错误

protected void Application_Error(Object sender, EventArgs e)
{
    GlobalErrorHandler.HandleError(((HttpApplication)sender).Context, Server.GetLastError(), new ErrorController());
}

全局错误处理程序

public class GlobalErrorHandler
{
    public static void HandleError(HttpContext context, Exception ex, Controller controller)
    {
        LogException(ex);

        context.Response.StatusCode = GetStatusCode(ex);
        context.ClearError();
        context.Response.Clear();
        context.Response.TrySkipIisCustomErrors = true;

        if (IsAjaxRequest(context.Request))
        {
            ReturnErrorJson(context, ex);
            return;
        }

        ReturnErrorView(context, ex, controller);
    }

    public static void LogException(Exception ex)
    {
        // log the exception
    }

    private static void ReturnErrorView(HttpContext context, Exception ex, Controller controller)
    {
        var routeData = new RouteData();
        routeData.Values["controller"] = "Error";
        routeData.Values["action"] = GetActionName(GetStatusCode(ex));

        controller.ViewData.Model = new HandleErrorInfo(ex, " ", " ");
        ((IController)controller).Execute(new RequestContext(new HttpContextWrapper(context), routeData));
    }

    private static void ReturnErrorJson(HttpContext context, Exception ex)
    {
        var json = string.Format(@"success: false, error:""{0}""", ex.Message);
        context.Response.ContentType = "application/json";
        context.Response.Write("{" + json + "}");
    }

    private static int GetStatusCode(Exception ex)
    {
        return ex is HttpException ? ((HttpException)ex).GetHttpCode() : 500;
    }

    private static bool IsAjaxRequest(HttpRequest request)
    {
        return request.Headers["X-Requested-With"] != null && request.Headers["X-Requested-With"] == "XMLHttpRequest";
    }

    private static string GetActionName(int statusCode)
    {
        string actionName;

        switch (statusCode)
        {
            case 404:
                actionName = "NotFound";
                break;

            case 400:
                actionName = "InvalidRequest";
                break;

            case 401:
                actionName = "AccessDenied";
                break;

            default:
                actionName = "ServerError";
                break;
        }

        return actionName;
    }

    public static bool IsDebug
    {
        get
        {
            bool debug = false;

#if DEBUG
            debug = true;
#endif
            return debug;
        }
    }
}

错误 Controller

public class ErrorController : Controller
{
    public ActionResult AccessDenied()
    {
        return View("AccessDenied");
    }

    public ActionResult InvalidRequest()
    {
        return View("InvalidRequest");
    }

    public ActionResult NotFound()
    {
        return View("NotFound");
    }

    public ActionResult ServerError()
    {
        return View("ServerError");
    }
}

ServerError View

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<System.Web.Mvc.HandleErrorInfo>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    ServerError
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

    <h2>ServerError</h2>

    <% if (Model.Exception != null ) { %>
        <p>
          Controller: <%= Model.ControllerName %>
        </p>
        <p>
          Action: <%= Model.ActionName %>
        </p>
        <p>
          Message: <%= Model.Exception.Message%>
        </p>
        <p>
          Stack Trace: <%= Model.Exception.StackTrace%>
        </p>
    <% } %>

</asp:Content>

关于c# - 使用 MVC2 的 HandleErrorInfo - 模型为空?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11542309/

相关文章:

c# - 类型 'System.Web.HttpInputStream' 未标记为可序列化

ASP.NET Core session 超时

asp.net-mvc - ASP .Net MVC 中多个设备的多 View

asp.net - 迭代 ModelBindingContext.ValueProvider

c# - 这是什么属性(property)?有必要吗?

时间:2019-05-17 标签:c#asp.netidentityandcustomroles

c# - 直到文件完全下载后,使用HttpClient请求的音频流才会播放

asp.net - 如何解决错误189.dll和.dll中都存在 'XXX'类型

ASP.NET-使用 System.IO.File.Delete() 从 wwwroot 内的目录中删除文件?

c# - 使用列表时如何在 foreach 中使用 CheckBoxFor?