.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     }

在前端页面有一个登陆页面直接使用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.User.Name)</p>
 4         <p>
 5             <em>密码</em>@Html.PasswordFor(model=>model.User.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>

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

 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         }

ModelState.IsValid 永远是false。因为我们没有对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     }

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         }

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

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

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

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

时间: 2024-10-19 17:59:25

.net使用FluentValidation进行服务端验证。的相关文章

ASP.NET MVC如何实现自定义验证(服务端验证+客户端验证)

ASP.NET MVC通过Model验证帮助我们很容易的实现对数据的验证,在默认的情况下,基于ValidationAttribute的声明是验证被使用,我们只需 要将相应的ValidationAttribute应用到Model的类型或者属性上即可.对于自定义验证,我们也只需要定义相应的Validation 就可以了,不过服务端验证比较简单,而客户端验证就要稍微复杂一些,本文提供一个简单的实例说明在ASP.NET MVC中实现自定义验证的基本步骤.[源代码从这里下载] 一.AgeRangeAttr

MIME类型-服务端验证上传文件的类型

MIME的作用 : 使客户端软件,区分不同种类的数据,例如web浏览器就是通过MIME类型来判断文件是GIF图片,还是可打印的PostScript文件. web服务器使用MIME来说明发送数据的种类, web客户端使用MIME来说明希望接收到的数据种类. Tomcat的安装目录/conf/web.xml 中就定义了大量MIME类型 ,你可也去看一下. 最近在做用表单上传文件,想在服务端验证上传文件的类型,只允许上传GIF,JPG,ZIP, 我们有两种方法, 第一:检查文件的扩展名, 第二:检查文

JSR-303 Bean Validation 介绍及 Spring MVC 服务端验证最佳实践

任何时候,当要处理一个应用程序的业务逻辑,数据校验是你必须要考虑和面对的事情. 应用程序必须通过某种手段来确保输入参数在上下文来说是正确的. 分层的应用在很多时候,同样的数据验证逻辑会出现在不同的层,这样就会导致代码冗余和一些管理的问题. 为了避免这样或那样的情况发生,最好是将验证逻辑与相应的数据模型进行绑定. 1. JSR-303 Bean Validation JSR 是Java Specification Requests 的缩写,是指向 JCP(Java Community Proces

项目中客户端,服务端验证,数据库联合唯一约束,事务管理。

项目中有个需求,发布一个活动,记录下参加该活动的id和参与人id,同时调用接口,往收藏夹中添加一条记录,往交易表中添加一条记录.最后根据返回的结果,给出不同的提示信息. 1.如果当前的在jsp页面上面做处理,判断是否参与过.参加过之后,参加按钮不可点.没有参加的情况,参加按钮可以点. 2.jsp客户端加上js处理,参加按钮点击完之后,按钮不可点. 3.在controller中,业务逻辑开始前,再次java判断是否参加过该活动. 4.在数据库中参与表(活动id,参与人id)加上联合唯一约束.根据异

model验证——remote服务端验证

项目中做的项目使用的mvc的model验证,感觉最难的一个是remote验证,其它的比较简单就不说了: remote验证例子: /// <summary> /// ErrorMessage 表示验证不通过时显示的消息 ///AdditionalFields 表示验证的时候用哪个字段作为参数来传递(通常用于编辑页面的时候验证) /// </summary> [Remote("actionName", "controllerName", Erro

Verify an App Store Transaction Receipt 【苹果服务端 验证一个应用程序商店交易收据有效性】

转自:http://blog.csdn.net/saindy5828/article/details/6414014 1. 从Transaction 的TransactionReceipt属性中得到接收的数据,并以base64编码: 2.创建JSON对象,字典格式,单键值对,键名为“receiptdata”,值为上一次编码的数据,效果: {"receipt-data":"base64编码之后的数据"} 3.发送HTTP POST请求,将数据发送到App Store 

springmvc-3.2-jsr303解决服务端验证问题

从以前的验证:Stringutils.isEmpty....到struts的验证:xxxvalidate 现在使用jsr303使之更加简单  依赖hibernate-validator-4.xx.jar 实体类中的变化 @Entity @Cache(usage=CacheConcurrencyStrategy.READ_WRITE) public class Admin { @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private

google支付服务端订单验证PHP代码

之前有转发一则关于google支付服务端验证的文章,今天把之前研究出得服务端订单支付验证代码(PHP版本)贴出来大家分享 在进行服务端交易验证之前,需要到google api consle后台https://console.developers.google.com开通google play developer api并获取请求api证书priket.p12文件: 交易状态API官方文档:https://developers.google.com/android-publisher/api-re

Token:服务端身份验证的流行方案

01- 身份认证 服务端提供资源给客户端,但是某些资源是有条件的.所以服务端要能够识别请求者的身份,然后再判断所请求的资源是否可以给请求者. token是一种身份验证的机制,初始时用户提交账号数据给服务端,服务端采用一定的策略生成一个字符串(token),token字符串中包含了少量的用户信息,并且有一定的期限.服务端会把token字符串传给客户端,客户端保存token字符串,并在接下来的请求中带上这个字符串. 它的工作流程大概是这样: 组件图 Token机制 在这样的流程下,我们需要考虑下面几