记录任何类型的异常

时间:2015-04-22 12:18:56

标签: c# asp.net-mvc entity-framework exception log4net

我正在使用C#,ASP.NET MVC Web Api,实体框架和.NET Framework 4.0进行开发。

我有这段代码来记录异常:

public void LogCompleteException(
    string controllerName,
    string actionName,
    Exception exception)
{
    string exceptionMessage = string.Empty;

    Exception e = exception;
    if (e.InnerException == null)
        e = null;
    else
        while (e.InnerException != null) e = e.InnerException;

    if (e == null)
        exceptionMessage = exception.Message;
    else
        exceptionMessage = string.Format("{0}\n\rInnerException: {1}", exception.Message, e.Message);

    _logger.ErrorFormat(
        LogTextFormatString,
        ExceptionText,
        controllerName,
        actionName,
        exceptionMessage);
}

但是在我的日志文件中我发现了这个:

  

一个或多个实体的验证失败。看到   'EntityValidationErrors'属性以获取更多详细信息。

当我写'See'EntityValidationErrors'属性以获取更多详细信息。',我只是展示了一个示例,其中我没有记录重要属性。

有很多例外;但是使用我的方法,我没有记录所有相关信息,因为可能存在我没有记录的'EntityValidationErrors'等属性。

当我通过异常来记录它时,我不知道它有什么属性,我不知道如何记录它拥有的每个属性。

您是否知道完全记录异常的方法?我的代码不会长期存在EntityValidationErrors属性或任何其他重要属性。

我正在使用log4net进行日志记录。

2 个答案:

答案 0 :(得分:3)

由于内部异常本身就是一个例外,也许您可​​以只递归并重用已有的方法:

if (e.InnerException != null)
{
    LogCompleteException(controllerName, actionName, e.InnerException);
}

但是,如果这确实有效,您仍将缺少EntityValidationErrors。

我最近使用的另一种方法是显式捕获并记录异常发生的位置:

try
{
    db.Add(something);
    db.SaveChanges();
}
catch (DbEntityValidationException ex)
{
    StringBuilder sb = new StringBuilder();

    // collect some extra info about the exception before logging
    foreach (var eve in ex.EntityValidationErrors)
    {
        sb.AppendLine(String.Format("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:", eve.Entry.Entity.GetType().Name, eve.Entry.State));
        foreach (var ve in eve.ValidationErrors)
        {
            sb.AppendLine(String.Format("Property: \"{0}\", Error: \"{1}\"", ve.PropertyName, ve.ErrorMessage));
        }
    }

    logger.Error("There was an error while trying to parse and save something!\n" + sb.ToString(), ex);
}

如果您想要Exception.Data字典条目,也可以添加它们:

foreach (DictionaryEntry entry in ex.Data)
{
    // you will want to use a StringBuilder instead of concatenating strings if you do this
    exceptionMessage = exceptionMessage + string.Format("Exception.Data[{0}]: {1}", entry.Key, entry.Value);
}

对于Custom异常类的属性,就像EntityValidationErrors一样,我只是陷阱并解析它们出现的位置。否则,您必须在每个异常类型上覆盖ToString()或使用一些反射hackery枚举所有属性,这些属性会使您不关心的属性显着混乱。

答案 1 :(得分:0)

您可以使用elmahlog4net appender。 Elmah日志捕获所有异常,并可以将它们记录到log4net实例。