您的位置:首页 > Web前端 > JQuery

ASP.NET MVC验证 - jQuery异步验证

2014-11-21 16:51 288 查看
本文主要体验通过jQuery异步验证。

在很多的教材和案例中,MVC验证都是通过提交表单进行的。通过提交表单,可以很容易获得验证出错信息。因为,无论是客户端验证还是服务端验证,总能找到与Model属性或验证特性对应的html元素和属性,并把错误信息显示出来。可是,在实际项目中,经常会遇到需要异步提交的情况。那么,如何把服务端的验证错误信息传递给前端视图呢?

□思路

1、服务端的验证错误信息是可以收集起来的以json形式传递个视图的。
2、服务端把错误信息存放在一个字典集合Dictionary<string,object>,让key是属性名,value是错误信息。
3、前台视图中,显示错误信息的元素id,比方说是Err_Name,当遍历从服务端传来的字典集合时,取出key,然后把错误信息动态赋值给$('#Err_'+key)。

Viewmodel

usingSystem;

[code]usingSystem.ComponentModel.DataAnnotations;

namespaceDataAnnotationAjax.Models

{

publicclassStudent

{

publicintId{get;set;}


[Required(ErrorMessage="姓名为必填项")]

[Display(Name="姓名")]

publicstringName{get;set;}


[Required(ErrorMessage="分数是必选项")]

[Range(60,100,ErrorMessage="分数必须在60和100之间")]

[Display(Name="分数")]

publicintScore{get;set;}


[Display(Name="招收日期")]

publicDateTimeEnrollment{get;set;}

}

}

[/code]

模拟一个仓储层,负责数据的初始化、添加和显示

usingSystem;

[code]usingSystem.Collections.Generic;
usingDataAnnotationAjax.Models;


namespaceDataAnnotationAjax.Service

{

publicstaticclassStudentRepository

{

privatestaticint_idSeed=1;

privatestaticreadonlyList<Student>_students=newList<Student>();


staticStudentRepository()

{

Randomrand=newRandom();

for(inti=0;i<3;i++)

{

varstudent=newStudent();

intid=_idSeed++;

student.Id=id;

student.Name="姓名"+id.ToString();

student.Score=(60+Convert.ToInt16(rand.NextDouble()*40));

student.Enrollment=DateTime.Now;

_students.Add(student);

}

}


publicstaticvoidAddStudent(Studentstu)

{

stu.Id=_idSeed++;

stu.Enrollment=DateTime.Now;

_students.Add(stu);

}


publicstaticList<Student>GetStudents()

{

return_students;

}

}

}


[/code]

BaseController

前台视图为了显示错误信息等,需要控制器传来的json可能包含如下构成:

1、是否验证通过:这个bool值很容易通过ModelState拿到。
2、错误信息的字典集合:每个控制器都有可能用到,可以把获取错误信息的字典集合方法放到一个基控制器中去。
3、再加一个福利:有时希望部分视图以字符串形式传递给某一视图,那就把根据视图名称和model返回视图字符串的方法也放到基控制器中。
usingSystem;
usingSystem.Collections.Generic;
usingSystem.IO;
usingSystem.Linq;
usingSystem.Web;
usingSystem.Web.Mvc;

namespaceDataAnnotationAjax.Controllers
{
publicclassBaseController:Controller
{
///<summary>
///把部分视图转换成string
///</summary>
///<paramname="viewName">部分视图名称</param>
///<paramname="model">viewmodel</param>
///<returns>部分视图字符串</returns>
publicstringRenderPartialViewToString(stringviewName,objectmodel)
{
ViewData.Model=model;
using(varsw=newStringWriter())
{
//根据部分视图名称+ControllerContext获得ViewEngineResult
//ViewEngineResult中有View属性
varviewResult=ViewEngines.Engines.FindPartialView(ControllerContext,viewName);

//创建ViewContext对象实例
varviewContext=newViewContext(ControllerContext,viewResult.View,ViewData,TempData,sw);

//把ViewEngineResult中的视图渲染到StringWriter实例中
viewResult.View.Render(viewContext,sw);

//获取视图string
returnsw.GetStringBuilder().ToString();
}
}

///<summary>
///获取ModelState中的错误信息,以字典集合的形式返回
///</summary>
///<returns></returns>
publicDictionary<string,object>GetErrorFromModelState()
{
varerrors=newDictionary<string,object>();
foreach(varkeyinModelState.Keys)
{
if(ModelState[key].Errors.Count>0)
{
errors[key]=ModelState[key].Errors;
}
}
returnerrors;
}
}
}


HomeController

HomeController做了:

1、显示一个异步提交的视图Index.cshtml
2、完成了验证通过情况下的数据添加。
3、不管是否验证通过,都要返回json字符串。


usingSystem.Web.Mvc;

[code]usingDataAnnotationAjax.Models;
usingDataAnnotationAjax.Service;


namespaceDataAnnotationAjax.Controllers

{

publicclassHomeController:BaseController

{

publicActionResultIndex()

{

returnView(StudentRepository.GetStudents());

}


[HttpPost]

publicActionResultAddStudent()

{

varstudent=newStudent();

varvalid=TryUpdateModel(student);

stringstudentPartialViewHtml=string.Empty;

if(valid)

{

StudentRepository.AddStudent(student);

varstudents=StudentRepository.GetStudents();

studentPartialViewHtml=RenderPartialViewToString("Students",students);

}

returnJson(new{Valid=valid,Errors=GetErrorFromModelState(),StudentsPartial=studentPartialViewHtml});

}

}

}


[/code]

部分视图Students.cshtml

@modelIEnumerable<DataAnnotationAjax.Models.Student>

<table>
<tr>
<th>
@Html.DisplayNameFor(model=>model.Name)
</th>
<th>
@Html.DisplayNameFor(model=>model.Score)
</th>
<th>
@Html.DisplayNameFor(model=>model.Enrollment)
</th>
</tr>

@foreach(variteminModel){
<tr>
<td>
@Html.DisplayFor(modelItem=>item.Name)
</td>
<td>
@Html.DisplayFor(modelItem=>item.Score)
</td>
<td>
@item.Enrollment.ToString("yy-MM-dd")
</td>
</tr>
}

</table>


Index.cshtml异步提交的界面


@modelIEnumerable<DataAnnotationAjax.Models.Student>

[code]
@{

ViewBag.Title="Index";

Layout="~/Views/Shared/_Layout.cshtml";

}

<styletype="text/css">

.errormsg{

color:red;

}

</style>


<div>

<tablecellpadding="0px">

<tr>

<td>姓名</td>

<td><inputtype="text"id="Name"/></td>

</tr>

<tr>

<td></td><tdcolspan="2"

id="Err_Name"class="errormsg"></td>

</tr>

<tr>

<td>分数</td>

<td><inputtype="text"id="Score"/></td>

<td>

<buttonid="btnAddStudent">添加学生</button>

<buttonid="btnClear">清空</button>

</td>

</tr>

<tr>

<td></td><tdcolspan="2"

id="Err_Score"class="errormsg"></td>

</tr>

</table>

</div>


<divid="divStudent">

@{Html.RenderPartial("Students",Model);}

</div>


@sectionscripts

{

<scripttype="text/javascript">

$(function(){

$('#btnAddStudent').click(function(){

vardata={

Name:$.trim($('#Name').val()),

Score:$.trim($('#Score').val())

};


$.ajax({

cache:false,

type:"POST",

url:'@Url.Action("AddStudent","Home")',

data:data,

dataType:"json",

success:function(data){

if(data.Valid){

$('#divStudent').html(data.StudentsPartial);

$('input').val("");

return;

}

$.each(data.Errors,function(key,value){

if(value!=null){

$('#Err_'+key).html(value[value.length-1].ErrorMessage);

}

});

},

error:function(xhr){

alert(xhr.responseText);

alert("数据没有能提交到服务器!");

}

});

});


$('#btnClear').click(function(){

$('.errormsg').html("");

$("input").val("");

});


$("input").keyup(function(){

var$errorDiv=$("#Err_"+this.id);

if($errorDiv.html()!=""){

$errorDiv.html("");

}

});

});

</script>

}


[/code]

几个关键点:
1、显示错误信息的元素id的命名有讲究的:Err_Name,Name与Model中的属性一致。
2、遍历服务端传来的错误信息字典集合时,对每个属性,即key,拿的是最近一次错误:$('#Err_'+key).html(value[value.length-1].ErrorMessage)。

没有填写信息报错:





填写分数不在定义区间报错:





全部填写正确,验证通过,把部分视图以string形式返回并加载到页面区域中:



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: