一起谈.NET技术,ASP.NET MVC中的Json Binding和Validate

简介:   电子商务网站支付功能页面往往会有很多信息,对于这些信息的保存,往往是分步完成的,那么使用Ajax最合适不过了,比如其中的收货人信息模块。这些信息的新建和编辑保存都是用Ajax来完成的。那么有几种方式完成这个操作呢,我想到如下几种。

  电子商务网站支付功能页面往往会有很多信息,对于这些信息的保存,往往是分步完成的,那么使用Ajax最合适不过了,比如其中的收货人信息模块。这些信息的新建和编辑保存都是用Ajax来完成的。那么有几种方式完成这个操作呢,我想到如下几种。
  先来看看该功能的截图:

  一般情况下这些信息会对应一个实体类,就命名为:ReceiverInfo,简单起见,我定义ReceiverInfo如下:


  1、将需要的值拼接成json文本,再Action里面处理

  首先您需要将要保存的值拼接成一个json文本,类似:

 
 
var test = " { ReceiverId: 5, ReceiverName: 'will', Sex: 'F', CreateDate: '2011-02-21' } " ;

  然后用Jquery保存到数据库,代码如下:

 
 
$.ajax({
url:
" /Home/test1 " ,
type:
" post " ,
cache:
false ,
data: test
});

  然后您在Action里面这样操作:

 
 
StreamReader reader = new StreamReader(Request.InputStream);
string bodyText
= reader.ReadToEnd();
JavaScriptSerializer js
= new JavaScriptSerializer();
ReceiverInfo receiver
= js.Deserialize < ReceiverInfo > (bodyText);
// 保存。。。

  2、利用自定义的ModelBinder实现

JsonBinder
1 public class JsonBinder<T> : IModelBinder
2 {
3 public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
4 {
5 StreamReader reader = new StreamReader(controllerContext.HttpContext.Request.InputStream);
6 string json = reader.ReadToEnd();
7
8 if (string.IsNullOrEmpty(json))
9 return json;
10
11 JavaScriptSerializer serializer = new JavaScriptSerializer();
12 object jsonData = serializer.DeserializeObject(json);
13 return serializer.Deserialize<T>(json);
14 }
15 }

  我们继承IModelBinder接口,实现其 方法:

 
 
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)

  即可。我们可以在Action里面这样使用:

 
 
public ActionResult Test1([ModelBinder( typeof (JsonBinder < ReceiverInfo > ))] ReceiverInfo receiverInfo)

  这样我们自定义的 IModelBinder就会取代DefaultModelBinder完成数据绑定。
  3、直接传递一个Json对象

  上面两种方法并没有利用MVC的System.ComponentModel.DataAnnotations进行有效的数据验证。您可能需要自己手动验证,无疑增加了工作量。

  我们试试这种方式。

  前端的写法:

 
 
1 . var b = {
2 . ReceiverId: 5 ,
3 . ReceiverName: " will " ,
4 . Sex: " F " ,
5 . CreateDate: " 2011-02-21 " };$.ajax({
6 . url: " /Home/test1 " ,
7 . type: " post " ,
8 . cache: false ,
9 . data: b,
10 . success: function(data) { alert(data.message); },
11 . error: function(xhr, a, b) { alert
12 . (xhr.responseText); }});

  Action的写法:

 
 
public ActionResult Test1(ReceiverInfo receiverInfo)

  我们能正常的得到绑定后的数据。而且我们还能利用System.ComponentModel.DataAnnotations进行数据验证。我们为ReceiverInfo做如下改动:

 
 
[System.ComponentModel.DataAnnotations.Required(ErrorMessage = " 收货人必须填写 " )]
public string ReceiverName { get ; set ; }

  并在前端为ReceiverName赋值为空字符串,再次执行,得到提示:

  很好,不过我们有新的要求了,那就是传递更复杂的对象,比如对象套嵌对象,对象有集合属性,这种方式不能胜任了。
  4、利用MvcFutures的JsonValueProviderFactory

  每一版的MVC都有一个MvcFutures,里面会有一些额外的功能,这些功能有些会加入下一个版本中,而这些功能在某些时候很有用处。我查看了里面的类,发现有一个类JsonValueProviderFactory正是处理复杂对象的提交和数据验证。

  由于json对象需要特定解析才能使用默认的DefaultModelBinder,而这个解析过程需要在ValueProvider阶段完成,所以需要实现特定的ValueProvider给DefaultModelBinder。我们需要实现一个ValueProviderFactory和IValueProvider,而MVC里面的DictionaryValueProvider<TValue>(继承了IValueProvider)已经足够使用了,所以只需要继承ValueProviderFactory实现其方法:public override IValueProvider GetValueProvider(ControllerContext controllerContext)即可,具体代码您可以看JsonValueProviderFactory。

  我们定义另一个类:

ReceiverInfoChild
 
  
public class ReceiverInfoChild
{
[System.ComponentModel.DataAnnotations.Required(ErrorMessage
= " ChildId必须填写 " )]
public string ChildId { get ; set ; }
}

  并为类ReceiverInfo增加一个属性public List<ReceiverInfoChild> ReceiverInfoChild { get; set; }

  我们把JsonValueProviderFactory拿出来放在项目里面,然后在Global.asax里面注册一下,就可以使用了。

 
 
1 . protected void Application_Start(){
2 . AreaRegistration.RegisterAllAreas();
3 . RegisterRoutes(RouteTable.Routes);
4 . ValueProviderFactories.Factories.Add( new
5 . JsonValueProviderFactory());}

  因为JsonValueProviderFactory中有:if (!controllerContext.HttpContext.Request.ContentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase))来判断进来的请求是不是json对象,所以我们提交数据的时候需要这样写:

 
 
1 . var ReceiverInfo = [
2 . {
3 . ReceiverInfoChild: [{ ChildId: " 1 " }, { ChildId: " 11 " }],
4 . ReceiverId: 5 ,
5 . ReceiverName: " will " ,
6 . Sex: " F " ,
7 . CreateDate: " 2011-02-21 "
8 . },
9 . {
10 . ReceiverInfoChild: [{ ChildId: " 2 " }, { ChildId: " 22 " }],
11 . ReceiverId: 5 ,
12 . ReceiverName: " will " ,
13 . Sex: " F " ,
14 . CreateDate: " 2011-02-21 " }
15 . ];$.ajax({
16 . url: " /Home/test1 " ,
17 . type: " post " ,
18 . cache: false ,
19 . contentType: " application/json;charset=utf-8 " ,
20 . data: JSON.stringify(ReceiverInfo),
21 . success: function(data) { alert(data.message); },
22 . error: function(xhr, a, b) { alert(xhr.responseText); }});

  其中JSON.stringify(ReceiverInfo)是将json对象转换成字符串,您可以到这里下载该类库。

  在Action里面,我们这样写就可以了:

 
 
public ActionResult Test1(List < ReceiverInfo > receiverInfo)

  看一下调试的结果:

  完全正常绑定了值。我们再看看数据验证:


  至此,我们实验了四种方案:

  第一种方案,最麻烦,而且容易出错(可能跟我个人不喜欢拼接字符串有关系);

  第二种方案,有一定的通用性,但是不利于数据验证;

  第三种方案,通用,可以进行有效的数据验证,应对一般的需求够用了,但是处理更复杂的对象不行;

  第四种方案,几乎可以处理我们遇到的所有情况

  另外,这是在ASP.NET MVC2中的使用,到了ASP.NET MVC3,微软已经把JsonValueProviderFactory作为内置的功能了。

目录
相关文章
|
6月前
|
前端开发 Java Go
Spring MVC 中的数据验证技术
Spring MVC 中的数据验证技术
45 0
|
6月前
|
存储 开发框架 前端开发
asp.net与asp.net优缺点及示例
asp.net与asp.net优缺点及示例
|
1月前
|
开发框架 前端开发 .NET
进入ASP .net mvc的世界
进入ASP .net mvc的世界
29 0
|
1月前
|
开发框架 中间件 .NET
C# .NET面试系列七:ASP.NET Core
## 第一部分:ASP.NET Core #### 1. 如何在 controller 中注入 service? 在.NET中,在ASP.NET Core应用程序中的Controller中注入服务通常使用<u>依赖注入(Dependency Injection)</u>来实现。以下是一些步骤,说明如何在Controller中注入服务: 1、创建服务 首先,确保你已经在应用程序中注册了服务。这通常在Startup.cs文件的ConfigureServices方法中完成。例如: ```c# services.AddScoped<IMyService, MyService>(); //
63 0
|
1月前
|
开发框架 前端开发 .NET
C# .NET面试系列六:ASP.NET MVC
<h2>ASP.NET MVC #### 1. MVC 中的 TempData\ViewBag\ViewData 区别? 在ASP.NET MVC中,TempData、ViewBag 和 ViewData 都是用于在控制器和视图之间传递数据的机制,但它们有一些区别。 <b>TempData:</b> 1、生命周期 ```c# TempData 的生命周期是短暂的,数据只在当前请求和下一次请求之间有效。一旦数据被读取,它就会被标记为已读,下一次请求时就会被清除。 ``` 2、用途 ```c# 主要用于在两个动作之间传递数据,例如在一个动作中设置 TempData,然后在重定向到另
99 5
|
3月前
|
开发框架 安全 搜索推荐
分享105个NET源码ASP源码,总有一款适合您
分享105个NET源码ASP源码,总有一款适合您
27 4
|
4月前
|
JSON 开发框架 .NET
ASP.NET Core Web API设置响应输出的Json数据格式的两种方式
ASP.NET Core Web API设置响应输出的Json数据格式的两种方式
|
6月前
|
SQL 前端开发 Java
JSP个人信息管理系统myeclipse开发sql数据库BS模式java编程struts2技术mvc框架
JSP 个人信息管理系统是一套完善的web设计系统,对理解JSP java编程开发语言有帮助struts2技术mvc框架,系统具有完整的源代码和数据库,开发环境为TOMCAT7.0,Myeclipse8.5开发,数据库为Mysql5.0,使用java语言开发,系统主要采用B/S模式开发。
57 0
|
6月前
|
SQL 前端开发 Java
JSP网上订餐管理系统myeclipse开发sql数据库BS模式java编程servlet技术mvc框架
JSP 网上订餐管理系统是一套完善的web设计系统,对理解JSP java编程开发语言有帮助servlet技术mvc框架,系统具有完整的源代码和数据库,开发环境为TOMCAT7.0,Myeclipse8.5开发,数据库为Mysql5.0,使用java语言开发,系统主要采用B/S模式开发。
39 0
|
6月前
|
开发框架 .NET API
ASP.NET Core Binding source
Binding source Attributes借助 binding source attributes 可以将请求传递的数据传递给 api,详细的attribute 如下图。但 在 api 项目下的 标识了 apicontroller 的controller下,binding source attributes 的规则 有所改变 HttpHEADhead 也是一种http 请求方法,他...
23 0
ASP.NET Core Binding source