2

我正在使用實體框架,我想驗證我的模型。實體框架驗證無例外

示例服務:

var user = _userRepository.GetUser(...); 
var order = user.MakeOrder();    //<- this is some business logic in Rich Domain Model 
_userRepository.Update(user); 
_orderRepository.Add(order); 

數據庫操作可以拋出DbEntityValidationException。我能趕上它,並做了一些工作呈現錯誤用戶:

try 
{ 
    _userRepository.Update(user); 
    _orderRepository.Add(order); 
} 
catch(DbEntityValidationException ex) 
{ 
    var error = ex.EntityValidationErrors(); 
    //Pass errors to Controller 
} 

但我知道,那異常緩慢。有沒有辦法做到沒有例外的相同的東西(例如某種返回值)以獲得更好的性能?

+0

做你的HTML文件'cshtml'? – Lucas

+0

@ I'bBlueDaBaDee,是 –

+1

那麼,你想避免例外,所以如果你的錯誤說,缺少必填字段,然後確保這些被捕獲客戶端。 –

回答

0

您可以使用DbContext.SaveChanges內部使用的相同方法。它是公開的 - DbContext.GetValidationErrors

驗證跟蹤的實體並返回包含驗證結果的DbEntityValidationResult集合。

當然,你應該以某種方式暴露你的存儲庫。

P.S.但是請注意,實際上這可能會導致更糟的性能,因爲SaveChanges會再次這樣做(並且注意,這種方法包括DetectChanges調用,如備註中所述),因此,由於驗證錯誤應該是例外,所以最好處理它們作爲例外情況,即它在你的原始代碼中。

-1

我會建議在嘗試保存到數據庫之前使用構建模型驗證。

本示例來自asp.net mvc模板中的構建登錄功能。

public class LoginViewModel 
{ 
    [Required] 
    [Display(Name = "Email")] 
    [EmailAddress] 
    public string Email { get; set; } 

    [Required] 
    [DataType(DataType.Password)] 
    [Display(Name = "Password")] 
    public string Password { get; set; } 

    [Display(Name = "Remember me?")] 
    public bool RememberMe { get; set; } 
} 

然後在控制器:

[HttpPost] 
    [AllowAnonymous] 
    [ValidateAntiForgeryToken] 
    public async Task<ActionResult> Login(LoginViewModel model, string returnUrl) 
    { 
     if (!ModelState.IsValid) 
     { 
      return View(model); 
     } 

     // This doesn't count login failures towards account lockout 
     // To enable password failures to trigger account lockout, change to shouldLockout: true 
     var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false); 
     switch (result) 
     { 
      case SignInStatus.Success: 
       return RedirectToLocal(returnUrl); 
      case SignInStatus.LockedOut: 
       return View("Lockout"); 
      case SignInStatus.RequiresVerification: 
       return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe }); 
      case SignInStatus.Failure: 
      default: 
       ModelState.AddModelError("", "Invalid login attempt."); 
       return View(model); 
     } 
    } 

並在視圖:

@using WebApplication1.Models 
@model LoginViewModel 
@{ 
    ViewBag.Title = "Log in"; 
} 

<h2>@ViewBag.Title.</h2> 
<div class="row"> 
    <div class="col-md-8"> 
     <section id="loginForm"> 
      @using (Html.BeginForm("Login", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { @class = "form-horizontal", role = "form" })) 
      { 
       @Html.AntiForgeryToken() 
       <h4>Use a local account to log in.</h4> 
       <hr /> 
       @Html.ValidationSummary(true, "", new { @class = "text-danger" }) 
       <div class="form-group"> 
        @Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" }) 
        <div class="col-md-10"> 
         @Html.TextBoxFor(m => m.Email, new { @class = "form-control" }) 
         @Html.ValidationMessageFor(m => m.Email, "", new { @class = "text-danger" }) 
        </div> 
       </div> 
       <div class="form-group"> 
        @Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" }) 
        <div class="col-md-10"> 
         @Html.PasswordFor(m => m.Password, new { @class = "form-control" }) 
         @Html.ValidationMessageFor(m => m.Password, "", new { @class = "text-danger" }) 
        </div> 
       </div> 
       <div class="form-group"> 
        <div class="col-md-offset-2 col-md-10"> 
         <div class="checkbox"> 
          @Html.CheckBoxFor(m => m.RememberMe) 
          @Html.LabelFor(m => m.RememberMe) 
         </div> 
        </div> 
       </div> 
       <div class="form-group"> 
        <div class="col-md-offset-2 col-md-10"> 
         <input type="submit" value="Log in" class="btn btn-default" /> 
        </div> 
       </div> 
       <p> 
        @Html.ActionLink("Register as a new user", "Register") 
       </p> 
       @* Enable this once you have account confirmation enabled for password reset functionality 
        <p> 
         @Html.ActionLink("Forgot your password?", "ForgotPassword") 
        </p>*@ 
      } 
     </section> 
    </div> 
    <div class="col-md-4"> 
     <section id="socialLoginForm"> 
      @Html.Partial("_ExternalLoginsListPartial", new ExternalLoginListViewModel { ReturnUrl = ViewBag.ReturnUrl }) 
     </section> 
    </div> 
</div> 

的HTML輔助方法,ValidationMessageFor將使用在顯示註釋文本,告知什麼是錯的。

+0

儘管此鏈接可能回答問題,但最好在此處包含答案的重要部分並提供供參考的鏈接。如果鏈接頁面更改,則僅鏈接答案可能會失效。 - [來自評論](/ review/low-quality-posts/13653732) – tarzanbappa

+0

我知道。我在上牀的路上打了電話。今天晚些時候我會在休息時間編輯答案。 –

2

1)你必須實現模型IValidatableObject接口,那麼在驗證方法

Your Model

2-)使用ModelState.IsValid屬性來定義的驗證規則。無需try catch塊

Your Api

3-)添加驗證消息塊頁面元素

ClientSideValitaion

詳情

http://weblogs.asp.net/scottgu/class-level-model-validation-with-ef-code-first-and-asp-net-mvc-3

附加

您可以使用流利的驗證 https://fluentvalidation.codeplex.com/wikipage?title=mvc

基本例如http://www.jerriepelser.com/blog/using-fluent-validation-with-asp-net-mvc-part-1-the-basics