zoukankan      html  css  js  c++  java
  • .net使用FluentValidation进行服务端验证。

          背景

          最近使用asp.mvc 做一个在线口语系统项目,在服务端验证问题遇到了一些小问题。

         自己根据数据库表user定义一个数据库表实体对象UserDbEntity

     1     [Table("User")]
     2     public class UserDbEntity : DbEntityModelBase
     3     {
     4         [Description("用户名")]
     5         [Required(ErrorMessage="*")]
     6         public string Name
     7         {
     8             get;
     9             set;
    10         }
    11         [Description("邮箱")]
    12         [Required]
    13         public string Email
    14         {
    15             get;
    16             set;
    17         }
    18         [Description("密码")]
    19         [Required(ErrorMessage="*")]
    20         public string Pwd
    21         {
    22             get;
    23             set;
    24         }
    25         [Description("确认密码,数据库不存在该字段")]
    26         [Required(ErrorMessage = "*")]
    27         public string SecondPwd
    28         {
    29             get;
    30             set;
    31         }
    32 
    33         [Description("真实姓名")]
    34         [Required]
    35         public string TrueName
    36         {
    37             get;
    38             set;
    39         }
    40 
    41         [Description("邮箱是否已激活,长度为1")]
    42         public int Actived
    43         {
    44             get;
    45             set;
    46         }
    47     }
    48 
    49     /// <summary>
    50     /// 所有DbEntityModel项目中的实体必须继承DbEntityModelBase或其子类,使用supperType模式控制共有子类的行为或者状态,此项目中的类根据数据库基本表或者视图保持基本一致
    51     /// </summary>
    52    public abstract class DbEntityModelBase
    53     {
    54         [Description("Guid标识")]
    55         public string GuidMark
    56         {
    57             get;
    58             set;
    59         }
    60         [Description("自增Id列")]
    61         public int Id
    62         {
    63             get;
    64             set;
    65         }
    66        [Description("排序,倒序")]
    67         public int Sort
    68         {
    69             get;
    70             set;
    71         }
    72     }
    View Code

      在前端页面有一个登陆页面直接使用UserDbEntity实体对象UserDbEntity

     1      <form id="login_form" style="padding: 10px 20px 10px 40px;" action="Login" method="post">
     2         <p>
     3             <em>用户名</em>@Html.EditorFor(model=>model.User.Name) @Html.ValidationMessageFor(model=>model.Name)</p>
     4         <p>
     5             <em>密码</em>@Html.PasswordFor(model=>model.Pwd) @Html.ValidationMessageFor(model=>model.User.Pwd)</p>
     6         <div style="padding: 5px; text-align: center;">
     7             <a href="#" onclick="$('#login_form').submit();return false" class="easyui-linkbutton" icon="icon-ok">登录</a>
     8              <a href="#" onclick="$('#login_form')[0].reset()" class="easyui-linkbutton"
     9                     icon="icon-cancel">重填</a>
    10         </div>
    11         </form>
    View Code

     在控制器中对输入进行验证

     1         [HttpPost]
     2         public ActionResult Login(UserDbEntity loginModel)
     3         {
     4             bool loginFlag = false;
     5             string name = loginModel.Name;
     6             string pwd = loginModel.Pwd; ;
     7             if(ModelState.IsValid){
     8                 return Login();
     9             }
    10             var user = new UserDbEntity();
    11 
    12             using (var scope = IocRegisterBLL.ContainerBLLComponent.BeginLifetimeScope())
    13             {
    14                 var userBLL = scope.Resolve<UserBLL>();
    15                 loginFlag = userBLL.AdminLogin(name, pwd, out user);
    16             }
    17 
    18             if (loginFlag)
    19             {
    20                 Session[C_LogOnSession] = user;
    21                 return Index();
    22             }
    23             else
    24             {
    25                 return Login();
    26             }
    27         }
    View Code

    ModelState.IsValid 永远是false。因为我们的表单对email输入,email是空,用mvc服务端验证机制验证,永远不能通过。

      

        遇到问题,我们就要思考。现在我有两种思路解决问题。

     第1种方法是。 为每个页面制定一个ViewModel, 然后这个ViewModel在使用DataAnnotations ,最后使用mvc服务端的验证机制。 当然这个方法也是大项目使用最多的方法。 ViewModel 和UserDbEntity之间的转化时候AutoMapper 进行DTO。 但这个方法我不太喜欢,因为我觉得我这个项目属于中小项目,没必要每个页面制定一个ViewModel。 于是我找到了第2种方法。

    第2种方法。使用FluentValidation验证。使用FluentValidation 为login页面 对 UserDbEntity 写一个验证类。

    使用FluentValidation 解决背景介绍中遇到的问题

    1 引用: FluentValidation.dll  ,可以直接 Nuget ,Install-Package FluentValidation。

    2. 编写UserLoginValidator类

    1    public class UserLoginValidator: AbstractValidator<UserDbEntity>
    2     {
    3         public UserLoginValidator()
    4         {
    5             RuleFor(u=>u.Name).NotNull().WithMessage("用户名不能为空");
    6             RuleFor(u => u.Pwd).NotNull().WithMessage("密码不能为空");
    7         }
    8     }
    View Code

    3、在login controller使用 UserLoginValidator类进行验证。

     1      [HttpPost]
     2         public ActionResult Login(UserDbEntity loginModel)
     3         {
     4             bool loginFlag = false;
     5             string name = loginModel.Name;
     6             string pwd = loginModel.Pwd;
     7             UserLoginValidator validInstance = new UserLoginValidator();
     8             if(!validInstance.Validate(loginModel).IsValid){
     9                 return Login();
    10             }
    11             var user = new UserDbEntity();
    12 
    13             using (var scope = IocRegisterBLL.ContainerBLLComponent.BeginLifetimeScope())
    14             {
    15                 var userBLL = scope.Resolve<UserBLL>();
    16                 loginFlag = userBLL.AdminLogin(name, pwd, out user);
    17             }
    18 
    19             if (loginFlag)
    20             {
    21                 Session[C_LogOnSession] = user;
    22                 return Index();
    23             }
    24             else
    25             {
    26                 return Login();
    27             }
    28         }
    View Code

    这样就能解决我在背景中碰到的问题。 如果项目中其他页面也用到到UserDbEntity,但验证规则需要个性化,你也可以另外针对UserDbEntity写另外一个Validator类。

    这样就不必要对给个页面制定一个ViewModel了。

    推荐在项目中使用FluentValidation进行服务端验证

     FluentValidation 在个github上的地址 https://github.com/JeremySkinner/FluentValidation。FluentValidation的链式方法调用,写验证非常的流畅。可以为你在项目中写服务端验证逻辑节省不少时间。



  • 相关阅读:
    Bridge Design Pattern
    终于写了个自己的简单MVC框架!
    c 第1章的习题 列表 ! :)
    如何创建 linux 下的计划任务运行 php 文件?
    c 的开篇(自学 c 语言)
    一连串问题,都和.net framework有关
    信号与信号量的区别[转]
    永久设置SecureCRT的背景色和文字颜色方案[转]
    do...while(0)的妙用 【转】
    给Ubuntu软件升级命令 [转]
  • 原文地址:https://www.cnblogs.com/huangkaiyan10/p/4640685.html
Copyright © 2011-2022 走看看