C# 实体框架中的无例外验证
我正在使用实体框架,我想验证我的模型 示例服务:C# 实体框架中的无例外验证,c#,asp.net,entity-framework,validation,domain-driven-design,C#,Asp.net,Entity Framework,Validation,Domain Driven Design,我正在使用实体框架,我想验证我的模型 示例服务: var user = _userRepository.GetUser(...); var order = user.MakeOrder(); //<- this is some business logic in Rich Domain Model _userRepository.Update(user); _orderRepository.Add(order); 但我知道,异常是缓慢的。是否有任何方法可以毫无例外
var user = _userRepository.GetUser(...);
var order = user.MakeOrder(); //<- this is some business logic in Rich Domain Model
_userRepository.Update(user);
_orderRepository.Add(order);
但我知道,异常是缓慢的。是否有任何方法可以毫无例外地执行相同的操作(例如某些类型的返回值)以获得更好的性能?您可以使用与
DbContext.SaveChanges内部使用的方法相同的方法。这是公开的-:
验证跟踪的实体并返回包含验证结果的DbEntityValidationResult集合
当然,您应该通过存储库以某种方式公开它
p.S.但请注意,事实上这可能会导致性能下降,因为SaveChanges
将再次执行此操作(请注意,此方法包括注释中提到的DetectChanges
调用),因此,既然验证错误应该是一种例外情况,可能最好将其作为例外情况处理,如原始代码所示。我建议在尝试保存到数据库之前使用内置模型验证
此示例来自内置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);
}
}
[HttpPost]
[异名]
[ValidateAntiForgeryToken]
公共异步任务登录(LoginView模型,字符串返回URL)
{
如果(!ModelState.IsValid)
{
返回视图(模型);
}
//这不会将登录失败计入帐户锁定
//要使密码失败触发帐户锁定,请更改为shouldLockout:true
var result=wait SignInManager.PasswordSignInAsync(model.Email、model.Password、model.RememberMe、shouldllockout:false);
开关(结果)
{
案例标志状态成功:
返回重定向到本地(returnUrl);
案例标志状态锁定输出:
返回视图(“锁定”);
案例标志状态。要求验证:
return RedirectToAction(“SendCode”,new{ReturnUrl=ReturnUrl,RememberMe=model.RememberMe});
案例信号状态故障:
违约:
AddModelError(“,”登录尝试无效“);
返回视图(模型);
}
}
并且认为:
@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>
@使用WebApplication1.Models
@模型LoginView模型
@{
ViewBag.Title=“登录”;
}
@ViewBag.Title。
@使用(Html.BeginForm(“Login”,“Account”,new{ReturnUrl=ViewBag.ReturnUrl},FormMethod.Post,new{@class=“form horizontal”,role=“form”}))
{
@Html.AntiForgeryToken()
使用本地帐户登录。
@Html.ValidationSummary(true,“,new{@class=“text danger”})
@LabelFor(m=>m.Email,新的{@class=“col-md-2控制标签”})
@TextBoxFor(m=>m.Email,新的{@class=“form control”})
@Html.ValidationMessageFor(m=>m.Email,“,new{@class=“text danger”})
@LabelFor(m=>m.Password,新的{@class=“col-md-2控制标签”})
@Html.PasswordFor(m=>m.Password,新的{@class=“form control”})
@Html.ValidationMessageFor(m=>m.Password,“,new{@class=“text danger”})
@CheckBoxFor(m=>m.RememberMe)
@LabelFor(m=>m.RememberMe)
@ActionLink(“注册为新用户”、“注册”)
@*为密码重置功能启用帐户确认后启用此选项
@ActionLink(“忘记密码?”,“放弃密码”)
*@
}
@Html.Partial(“_externalLoginListPartial”,新的ExternalLoginListViewModel{ReturnUrl=ViewBag.ReturnUrl})
Html助手方法ValidationMessageFor将使用显示注释中的文本来通知问题所在。1)您必须实现模型IValidatableObject接口,然后在Validate方法中定义验证规则
2-)使用ModelState.IsValid属性。不需要试一下挡块
3-)为页面元素添加验证消息块
欲知详情
附加的
您可以使用fluent验证
基本示例如果希望避免页面的往返,请尝试向模型添加验证,并尝试添加客户端验证。使用JQuery验证进行客户端验证以获得更好的性能
有关客户端验证的更多详细信息。请尝试浏览以下链接:
您的html文件是否为cshtml
?@I'mBlueDaBaDee,yesWell,您希望避免出现异常,因此如果您在例如缺少必填字段方面遇到错误,请确保这些错误被客户端捕获。您是否有任何理由不使用内置模型验证?请记住接受回答,而此链接可能会回答问题,最好在这里包括答案的基本部分,并提供链接供参考。如果链接页面发生更改,仅链接的答案可能无效。-我知道。我在睡觉的路上打电话。我将在今天晚些时候工作休息时编辑答案。
@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>