ASP.NET MVC中的Json “.NET研究”Binding和Validate

  电子商务网站支付功能页面往往会有很多信息,对于这些信息的保存,往往是分步完成的,那么使用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赋值为空字符串,再次执行,得到提示:

  很好,不过我们有新的要求了,那就是传递更复杂的对象,比如对象套嵌对象,对象有集合属性,这种方式不能胜任了。上海闵行企业网站设计与制作 style="font-size: 16px;">
  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.OrdinalIgnoreC上海网站建设ase))来判断进来的请求是不是json对象,所以我们提交数据的时候需要这样写:


1. var ReceiverInfo = [
2. {
3. ReceiverInfoChild: [{ ChildId: "1" }, { ChildId: "上海企业网站设计与制作e="color: #800000;">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里面,我们这样写就可以了:


上海徐汇企业网站制作"color: #0000ff;">public ActionResult Test1(List<ReceiverInfo> receiverInfo)

  看一下调试的结果:

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

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

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

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

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

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

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

时间: 2024-09-20 05:37:16

ASP.NET MVC中的Json “.NET研究”Binding和Validate的相关文章

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

电子商务网站支付功能页面往往会有很多信息,对于这些信息的保存,往往是分步完成的,那么使用Ajax最合适不过了,比如其中的收货人信息模块.这些信息的新建和编辑保存都是用Ajax来完成的.那么有几种方式完成这个操作呢,我想到如下几种. 先来看看该功能的截图: 一般情况下这些信息会对应一个实体类,就命名为:ReceiverInfo,简单起见,我定义ReceiverInfo如下: 1.将需要的值拼接成json文本,再Action里面处理 首先您需要将要保存的值拼接成一个json文本,类似: var te

ASP.NET MVC中对数据进行排序的方“.NET研究”法

本系列是讲解如何在asp.net mvc中对数据进行展示.排序.分页等的系列文章.在上周的文章中,一步一步教会了大家如何使用ASP.NET MVC框架去的展示数据.在上周的文章中,我们先用Visual Studio创建了一个新的ASP.NET MVC应用程序,接着连接到了Northwind数据库,并展示了如何使用微软的LINQ-SQL的工具去访问数据库中的数据,接着指导如何去实现视图层去展示产品信息及如何设计控制器. 本文是在上一篇文章的例子基础上,展示了如何去实现数据的双向排序.如果你是已经熟

包含在ASP.NET MVC中的过滤器

在深入研究如何编写过滤器之前,首先看看包含在ASP.NET MVC中的过滤器. ASP.NET MVC包括了如下3种即开即用的动作过滤器: Authorize:该过滤器用于限制对控制器或控制器动作的访问. HandleError:该过滤器用来指定一个处理异常的动作,这个异常是从动作方法的内部抛出的. OutputCache:该过滤器用来为动作方法提供输出的缓存. 接下来将依次深入讨论这3个过滤器. 1  Authorize AuthorizeAttribute是包含在ASP.NET MVC中默认

在 Asp.NET MVC 中使用 SignalR 实现推送功能

原文http://www.cnblogs.com/kesalin/archive/2012/11/09/signalr_push.html 在 Asp.NET MVC 中使用 SignalR 实现推送功能 罗朝辉 ( http://www.cnblogs.com/kesalin/ ) CC许可,转载请注明出处   一,简介 Signal 是微软支持的一个运行在 Dot NET 平台上的 html websocket 框架.它出现的主要目的是实现服务器主动推送(Push)消息到客户端页面,这样客户

ASP.NET MVC中的AJAX应用_实用技巧

一.ASP.NET MVC中的AJAX应用 首先,在ASP.NET MVC中使用自带的ajax功能,必须要导入2个js文件(顺序不能颠倒): ASP.NET MVC提供了2个常用的ajax辅助方法. Ajax.ActionLink 该辅助方法用于在页面上生成具有ajax功能的超链接. 在该辅助方法中有一个AjaxOptions类型的参数,它包括如下属性: Confirm:在发送ajax请求前,弹出确认对话框,该属性就是设置对话框中的提示消息HttpMethod:用于设置请求的类型:Get|Pos

ASP.NET MVC中使用jQuery时的浏览器缓存问题详解_实用技巧

介绍 尽管jQuery在浏览器ajax调用的时候对缓存提供了很好的支持,还是有必要了解一下如何高效地使用http协议. 首先要做的事情是在服务器端支持HTTP GET,定义不同的URL输出不同的数据(MVC里对应的就是action).如果要使用同一个地址获取不同的数据,那就不对了,一个HTTP POST也不行因为POST不能被缓存.许多开发人员使用POST主要有2个原因:明确了数据不能被缓存,或者是避免JSON攻击(JSON返回数组的时候可以被入侵). 缓存解释 jQuery全局对象里的ajax

如何在 ASP.NET MVC 中集成 AngularJS(3)

今天来为大家介绍如何在 ASP.NET MVC 中集成 AngularJS 的最后一部分内容. 调试路由表 - HTML 缓存清除 就在我以为示例应用程序完成之后,我意识到,我必须提供两个版本的路由表:一个运行在调试模式的应用程序下和一个运行在发布模式的应用程序下.在调试模式下,JavaScript 文件在未使用压缩功能的情况下会被下载.如果想要调试并在 JavaScript 控制器中设置断点,这是必须的.事实上,路由表的产生版本也出现了一些挑战,由于产生路由代码使用的是 JavaScript

如何在 ASP.NET MVC 中集成 AngularJS(2)

在如何在 ASP.NET MVC 中集成 AngularJS(1)中,我们介绍了 ASP.NET MVC 捆绑和压缩.应用程序版本自动刷新和工程构建等内容. 下面介绍如何在 ASP.NET MVC 中集成 AngularJS 的第二部分. ASP.NET 捆绑和压缩 CSS 和 JavaScript 的捆绑与压缩功能是 ASP.NET MVC 最流行和有效的特性之一.捆绑和压缩降低了 HTTP 请求和有效载荷的大小,结果是可以更快和更好的执行 ASP.NET MVC 的网站.有许多可以减少 CS

如何在 ASP.NET MVC 中集成 AngularJS(1)

介绍 当涉及到计算机软件的开发时,我想运用所有的最新技术.例如,前端使用最新的 JavaScript 技术,服务器端使用最新的基于 REST 的 Web API 服务.另外,还有最新的数据库技术.最新的设计模式和技术. 当选择最新的软件技术时,有几个因素在起作用,其中包括如何将这些技术整合起来.过去两年中,我最喜欢的一项技术就是设计单页面应用(SPA)的 AngularJS.作为一个微软stack开发者,我也是使用 ASP.NET MVC 平台实现 MVC 设计模式和并进行研究的粉丝,包括它的捆