c# - 带有自定义错误消息的 MVC 错误处理

标签 c# asp.net-mvc error-handling exception

我正在使用 MVC5 构建一个新的 Web 应用程序,我需要以下内容:

  1. 捕捉错误
  2. 在文件中记录详细信息
  3. 通过电子邮件发送给他们
  4. 添加到详细自定义信息(例如 Id 记录我正在尝试阅读)
  5. 返回查看给用户的自定义消息

我找到了很多关于 HandleErrorAttribute 的信息 但是它们都不允许向错误添加特定的细节,我还发现了一些信息说 try catch 方法对于服务器来说太重

目前,我有:

Controller :

public partial class HomeController : Controller
{
    private static Logger logger = LogManager.GetCurrentClassLogger();

    public virtual ActionResult Index()
    {
        try
        {
            return View();
        }
        catch (Exception e)
        {
            logger.Error("Error in Index: " + e);
            return MVC.Error.Index("Error in Home Controller");
        }
    }
}

我发现这个扩展的 HandleErrorAttribute 看起来很完整,但没有做我需要的一切:

private bool IsAjax(ExceptionContext filterContext)
{
    return filterContext.HttpContext.Request.Headers["X-Requested-With"] == "XMLHttpRequest";
}

public override void OnException(ExceptionContext filterContext)
{
    if (filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled)
    {
        return;
    }


    // if the request is AJAX return JSON else view.
    if (IsAjax(filterContext))
    {
        //Because its a exception raised after ajax invocation
        //Lets return Json
        filterContext.Result = new JsonResult(){Data=filterContext.Exception.Message,
            JsonRequestBehavior=JsonRequestBehavior.AllowGet};

        filterContext.ExceptionHandled = true;
        filterContext.HttpContext.Response.Clear();    
    }
    else
    {
        //Normal Exception
        //So let it handle by its default ways.
        base.OnException(filterContext);

    }

    // Write error logging code here if you wish.

    //if want to get different of the request
    //var currentController = (string)filterContext.RouteData.Values["controller"];
    //var currentActionName = (string)filterContext.RouteData.Values["action"];
}

最佳答案

Elmah 最符合您的要求。非常好的记录错误的插件。

ELMAH 代表错误记录模块和处理程序

ELMAH 提供了如此高度的可插入性,以至于即使安装 ELMAH 也不需要编译您的应用程序。

ELMAH (Error Logging Modules and Handlers) is an application-wide error logging facility that is completely pluggable. It can be dynamically added to a running ASP.NET web application, or even all ASP.NET web applications on a machine, without any need for re-compilation or re-deployment.

引用自SCOTT HANSELMAN的博客

只需将 ELMAH 的二进制文件复制到应用程序的 bin 文件夹并编辑 web.config 文件。就是这样!

您需要将以下内容添加到您的 web.config 并进行以下链接中描述的一些其他更改。

<sectionGroup name="elmah">
  <section name="security" requirePermission="false" type="Elmah.SecuritySectionHandler, Elmah" />
  <section name="errorLog" requirePermission="false" type="Elmah.ErrorLogSectionHandler, Elmah" />
  <section name="errorMail" requirePermission="false" type="Elmah.ErrorMailSectionHandler, Elmah" />
  <section name="errorFilter" requirePermission="false" type="Elmah.ErrorFilterSectionHandler, Elmah" />
</sectionGroup>

例如设置邮件帐户

<configuration>
    <configSections>
        <sectionGroup name="elmah">
            <section name="errorLog" requirePermission="false" type="Elmah.ErrorLogSectionHandler, Elmah"/>
            <section name="errorMail" requirePermission="false" type="Elmah.ErrorMailSectionHandler, Elmah"/>
            <section name="errorFilter" requirePermission="false" type="Elmah.ErrorFilterSectionHandler, Elmah"/>
        </sectionGroup>
    </configSections>
    <elmah>
    <errorMail from="test@test.com" to="test@test.com"
       subject="Application Exception" async="false"
       smtpPort="25" smtpServer="***"
       userName="***" password="***">
    </errorMail>
    </elmah>
<system.web>        
    <customErrors mode="RemoteOnly" defaultRedirect="CustomError.aspx">
        <error statusCode="403" redirect="NotAuthorized.aspx" />
        <!--<error statusCode="404" redirect="FileNotFound.htm" />-->
    </customErrors>
    <httpHandlers>
        <remove verb="*" path="*.asmx"/>
        <add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
        <add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
        <add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" validate="false"/>
        <add verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />
    </httpHandlers>
    <httpModules>
        <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
        <add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah"/>
        <add name="ErrorMail" type="Elmah.ErrorMailModule, Elmah" />
    </httpModules>
</system.web>
</configuration>

这里有一些很好的引用链接(其中包含有关将 ELMAH 安装到您的项目的详细引用)供您引用。

https://msdn.microsoft.com/en-us/library/aa479332.aspx

https://code.google.com/p/elmah/wiki/MVC

更新

Add to the detail custom information (for example the Id of the record I'm trying to read)

您可以构建自己的派生自 Exception 的自定义异常。

public class MyException : Exception
{
    public MyException(string message, Exception ex) : base(ex.Message, ex)
    {

    }
}

然后像这样使用它

public virtual ActionResult Index()
{
    try
    {
        return View();
    }
    catch (Exception e)
    {
        throw new MyException("detailed exception", e);
    }
}

通过这种方式,主要异常将被包装在 myexception 中,您可以添加详细的自定义异常消息。

Return to the view custom messages to the user

你只需要添加

<system.web>
    <customErrors mode="On">
    </customErrors>
<sytem.web>

并在 ~/View/Shared 文件夹中添加 Error.cshtml 然后,每当遇到异常时,它都会在 view/shared 文件夹中查找 Error.cshtml 并呈现内容。这样您就可以在那里呈现您的自定义消息。

关于c# - 带有自定义错误消息的 MVC 错误处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28429272/

相关文章:

c# - 从 Azure 应用服务到 Azure VM 上托管的 API 的 API 调用 --错误 尝试以访问权限禁止的方式访问套接字

c# - JQuery:如何使用 live 和 post 函数

asp.net-mvc - MVC,不再使用 HttpContext.Current "supposed"了吗?

php - PHP重定向503而不更改URL

php - mysqli 准备语句错误 - 过程样式

c#:从域中获取 CNAME 和 MX 记录?

c# - 为 MVVM Light ICommand 正确使用 CanExecute

jquery - 如何在 asp.net mvc 4 中使用 jquery?

c# - 尝试在 ActionResult 中返回 HTML 会导致 HTTP 406 错误

java - 做while循环错误(switch语句)