【问题标题】:How do I display the stack trace in a error view?如何在错误视图中显示堆栈跟踪?
【发布时间】:2014-05-09 09:45:23
【问题描述】:

我有一个启用了 customErrors 的网站,它会将我引导至自制视图。但是如果出现服务器错误,我想在 SorryPage 视图上显示堆栈跟踪。为什么?因为这样用户可以复制粘贴错误并将其发送到我们公司的 IT 帮助台,这样我们就知道出了什么问题以及错误来自哪里。

我以前见过这个,但不知道该怎么做。非常感谢任何帮助!

控制器:

public ActionResult SorryPage()
    {
        return View("Error", new ErrorModel(ErrorMessages.SorryPage, "General", "Home", Labels.GoBackToPortal));
    }

查看:

@using ILVO.Web.Resources
@model ILVO.Web.Areas.General.Error._Error.ErrorModel
@{
ViewBag.Title = "Error pagina";
Layout = "~/Views/Layouts/_Layout.cshtml";
}

<h1>@Html.Label("Error", Labels.TitleErrorPage)</h1>
<br/>
<h2>@Model.ErrorMessage</h2>

<br/>
<div class="margin-bottom5px">
@Html.ActionLink(Model.Button, "Index", Model.ToController, new { Area = Model.ToArea }, new { @class = "button" })
</div>

型号:

public class ErrorModel
{
    public ErrorModel(string errorMessage, string toArea, string toController, string button)
    {
        ErrorMessage = errorMessage;
        ToArea = toArea;
        ToController = toController;
        Button = button;
    }

    public string ErrorMessage { get; set; }
    public string ToArea { get; set; }
    public string ToController { get; set; }
    public string Button { get; set; }
}

我的 cfg 文件:

<customErrors mode="RemoteOnly" xdt:Transform="Replace" defaultRedirect="~/General/Error/SorryPage">
  <error statusCode="500" redirect="~/General/Error/SorryPage"/>
  <error statusCode="404" redirect="~/General/Error/NotFound"/>
</customErrors>

【问题讨论】:

    标签: asp.net-mvc error-handling stack-trace


    【解决方案1】:

    最简单的方法是禁用自定义错误。您将获得经典的“黄屏死机”,其中包括异常消息和堆栈跟踪。它应该看起来很丑,这样你就不会向世界展示它。

    在 &lt;system.web&gt; 部分下的 web.config 中添加以下内容:

    <customErrors mode="Off" />
    

    您还可以在 web.Debug.config 中进行设置,以便仅将其部署到您的测试环境中。您将需要设置发布或构建服务器,并且您的测试环境获得调试配置。请注意插入转换的使用。

    <system.web>
      <customErrors mode="Off" xdt:Transform="Insert" />
    </system.web>
    

    【讨论】:

      【解决方案2】:

      您只需为您的错误创建 Db 并使用过滤器将它们添加到 Db 中。

      型号:

      public class ExceptionDetail
      {
          public int Id { get; set; }
          public string ExceptionMessage { get; set; }    
          public string ControllerName { get; set; }  
          public string ActionName { get; set; }  
          public string StackTrace { get; set; }  
          public DateTime Date { get; set; }  
      }
      

      与 Db 的连接:

      public class LoggerContext : DbContext
      {
          public LoggerContext() : base("DefaultConnection")
          {
          }
          public DbSet<ExceptionDetail> ExceptionDetails { get; set; }
      }
      

      控制器:

      public class HomeController : Controller
      {
          LoggerContext db = new LoggerContext();
      
          public ActionResult Index() // here we have our errors
          {
              return View(db.ExceptionDetails.ToList());
          }
          [ExceptionLogger]// our filter
          public ActionResult Test(int id)// just random action
          {
              if (id > 3)
              {
                  int[] mas = new int[2];
                  mas[6] = 4;
              }
              else if (id < 3)
              {
                  throw new Exception("id cann`t be < 3");
              }
              else
              {
                  throw new Exception("id must be a number");
              }
              return View();
          }
      }
      

      现在为 ExceptionLogger 编写代码(创建文件夹“Filters”并添加类“ExceptionLoggerAttribute”)

      public class ExceptionLoggerAttribute : FilterAttribute, IExceptionFilter
      {
          public void OnException(ExceptionContext filterContext)
          {
              ExceptionDetail exceptionDetail = new ExceptionDetail()
              {
                  ExceptionMessage = filterContext.Exception.Message,
                  StackTrace = filterContext.Exception.StackTrace,
                  ControllerName = filterContext.RouteData.Values["controller"].ToString(),
                  ActionName = filterContext.RouteData.Values["action"].ToString(),
                  Date = DateTime.Now
              };
      
              using (LoggerContext db = new LoggerContext())
              {
                  db.ExceptionDetails.Add(exceptionDetail);
                  db.SaveChanges();
              }
      
              filterContext.ExceptionHandled = true;
          }
      }
      

      查看:

      您可以通过右键单击“索引”并选择模板=列表来创建视图, model = ExceptionDetail,所有代码都会自动生成。

      【讨论】:

        【解决方案3】:

        “因为这样用户可以复制粘贴错误并将其发送到我们公司的 IT 帮助台,这样我们就知道出了什么问题以及错误来自哪里”。

        黑客可以使用该信息。为什么不自己记录信息或通过电子邮件发送?

        您也可以使用我的(免费)服务,为您处理一切:https://coderr.io

        【讨论】:

        • 是的,但它是一个 Intranet 网站,因此只有登录该域的员工才能看到该网站。我认为在这种情况下风险非常低。
        • 您显然不必处理 PCI 合规性问题。尽管如此,仅仅因为它是一个 Intranet 站点,就不能作为对安全性松懈的借口。在这种特殊情况下,也许这不是一个巨大的交易,但它是一个滑坡。如果您允许自己对安全性偷懒,您就会在某个会重要的地方搞砸。
        猜你喜欢
        • 2017-07-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-12
        • 2018-09-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多