在现代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开发者使用的视图引擎),有一种批评是它在渲染简单标签时过度负担客户端。如果比较过与
在开发这个框架时,意识到将领域对象序列化为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("");
}