在上一篇“asp.net mvc常用的数据注解和验证以及entity framework数据映射”话题中,有的博友提到

‘“同一个实体在3-4个地方会发生修改,每个修改需要验证的方式都不一样,后端就不能写固定验证。”

此博友的言论我是很赞同的,在基于asp.net mvc上,我有对应的策略,并且,你只需几行代码,就解决了所有的事情。

还是举上次的Model,如下:

[Table("AdminInfo")]
public partial class AdminInfo
{
[Key]
[Display(Name = "编号:")]
[Column("Id")]
public int Id { get; set; } [Required(ErrorMessage = "*不能为空!")]
[RegularExpression(@"^[\u4E00-\u9FA5\uf900-\ufa2d\w\.\s]{6,18}$", ErrorMessage = "*6-18位拼音或数字")]
[Column(TypeName = "nvarchar")]
[MaxLength()]
[Display(Name = "用户名:")]
///[Remote("CheckUserName","Account")]
public string UserName { get; set; } [Required(ErrorMessage = "*不能为空!")]
[RegularExpression(@"^[\u4E00-\u9FA5\uf900-\ufa2d\w\.\s]{6,18}$", ErrorMessage = "*6-18位拼音或数字")]
[Column(TypeName = "nvarchar")]
[MaxLength()]
[MinLength()]
[Display(Name = "密码:")]
[DataType(DataType.Password)]
public string PassWord { get; set; } [Column(TypeName = "nvarchar")]
[Display(Name = "真实姓名:")]
[MaxLength()]
public string TrueName { get; set; } [Display(Name = "是否可用:")]
public bool? IsUseFul { get; set; } [ReadOnly(true)]
[Display(Name = "创建时间:")]
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime CreatTime { get; set; } [Display(Name = "等级")]
public int? Orders { get; set; } [NotMapped]
[Required(ErrorMessage = "*不能为空!")]
[RegularExpression(@"^[\u4E00-\u9FA5\uf900-\ufa2d\w\.\s]{6,18}$", ErrorMessage = "*6-18位拼音或数字")]
[Display(Name = "新密码")]
[DataType(DataType.Password)]
public virtual string PassWord1 { get; set; } [NotMapped]
[Compare("PassWord1", ErrorMessage = "新密码和确认密码不一致!")]
[Required(ErrorMessage = "*不能为空!")]
[RegularExpression(@"^[\u4E00-\u9FA5\uf900-\ufa2d\w\.\s]{6,18}$", ErrorMessage = "*6-18位拼音或数字")]
[Display(Name = "确认密码")]
[DataType(DataType.Password)]
public virtual string PassWord2 { get; set; }
}

在基于这个Model上,我们做一些业务,比如:添加,页面如下:

@{
Layout = null;
}
@model SnsModels.AdminInfo <!DOCTYPE html> <html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
<link href="/css/demo.css" rel="stylesheet"/>
<script type="text/javascript" src="/Scripts/jquery-1.7.2.min.js"></script>
<script src="/Scripts/jquery.validate.min.js" type="text/javascript"></script>
<script src="/Scripts/jquery.validate.unobtrusive.min.js" type="text/javascript"></script>
<script src="/Scripts/jquery.unobtrusive-ajax.min.js" type="text/javascript"></script>
</head>
<body>
<div class="web"> @using (Ajax.BeginForm("AddSubmit", "AdminInfo", new AjaxOptions { HttpMethod = "post" }))
{
<table class="table">
<tr>
<td colspan="" class="TableTitle">创建管理员</td>
</tr>
<tr>
<td>@Html.LabelFor(m => m.UserName)</td>
<td class="td2">@Html.TextBoxFor(m => m.UserName)</td>
</tr>
<tr>
<td>&nbsp;</td>
<td class="td2">@Html.ValidationMessageFor(m => m.UserName)</td>
</tr> <tr>
<td>@Html.LabelFor(m => m.PassWord)</td>
<td class="td2">@Html.PasswordFor(m => m.PassWord)</td>
</tr>
<tr>
<td>&nbsp;</td>
<td class="td2">@Html.ValidationMessageFor(m => m.PassWord)</td>
</tr> <tr>
<td>@Html.LabelFor(m => m.TrueName)</td>
<td class="td2">@Html.TextBoxFor(m => m.TrueName)</td>
</tr>
<tr>
<td>&nbsp;</td>
<td class="td2">@Html.ValidationMessageFor(m => m.TrueName)</td>
</tr> <tr>
<td>&nbsp;</td>
<td class="td2">
<input type="submit" value="提交" /></td>
</tr>
</table>
}
</div>
</body>
</html>

在这里,我只用到了3个字段,但是Model上有很多字段,并且还有需要验证的字段,我们上面的业务中是没有显示出来的。

那么我们在控制器中做一些改动,如下:

[HttpPost]
public ActionResult AddSubmit([Bind(Include = "UserName,PassWord,TrueName")] SnsModels.AdminInfo Model)
{
try
{
if (Request.IsAjaxRequest())
{
ModelState.Remove("PassWord1");
                    ModelState.Remove("PassWord2");
if (ModelState.IsValid)
{
if (Repository.Create<SnsModels.AdminInfo>(Model))
{
return JavaScript("alert('添加成功...');");
}
else
{
return JavaScript("alert('添加失败...');");
}
}
else
{
return JavaScript("alert('数据验证未通过...');");
}
}
else
{
return Content("<script>alert('请求不通过...');window.location='/AdminInfo/Add';</script>");
}
}
catch (Exception ex)
{
return JavaScript("alert('"+ex.Message.ToString()+"');");
}
}

ModelState.Remove("PassWord1");

ModelState.Remove("PassWord2");

上面2行,表示这字段,在本控制器中我们不需要验证。

然后我们体检Model到DAL层。如下:

/// <summary>
/// 创建一条记录
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="model"></param>
/// <returns></returns>
public int Create<T>(T model) where T : class
{
int Result = ;
using (SnsLearningLogManagerDB db = new SnsLearningLogManagerDB())
            {
                db.Configuration.ValidateOnSaveEnabled = false;
                db.Set<T>().Add(model);
                Result = db.SaveChanges();
                db.Configuration.ValidateOnSaveEnabled = true;
                return Result;
            }
}
db.Configuration.ValidateOnSaveEnabled = false;
db.Configuration.ValidateOnSaveEnabled = true;

这2个地方需要注意,如果没有,你插入的时候会一直显示操作异常。

在业务逻辑中我们已经验证过Model,在这里其实是不需要再进行验证的。

如果你一定要加上这个的话,我个人的解决方案是:
新建一个ViewModel针对此业务逻辑,然后数据验证通过之后把ViewModel传递给Model,这样就搞定了。 在控制器层有一段这样的代码 [Bind(Include = "UserName,PassWord,TrueName")]
这个是什么意思呢? 指定你的Model从View层接受到的属性,这个主要是防止攻击所用,因为别人可以仿造表单传递一些其他的参数进来,导致项目受损。
比如:我在伪造一个表单,包含orders字段,次字段如果表示管理员身份的话,而0表示高级管理员,那么我直接给orders赋值0,这样传递到控制器上还是能验证通过的,这将导致往数据库插入错误数据。
当然,我们有办法防止这些的,但是,加入[Bind(Include = "UserName,PassWord,TrueName")]如此简单,我们何乐不为呢! 本来也是菜鸟级别,如言论和代码有什么错误之处,还望大牛们指点。 自上次博客附带QQ群招人信息,不少博友都申请加入,小弟不慎感激。
以下为QQ群广告:
本群提供ASP.NET MVC,EF,LINQ,WEB API技术支持,不在乎人多,在乎人精。

ASP.NET MVC群 171560784  

诚邀各路高手、初学者加入。
 

ASP.NET MVC局部验证及相关问题的更多相关文章

  1. 【转】ASP.NET MVC 数据验证及相关内容

    原文地址:http://www.jb51.net/article/56713.htm 一.数据验证 数据验证的步骤在模型类中添加与验证相关的特性标记在客户端导入与验证相关的js文件和css文件使用与验 ...

  2. ASP.NET MVC Model验证(三)

    ASP.NET MVC Model验证(三) 前言 上篇中说到在MVC框架中默认的Model验证是在哪里验证的,还讲到DefaultModelBinder类型的内部执行的示意图,让大家可以看到默认的M ...

  3. ASP.NET MVC Model验证(二)

    ASP.NET MVC Model验证(二) 前言 上篇内容演示了一个简单的Model验证示例,然后在文中提及到Model验证在MVC框架中默认所处的位置在哪?本篇就是来解决这个问题的,并且会描述一下 ...

  4. ASP.NET MVC 5 - 验证编辑方法(Edit method)和编辑视图(Edit view)

    在本节中,您将验证电影控制器生成的编辑方法(Edit action methods)和视图.但是首先将修改点代码,使得发布日期属性(ReleaseDate)看上去更好.打开Models \ Movie ...

  5. [渣译文] 使用 MVC 5 的 EF6 Code First 入门 系列:为ASP.NET MVC应用程序更新相关数据

    这是微软官方教程Getting Started with Entity Framework 6 Code First using MVC 5 系列的翻译,这里是第八篇:为ASP.NET MVC应用程序 ...

  6. ASP.NET MVC 2 验证

    来源:http://www.cnblogs.com/jhxk/articles/2612885.html  只为把自己觉的好的存起来 对用户输入的验证以及强制业务规则/逻辑是大多数web应用的核心需求 ...

  7. ASP.NET MVC应用程序更新相关数据

    为ASP.NET MVC应用程序更新相关数据 这是微软官方教程Getting Started with Entity Framework 6 Code First using MVC 5 系列的翻译, ...

  8. ASP.NET MVC异步验证是如何工作的02,异步验证表单元素的创建

    在上一篇"ASP.NET MVC异步验证是如何工作的01,jQuery的验证方式.错误信息提示.validate方法的背后"中,了解了jQuery如何验证,如何显示错误信息,本篇要 ...

  9. ASP.NET MVC Model验证(五)

    ASP.NET MVC Model验证(五) 前言 上篇主要讲解ModelValidatorProvider 和ModelValidator两种类型的自定义实现, 然而在MVC框架中还给我们提供了其它 ...

随机推荐

  1. ServiceStack.Redis.RedisNativeClient的方法“get_Db”没有实现

    Redis 4.0.0.0版本已经开始收费 Redis 4.0.5.0 已经完成收费 今日在更换Redis版本时 出现了ServiceStack.Redis.RedisNativeClient的方法“ ...

  2. 【Android 界面效果16】关于android四大组件的总结

    Android四大组件:Activity.Service.Broadcast receiver.Content provider 在Android中,一个应用程序可以使用其它应用程序的组件,这是And ...

  3. IIS与JIRA的反向代理配置

    JIRA配置修改 JIRA与IIS ARR的集成,除了上篇(Visual SVN IIS反向代理设置)中讲到的基本的ARR配置之外,还需要在JIRA安装目录的conf\server.xml文件中做一个 ...

  4. jquery plugins —— datatables ajax post更新数据

    通过下面语句,可以定义datatables插件通过ajax post方法从服务器段获取JSON格式的数据. 错误写法(这样写再执行ajax.reload()方法时,ID参数还是初始时,不会更新): v ...

  5. 实现MVC4多级Views目录

    建立自己MyViewEngine类让他继承RazorViewEngine,之后在构造函数里面写入设置视图位置格式代码如下: public class MyViewEngine : RazorViewE ...

  6. Nginx 反向代理,流量转发到固定内网 IP 方法

    主配置文件: user nginx; worker_processes ; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pi ...

  7. React Native视频播放(iOS)

    网站链接:http://www.ncloud.hk/%E6%8A%80%E6%9C%AF%E5%88%86%E4%BA%AB/learn-react-native-video/ React Nativ ...

  8. hdu-5680 zxa and set(水题)

    题目链接: zxa and set Time Limit: 2000/1000 MS (Java/Others)     Memory Limit: 65536/65536 K (Java/Other ...

  9. 转: 跨终端Web之Hybrid App

    转:  http://www.infoq.com/cn/articles/hybrid-app 编者按:InfoQ开设新栏目“品味书香”,精选技术书籍的精彩章节,以及分享看完书留下的思考和收获,欢迎大 ...

  10. Linux 网卡设备驱动程序设计(3)

    三.网络子系统深度分析 用户程序通过网络发送这个网络数据包 通过 SCI 协议无关接口 协议栈 <   UDP的实现  会选择路由 <    IP的实现  会建立这个邻居子系统,建立邻居信 ...