背景

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

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

     [Table("User")]
public class UserDbEntity : DbEntityModelBase
{
[Description("用户名")]
[Required(ErrorMessage="*")]
public string Name
{
get;
set;
}
[Description("邮箱")]
[Required]
public string Email
{
get;
set;
}
[Description("密码")]
[Required(ErrorMessage="*")]
public string Pwd
{
get;
set;
}
[Description("确认密码,数据库不存在该字段")]
[Required(ErrorMessage = "*")]
public string SecondPwd
{
get;
set;
} [Description("真实姓名")]
[Required]
public string TrueName
{
get;
set;
} [Description("邮箱是否已激活,长度为1")]
public int Actived
{
get;
set;
}
} /// <summary>
/// 所有DbEntityModel项目中的实体必须继承DbEntityModelBase或其子类,使用supperType模式控制共有子类的行为或者状态,此项目中的类根据数据库基本表或者视图保持基本一致
/// </summary>
public abstract class DbEntityModelBase
{
[Description("Guid标识")]
public string GuidMark
{
get;
set;
}
[Description("自增Id列")]
public int Id
{
get;
set;
}
[Description("排序,倒序")]
public int Sort
{
get;
set;
}
}

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

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

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

         [HttpPost]
public ActionResult Login(UserDbEntity loginModel)
{
bool loginFlag = false;
string name = loginModel.Name;
string pwd = loginModel.Pwd; ;
if(ModelState.IsValid){
return Login();
}
var user = new UserDbEntity(); using (var scope = IocRegisterBLL.ContainerBLLComponent.BeginLifetimeScope())
{
var userBLL = scope.Resolve<UserBLL>();
loginFlag = userBLL.AdminLogin(name, pwd, out user);
} if (loginFlag)
{
Session[C_LogOnSession] = user;
return Index();
}
else
{
return Login();
}
}

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类

    public class UserLoginValidator: AbstractValidator<UserDbEntity>
{
public UserLoginValidator()
{
RuleFor(u=>u.Name).NotNull().WithMessage("用户名不能为空");
RuleFor(u => u.Pwd).NotNull().WithMessage("密码不能为空");
}
}

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

      [HttpPost]
public ActionResult Login(UserDbEntity loginModel)
{
bool loginFlag = false;
string name = loginModel.Name;
string pwd = loginModel.Pwd;
UserLoginValidator validInstance = new UserLoginValidator();
if(!validInstance.Validate(loginModel).IsValid){
return Login();
}
var user = new UserDbEntity(); using (var scope = IocRegisterBLL.ContainerBLLComponent.BeginLifetimeScope())
{
var userBLL = scope.Resolve<UserBLL>();
loginFlag = userBLL.AdminLogin(name, pwd, out user);
} if (loginFlag)
{
Session[C_LogOnSession] = user;
return Index();
}
else
{
return Login();
}
}

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

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

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

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

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

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

    ASP.NET MVC通过Model验证帮助我们很容易的实现对数据的验证,在默认的情况下,基于ValidationAttribute的声明是验证被使用,我们只需 要将相应的ValidationAttr ...

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

    任何时候,当要处理一个应用程序的业务逻辑,数据校验是你必须要考虑和面对的事情. 应用程序必须通过某种手段来确保输入参数在上下文来说是正确的. 分层的应用在很多时候,同样的数据验证逻辑会出现在不同的层, ...

  3. C#在服务端验证客户端证书(Certificate)

    使用https协议进行通讯的时候可以设置双向证书认证,客户端验证服务端证书的方法前面已经介绍过了,现在说一下在服务端验证客户端证书的方案. 这里给出的方案比较简单,只需要在Service端的配置文件中 ...

  4. ASP.NET的服务端验证(干货)

    最近有项目需要使用.net的web,啥也不说,直接开始学习.net的mvc框架.感觉微软的web项目其实还是很好用的,今天和大家分享一下服务端验证的事情.其实原理就是用到了c#的特性,特性不用多说,大 ...

  5. Asp.net MVC 服务端验证多语言错误

    服务端验证用户提交信息时为了实现多语言使用了资源文件,如: using System.ComponentModel.DataAnnotations; public class UserModel { ...

  6. Easyui validatebox后台服务端验证

    Easyui validatebox的验证提示十分好用,可是在实际项目的运用中,经常会遇到需要服务器验证后并返回验证结果信息,比如验证用户名.手机号.邮箱是否已存在.于是就想着怎么拓展Easyui的验 ...

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

    MIME的作用 : 使客户端软件,区分不同种类的数据,例如web浏览器就是通过MIME类型来判断文件是GIF图片,还是可打印的PostScript文件. web服务器使用MIME来说明发送数据的种类, ...

  8. Angular4 后台管理系统搭建(9) - 用自定义angular指令,实现在服务端验证

    最近这段时间发现,北京这用angular4 或 angular2的公司很少.几乎是没有.很担心自己是不是把精力放到了不应该的地方.白耽误了时间.但是随着我对新版angular框架理解的加深.个人感觉a ...

  9. TCP之传输对象 客户端传输user对象到服务端 验证登录是否合法

    Server.java package com.sxt.tcp4; import java.io.IOException; import java.io.ObjectInputStream; impo ...

随机推荐

  1. scala 学习: case class

    case class: 1.定义为case class 的类在实例化时,可以不使用new 关键字. case class People(name:String, age:Int) val zhangs ...

  2. js 定时函数

    Document自带的方法: 循环执行:var timeid = window.setInterval(“方法名或方法”,“延时”);window.clearInterval(timeid); 定时执 ...

  3. ssh连接速度慢解决

    这些天,公司新安装的几台服务器,发现SSH本地连接上去,速度非常慢,慢的难以忍受,大概30秒左右. 后来到网上查了下,尝试了一种办法,效果还可以,特发上来给大家共享. [root@data208 ~] ...

  4. JQuery Mobile 页面参数传递(转)

    在单页模版中使用基于HTTP的方式通过POST和GET请求传递参数,而在多页模版中不需要与服务器进行通信,通常在多页模版中有以下三种方法来实现页面间的参数传递. 1.GET方式:在前一个页面生成参数并 ...

  5. 解决Linux c语言运行时候“段错误 (核心已转储)”问题-采用gdb 解决

    编译没有警告,没有错误,运行就打印 段错误 (核心已转储) 网上找了一下,都是各种问题,都推荐用gdb 调试解决,咱也来趁机学习gdb一下.   gcc+gdb)输入命令行 运行 sudo apt-g ...

  6. 关于Android的布局

    Android中五大布局是直接继承ViewGroup的布局:RelativeLayout.GridLayout.FrameLayout.AbsoluteLayout.LinnerLayout(Tabl ...

  7. jquery 滚动到底部加载

    var body_ = $(window); var indexPage = 2; var pageCount = <?php echo $pageCount;?>; var _ajaxR ...

  8. WCF三种通信模式

    WCF在通信过程中有三种模式:请求与答复.单向.双工通信. 请求与答复模式 描述:客户端发送请求,然后一直等待服务端的响应(异步调用除外),期间处于假死状态,直到服务端有了答复后才能继续执行其他程序 ...

  9. Android编译环境搭建(0818-0819)

    1 在虚拟机VMware上安装64位Ubuntu14.04LTS 首先需要安装虚拟机并激活.然后新建虚拟机,选择使用下载好的Ubuntu镜像.注意需要将光驱改为自己下载的,而不是autoinst.is ...

  10. 使用JMeter进行负载测试——终极指南

    这篇教程讨论的是JMeter,它是一款基于Java的.集合了几个应用程序.具有特定用途的负载和性能测试工具. 本篇主要涉及的内容: 解释一下JMeter的用途 JMeter的实现方式以及采用的技术 安 ...