10

私は MVC4 と EF5.x を使用してアプリケーションを作成しており、レビューのために例外を記録するために ELMAH を使用しています。最近アプリケーションをリリースしましたが、予想どおり、ELMAH ログが数十個の例外でいっぱいになりました。素晴らしい(そしてそうではない)!問題は、それらの例外の 1 つが

System.Data.Entity.Validation.DbEntityValidationException
Validation failed for one or more entities. 
See 'EntityValidationErrors' property for more details.

もちろん、詳細について EntityValidationErrors プロパティを確認する方法はなく、スタック トレースは私の SubmitChanges() までラップされます。

ELMAH には、独自の例外を発生させ、何をどのようにログに記録するかを何らかの方法でカスタマイズできる機能があることを知っています。残念ながら、私はまだ ELMAH と MVC に非常に慣れていないため、Google 検索では関連するものは何も見つかりませんでした。EntityValidationErrors のログ記録に関するブログ記事を見つけました。著者は、その方法を ELMAH に投稿すると具体的に述べていましたが、それは 2012 年 9 月に投稿されたもので、それ以来何も見ていません。

どんな助けでも大歓迎です!

4

5 に答える 5

5

以上を踏まえた上で、この拡張方法はいかがでしょうか。

public static void SaveChangesWithBetterValidityException(this DbContext context)
    {
        try
        {
            context.SaveChanges();
        }
        catch (DbEntityValidationException ve)
        {
            var errors = new List<string>();
            foreach (var e in ve.EntityValidationErrors)
            {
                errors.AddRange(e.ValidationErrors.Select(e2 => string.Join("Validation Error :: ", e2.PropertyName, " : ", e2.ErrorMessage)));
            }
            var error = string.Join("\r\n", errors);
            var betterException = new Exception(error, ve);

            throw betterException;
        }
    }

Elmah のログには、はるかに優れた例外が記録されます。

于 2015-06-24T10:25:36.767 に答える
1

以下のコードに従って再スローすることは完全ではありません (ただし、Elmah が投稿したアドレスのログに記録された詳細が例外の原因を示しているため、ここでコール スタックをリセットしてもかまいません)。独自のセキュリティへの影響がありますが、これはかなり簡潔であり、私のニーズを満たしています:

try
{
    return base.SaveChanges();
}
catch (DbEntityValidationException e)
{
    var de = new DetailedEntityValidationException(e);
    throw de;
}

public class DetailedEntityValidationException : Exception
{
    public DetailedEntityValidationException(DbEntityValidationException ve)
        : base(ve.Message + ":\r\n\t-" + string.Join(new string('-',20) + "\r\n\t-", ve.EntityValidationErrors.Select(ev=>string.Join("\r\n\t-",ev.ValidationErrors.Select(e=>e.ErrorMessage)))))
    {}
}
于 2016-09-13T01:45:36.230 に答える
0

Elmah および EF Validation エラーのグローバル Web API ソリューションの実装を次に示します。

public class ElmahHandleWebApiErrorAttribute : ExceptionFilterAttribute
{
   public override void OnException(HttpActionExecutedContext context)
   {
       var e = context.Exception;
       // Try parse as entity error (i'm not sure of performance implications here)
       var efValidationError = e as DbEntityValidationException;
      if (efValidationError == null)
       {
           RaiseErrorSignal(e);
       }
       else
       {
           RaiseEntityFrameWorkValidationErrorSignal(efValidationError);
       }
  }

   private static bool RaiseErrorSignal(Exception e)
   {
       var context = HttpContext.Current;
      if (context == null)
           return false;
       var signal = ErrorSignal.FromContext(context);
       if (signal == null)
           return false;
       signal.Raise(e, context);
       return true;
   }

   private static bool RaiseEntityFrameWorkValidationErrorSignal(DbEntityValidationException e)
   {
       var context = HttpContext.Current;
       if (context == null)
           return false;
       var signal = ErrorSignal.FromContext(context);
       if (signal == null)
           return false;

      //Taken from post above
      var errors = new List<string>();
       foreach (var entityError in e.EntityValidationErrors)
       {
           errors.AddRange(entityError.ValidationErrors.Select(e2 => string.Join("Validation Error :: ", e2.PropertyName, " : ", e2.ErrorMessage)));
        }
       var error = string.Join("\r\n", errors);
       var betterException = new Exception(error, e);

       signal.Raise(betterException, context);        
       return true;
   }
}

WebApiConfig.cs次に、下のファイルに属性を登録しますApp_Start

config.Filters.Add(new ElmahHandleWebApiErrorAttribute());
于 2016-03-14T19:34:01.233 に答える