JSON数据序列化与客户端绑定

在现代Web开发中,JSON(JavaScript Object Notation)格式因其简洁和易于阅读的特性,被广泛用于数据交换。JSON格式不仅在服务器与客户端之间传输数据时非常高效,而且可以轻松地在客户端转换成对象。例如,在JavaScript中,可以这样声明一个数组:

var myArray = [ "this", "that", "the other" ];

对象表示法甚至更简单。想象一下C#中的"Person"类:

public class Person { public int ID { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public string SSN { get; set; } }

如果想将这些数据表达给客户端,可以这样做:

var person = { "ID": "1", "FirstName": "Jeremy", "LastName": "Likness", "SSN": "111-222-3333" }; alert("My name is " + person.FirstName + " " + person.LastName);

对于WebForms视图引擎(大部分.NET开发者使用的视图引擎),有一种批评是它在渲染简单标签时过度负担客户端。如果比较过与,就会明白这一点。此外,开发者往往会迷失在AJAX框架的“便利性”中,而忽略了将级联下拉列表包装在更新面板中的性能影响。一个更简单的方法是使用第三方工具,如JQuery,来序列化值并绑定它们。

在开发这个框架时,意识到将领域对象序列化为JSON会非常简单。想要一个通用的解决方案,它不依赖于反射进行抽象,并且让完全控制要渲染的属性,而不必在领域模型中添加属性或其他声明,这些完全是UI相关的。

结果是一个带有Serialize()方法的"JSONObject",它输出JSON代码。以下是类定义:

namespace MyJSON { public delegate string PropertyValue(T instance, string property); public class JSONObject { private readonly T _object; private readonly List _properties; private readonly PropertyValue _propValue; public JSONObject(T instance, IEnumerable properties, PropertyValue propValue) { _object = instance; _properties = new List(properties); _propValue = propValue; } public string Serialize() { StringBuilder json = new StringBuilder(); json.Append("{"); bool first = true; foreach (string prop in _properties) { if (first) { first = false; } else { json.Append(","); } string value = _propValue(_object, prop); json.Append(string.Format("\"{0}\":{1}", prop, EncodeJsString(value))); } json.Append("}"); return json.ToString(); } } }

JSON对象接受类型T,它可以是任何类型。构造函数接受"T",以及一个数组和一个委托。数组是一个字符串列表,描述了感兴趣的属性。例如,可能只想发送id和LastName,因为在客户端脚本中不使用其他属性。最后是委托。签名很简单:给定属性和实体,它的值作为字符串是什么?这允许注入逻辑,将UI属性映射到领域属性。最简单的发送数据的方法是将其实现为字符串,然后在客户端适当地操作。毕竟,JavaScript本身并不"知道"复杂对象。

最简单的用法是发送Person对象并显示名称。例如:

<b>ID:</b> <span id="personId"></span> <b>Name:</b> <span id="personName"></span>

在脚本中,简单地创建JSON对象并序列化它:

JSONObject<Person> jsonPerson = new JSONObject<Person>(new Person { ID = 1, LastName = "Likness" }, new[] { "id", "name" }, (entity, property) => property.Equals("id") ? entity.ID : entity.LastName); Page.ClientScript.RegisterClientScriptBlock(GetType(), GetType(), string.Format("var person={0}", jsonPerson.Serialize()), true);

最后,需要一些东西来为连接,选择JQuery...

<script type="text/javascript"> $(document).ready(function(){ $("#personId").html(person.id); $("#personName").html(person.name); }); </script>

脚本块接受一个类型(只是使用页面或所在的控件的类型),一个键(这应该是每个脚本块唯一的...再次使用类型,但可以将其强类型化或设置为const等),要发出的JavaScript(来自JSON对象的serialize方法),然后true告诉它要包装脚本标签,因为没有自己这样做。

这些对象可以作为回调的结果返回(只需将它们分配给window.var对象,以便它们全局可访问,并使用eval),或者可能会渲染一个对象数组,然后做类似这样的事情:

for (var x = 0; x < window.json_options.length; x++) { var option = window.json_options[x]; $("#selBox").append(""); }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485