使用 Webservice 和 JSON 将数据绑定到表格。






2.44/5 (11投票s)
2007年10月12日
4分钟阅读

52142

918
使用 WebServices 创建 JSON 应用程序
引言
JavaScript 对象表示法,简称 JSON,旨在成为 XML 的轻量级替代品,当 XML 对于您要实现的目标来说有点过于沉重时。尽管 JSON 不可扩展,因为它使用了固定的数据类型集,但它可以用来以文本形式表示复杂的对象。JSON 是一个理想的数据交换格式,当使用 AJAX 等技术时,您的服务器端对象可以转换为 JSON,发送到客户端,在客户端脚本中进行评估,然后进行操作以构建动态广告、菜单等。
基本 JSON 结构
JSON 由两种所有程序员都熟悉的结构组成,即
- 对象 - JSON 类型集合,通过键访问。这可以看作是
IDictionary<string, JsonType>
。 - 数组 - JSON 类型集合,通过索引访问。这可以看作是
IList<JsonType>
。
JSON 还定义了四种原始类型
- 字符串 - 一组由双引号括起来的 Unicode 字符。支持基本控制字符以及四位数的 Unicode 转义序列。
- 数字 - 可以是负数、包含小数部分和包含指数的数字。
- 布尔值 - true 或 false。
- null - null 值。
我不想用细节来烦扰您,但 JSON 规范的链接可以在“参考”部分找到。
代码
NetServ.Net.Json
命名空间中的所有 JSON 类型都实现了 IJsonType
接口。此接口允许通过其 JsonTypeCode
标识类型,并允许其将内容写入 IJsonWriter
。IJsonType
接口的实现包括 JsonString
、JsonNumber
、JsonBoolean
、JsonArray
、JsonObject
和 JsonNull
。该接口定义如下:
using System;
namespace NetServ.Net.Json
{
/// <summary>
/// Defines a JavaScript Object Notation data type.
/// </summary>
public interface IJsonType
{
/// <summary>
/// Writes the contents of the Json type using the specified
/// <see cref="NetServ.Net.Json.IJsonWriter"/>.
/// </summary>
/// <param name="writer">The Json writer.</param>
void Write(IJsonWriter writer);
/// <summary>
/// Gets the <see cref="NetServ.Net.Json.JsonTypeCode"/> of the type.
/// </summary>
JsonTypeCode JsonTypeCode {
get;
}
}
/// <summary>
/// Defines the different types of Json structures and primitives.
/// </summary>
[Serializable()]
public enum JsonTypeCode
{
/// <summary>
/// A unicode encoded string.
/// </summary>
String,
/// <summary>
/// A number.
/// </summary>
Number,
/// <summary>
/// A boolean value represented by literal "true" and "false".
/// </summary>
Boolean,
/// <summary>
/// A null value.
/// </summary>
Null,
/// <summary>
/// A structured object containing zero or more name/value pairs,
/// delimited by curly brackets.
/// </summary>
Object,
/// <summary>
/// An unordered collection of values, delimted by square brackets.
/// </summary>
Array
}
}
IJsonWriter
接口定义了一个 JSON 写入器。它定义了将 JSON 类型转换为文本所需的基本方法。该接口的一个实现是 JsonWriter
类,它将 JSON 文本写入底层的 TextWriter
。
using System;
namespace NetServ.Net.Json
{
/// <summary>
/// Defines a JavaScript Object Notation writer.
/// </summary>
public interface IJsonWriter
{
/// <summary>
/// Writes the start of an array to the underlying data stream.
/// </summary>
void WriteBeginArray();
/// <summary>
/// Writes the end of an array to the underlying data stream.
/// </summary>
void WriteEndArray();
/// <summary>
/// Writes the start of an object to the underlying data stream.
/// </summary>
void WriteBeginObject();
/// <summary>
/// Writes the end of an object to the underlying data stream.
/// </summary>
void WriteEndObject();
/// <summary>
/// Writes a object property name to the underlying data stream.
/// </summary>
/// <param name="value">The property name.</param>
void WriteName(string value);
/// <summary>
/// Writes a raw string value to the underlying data stream.
/// </summary>
/// <param name="value">The string to write.</param>
void WriteValue(string value);
}
}
.NET 中的使用示例
以下是一个如何构建 JSON 类型集合并将结果写入控制台的简短示例。请注意,一个更复杂的示例,包括多个嵌套对象和数组,已包含在演示项目下载中。
using System;
using NetServ.Net.Json;
namespace JsonTest
{
[STAThread()]
public class Program
{
public static void Main(string[] args) {
JsonObject order = new JsonObject();
JsonObject addr = new JsonObject();
JsonArray items = new JsonArray();
JsonObject item;
// Add some items into the array.
item = new JsonObject();
item.Add("ID", new JsonString("Chicken & Chips"));
item.Add("Qty", new JsonNumber(2));
item.Add("Price", new JsonNumber(1.50D));
item.Add("Req", new JsonString("Plenty of salad."));
items.Add(item);
// The less verbose way.
item = new JsonObject();
item.Add("ID", "Pizza");
item.Add("Qty", 1);
item.Add("Price", 9.60D);
item.Add("Size", "16\"");
item.Add("Req", "");
items.Add(item);
// Add the address information.
addr.Add("Street", "16 Bogus Street");
addr.Add("City", "Bogustown");
addr.Add("County", "Boguscounty");
addr.Add("Postcode", "B0GU5");
// Add the items and address into the order.
order.Add("Items", items);
order.Add("Address", addr);
order.Add("Name", "Andrew Kernahan");
order.Add("Tel.", "55378008");
order.Add("Delivery", true);
order.Add("Total", 12.60D);
using(JsonWriter writer = new JsonWriter()) {
// Get the container to write itself and all it's
// contained types to the writer.
order.Write(writer);
// Print the result.
Console.WriteLine(writer.ToString());
}
}
}
}
使用 JsonWriter
将产生最紧凑的输出。另一个 IJsonWriter
是 IndentedJsonWriter
,它将产生缩进的输出,如果需要,人类可以轻松阅读。当使用 IndentedJsonWriter
时,上面的示例将产生以下输出。
{
"Items":
[
{
"ID": "Chicken & Chips",
"Qty": 2,
"Price": 1.5,
"Req": "Plenty of salad."
},
{
"ID": "Pizza",
"Qty": 1,
"Price": 9.6,
"Size": "16\"",
"Req": ""
}
],
"Address":
{
"Street": "16 Bogus Street",
"City": "Bogustown",
"County": "Boguscounty",
"Postcode": "B0GU5"
},
"Name": "Andrew Kernahan",
"Tel.": "55378008",
"Delivery": true,
"Total": 12.6
}
JsonParser
类用于构建从 TextReader
读取的 JSON 类型。下面是一个解析和提取 JSON 类型的简单示例。请注意,更复杂的示例可以在演示项目下载中找到。
using System;
using System.IO;
using NetServ.Net.Json;
namespace JsonTest
{
public class Program
{
[STAThread()]
public static void Main(string[] args) {
StringReader rdr =
new StringReader("{\"Name\":\"Andy\",\"Age\":23,\"Hungry?\":true}");
// The parser takes any TextReader derived class as its source.
JsonParser parser = new JsonParser(rdr, true);
JsonObject obj = (JsonObject)parser.ParseObject();
// Get the information from the object.
JsonString name = (JsonString)obj["Name"];
JsonNumber age = (JsonNumber)obj["Age"];
JsonBoolean hungry = (JsonBoolean)obj["Hungry?"];
// Print out the information.
Console.WriteLine("Name:\t\t{0}", name.Value);
Console.WriteLine("Age:\t\t{0}", age.Value.ToString());
Console.WriteLine("Hungry?:\t{0}", hungry.Value.ToString());
}
}
}
JavaScript 中的使用示例
如果您将 JSON 用作 AJAX 数据交换格式,那么在客户端脚本中使用 JSON 文本会非常简单,如下面的示例所示。
function updateAdvertsCallback(result, context) {
// result = [
// {"AdvertId":"left","InnerHTML":"Some text","ImageSrc":"animage""},
// {"AdvertId":"right","InnerHTML":"Some more text",
// "ImageSrc":"anotherimage""}
// ]
// Use the JavaScript compiler to parse the text and generate
// the objects.
var adverts = eval("(" + result + ")");
// Then access the members as you would normally.
for(var i = 0; i < adverts.length; ++i) {
document.getElementById("advertHTML_" +
adverts[i].AdvertId).innerHTML = adverts[i].InnerHTML;
document.getElementById("advertImg_" +
adverts[i].AdvertId).src = adverts[i].ImageSrc;
}
}
您应该意识到,JavaScript 的 eval
函数可以在评估时执行客户端代码,因此仅当您信任 JSON 的来源时才应使用它。另一种方法是使用一个只识别有效 JSON 输入并忽略其他所有内容的解析器。一个好的 JavaScript JSON 解析器可以在这里找到。
关注点
NetServ.Net.Json
命名空间中的大多数 JSON 类型都利用了 C# 的运算符重载的强大功能。这允许您编写非常简洁的代码,精确地表达您想要实现的目标。
// JsonBoolean jb = JsonBoolean.Get(true);
JsonBoolean jb = true;
// JsonNumber jn = new JsonNumber(42);
JsonNumber jn = 42;
// JsonString js = new JsonString("Hello World!");
JsonString js = "Hello World!";
此外,NetServ.Net.Json
库是符合 CLS 标准的,因此可以在任何使用符合 CLS 标准的语言开发的 .NET 项目中使用。
单元测试
下载中包含了该库编译的单元测试。这些测试是与 Marc Clifton 的高级单元测试工具一起编写的。下面可以看到对这 200 个测试的概述。

结论
我承认这篇文章有点轻量级(第一次写,请多包涵!),但希望您能欣赏到 JSON 格式在 XML 对于您的需求来说过于繁重时的有用性。
参考文献
- http://www.json.org/ - 官方 JSON 网站。
- RFC4627 - JavaScript 对象表示法 (JSON) 的 application/json 媒体类型。
有用链接
历史
- 2007 年 1 月 16 日 - v1.1 首次公开发布。