web-dev-qa-db-ja.com

System.Data.Entity.Validation.DbEntityValidationExceptionを処理する方法は?

私のアプリは次のエラーを受け取ります:

タイプ 'System.Data.Entity.Validation.DbEntityValidationException'の例外がEntityFramework.dllで発生しましたが、ユーザーコードでは処理されませんでした

追加情報:1つ以上のエンティティの検証に失敗しました。詳細については、「EntityValidationErrors」プロパティを参照してください。

新しいユーザーを登録しようとすると、このエラーが発生します。 「db.SaveChanges()」でエラーが発生します

コードは次のとおりです。

public ActionResult Registration(x.Models.User user)
        {
            if(ModelState.IsValid)
            {
                using(var db = new xDBEntities1())
                {
                    var crypto = new SimpleCrypto.PBKDF2();
                    var encrpPass = crypto.Compute(user.password);
                    var sysUser = db.users.Create();

                    sysUser.email = user.email;
                    sysUser.username = user.username;
                    sysUser.password = encrpPass;
                    sysUser.premium_credits = 0;
                    sysUser.login_times = 0;
                    sysUser.last_ip = Request.ServerVariables["REMOTE_ADDR"];
                    sysUser.creation_ip = Request.ServerVariables["REMOTE_ADDR"];
                    sysUser.banned = 0;
                    sysUser.creation_date = DateTime.Now;
                    sysUser.creation_time = DateTime.Now.TimeOfDay;

                    db.users.Add(sysUser);
                    db.SaveChanges();
                }
            }
            return RedirectToAction("Index", "Home");
        }

編集:ユーザーモデルクラス

public class User
    {
        [Required]
        [StringLength(50)]
        [Display(Name="Username: ")]
        public String username { get; set; }
        [Required]
        [DataType(DataType.Password)]
        [StringLength(50,MinimumLength=6)]
        [Display(Name="Password: ")]
        public string password { get; set; }
        [Required]
        [EmailAddress]
        [StringLength(50)]
        public string email { get; set; }
        public int phonenumber { get; set; }
        public int mobilephonenumber { get; set; }

    }
}

どのように処理できますか?

14
user2545576

何らかの種類のデータベース検証が行われ、データを書き込むことができません。

解決策はすでにこのページに記載されています。

1つ以上のエンティティの検証に失敗しました。詳細については、「EntityValidationErrors」プロパティを参照してください

.net mvcを使用する際の注意点として、Console.Writeline()の代わりにSystem.Diagnostics.Debug.WriteLine()を使用する必要があります。これにより、デバッグ時にデバッグ出力ウィンドウに書き込みが行われます。 mvcプロジェクトの実行時にコンソールに書き込むことができないため。

15
Sebastian

このエラーを解決するには、DatabaseContextオブジェクトのSaveChanges()メソッドをtryブロックにラップし、Catchループで各エラーをループして、エラーの場所を見つけます。コードは以下になります。

        try
        {
            db.SaveChanges();
        }
        catch (DbEntityValidationException ex)
        {
            foreach (var entityValidationErrors in ex.EntityValidationErrors)
            {
                foreach (var validationError in entityValidationErrors.ValidationErrors)
                {
                    Response.Write("Property: " + validationError.PropertyName + " Error: " + validationError.ErrorMessage);
                }
            }
        }

エラーが見つかったら、それを修正するために作業できます。それが役に立てば幸い。ありがとう

27
RAVI VAGHELA

SaveChangesをオーバーライドして、この例外を処理し、より詳細な例外の詳細を提供できます。

コンテキストクラスの「次」にクラスを作成できます。そのクラスの完全なコードは次のとおりです。

using System.Data.Entity;
using System.Data.Entity.Validation;
using System.Linq;

namespace MyNamespace
    {
        public partial class MyContext : DbContext
        {
            // Override base SaveChanges to expand out validation errors so client gets an actually helpful message
            public override int SaveChanges()
            {
                try
                {
                    return base.SaveChanges();
                }
                catch (DbEntityValidationException ex)
                {
                    // Retrieve the error messages as a list of strings.
                    var errorMessages = ex.EntityValidationErrors
                    .SelectMany(x => x.ValidationErrors)
                    .Select(x => x.ErrorMessage);

                    // Join the list to a single string.
                    var fullErrorMessage = string.Join("; ", errorMessages);

                    // Combine the original exception message with the new one.
                    var exceptionMessage = string.Concat(ex.Message, " The validation errors are: ", fullErrorMessage);

                    // Throw a new DbEntityValidationException with the improved exception message.
                    throw new DbEntityValidationException(exceptionMessage, ex.EntityValidationErrors);
                }
            }
        }
    }

詳細については、これを確認してください: http://devillers.nl/blog/improving-dbentityvalidationexception/

5
Romias

すでに受け入れられた答えがありますが、私の経験はおそらく将来誰かを助けることができるでしょう。クイックテストでは、Configuration.csファイルでデータベースに入力しているデータを確認し、モデルで検証条件を確認できます。たとえば、私の場合、次の検証条件をモデルに入れます。

[Range(1, 100),DataType(DataType.Currency)]
public decimal Price { get; set; }

次に、Configuration.cs内で、価格を次のように割り当てます。

new Photo{
    Title = "Photo 2",
    DateTaken = DateTime.Parse("2013-6-15"),
    Genre = "Nature",
    CameraModel = "Canon",
    Price = 200
}

これにより、EntityFrameworkExceptionsが作成され、データベースがシードされなくなりました。

3
user3941146

データを保存しようとしているデータベースフィールドのサイズを確認します。フィールドをvarchar(50)からvarchar(max)に変更すると、うまくいきました。

Entity Frameworkを使用している場合は、変更を加えたテーブルを削除して追加する必要がある場合があります。

1
stink

DBおよびモデルのパスワードの長さは、encrpPassの長さ以上でなければなりません。

1
Source007