JSON 与 XML 解析
开发专题 · Newtonsoft / DataContractJsonSerializer / XmlSerializer(.NET Framework 4.8)
本页说明在 .NET Framework 4.8 窗体(或控制台)项目中把对象与 JSON、XML 互转。目标框架以 LCode 默认的 .NET 4.8 为准;示例写法面向 C# 5.0 与 VB.NET(勿用 C# 6+ 语法如字符串插值、nameof)。操作文案以 LCode 中文界面为准。把 JSON/XML 文件加入项目见 资源文件;HTTP 响应体拿到字符串后再按本页解析,见 网络请求。
选用哪种方式
| 方式 | 命名空间 / 程序集 | 适用 |
|---|---|---|
DataContractJsonSerializer(框架自带) |
System.Runtime.Serialization.Json(程序集 System.Runtime.Serialization) |
不想引入第三方 DLL 时的 JSON 序列化;类型上通常标 [DataContract] / [DataMember] |
JsonConvert / JsonSerializer(Newtonsoft.Json) |
Newtonsoft.Json(第三方程序集 Newtonsoft.Json.dll) |
字段映射灵活、生态常见;需在 LCode 中浏览引用 DLL(主界面 NuGet暂不支持,待更新完善) |
XmlSerializer(框架自带) |
System.Xml.Serialization(程序集 System.Xml) |
对象 ↔ XML 字符串/文件;类型须有无参构造函数与可读写公共属性 |
JavaScriptSerializer(轻量备选) |
System.Web.Script.Serialization(程序集 System.Web.Extensions) |
简单字典/匿名结构;资源页示例已用。复杂模型优先上两行 JSON 方案 |
在 LCode 中引用
按 窗体应用入门 建好项目后,按所选方案补引用(通用步骤见 引用 DLL):
- DataContractJsonSerializer:右键项目 → 添加引用 → GAC 或框架列表,勾选
System.Runtime.Serialization→ 确定。代码中using System.Runtime.Serialization;与using System.Runtime.Serialization.Json;(VB:Imports同名命名空间)。 - XmlSerializer:窗体项目一般已引用
System.Xml。若编译找不到类型:同样「添加引用」勾选System.Xml。代码中using System.Xml.Serialization;/Imports System.Xml.Serialization。 - Newtonsoft.Json:将
Newtonsoft.Json.dll(与目标框架匹配的 .NET 4.x 版本)放到解决方案内固定目录(如lib\)→ 添加引用 → .NET集合浏览器 → 浏览(B)... 选中该 DLL → 确定。勾选「本地复制」为 True,保证输出目录带上 DLL。LCode 主界面 NuGet暂不支持,待更新完善,勿期待包管理器一键安装。 - 菜单 编译 → 编译解决方案(F8),确认无命名空间 / 程序集错误。
| 方案 | 需添加的引用 | LCode 操作要点 |
|---|---|---|
| DataContract JSON | System.Runtime.Serialization |
添加引用 → GAC / 框架列表勾选 |
| Newtonsoft JSON | Newtonsoft.Json.dll(浏览) |
浏览托管 DLL;本地复制 True;无 NuGet |
| XmlSerializer | System.Xml(多已默认) |
缺引用时再添加;一般不必第三方包 |
提示:把配置 JSON/XML 放进项目时,常用「成功行为」
Content +「复制到输出目录」。读文件路径可用 Path.Combine(Application.StartupPath, ...)。详见 资源文件。
JSON · DataContractJsonSerializer
类型用数据约定特性标记;序列化写入流,再转字符串。下面模型表示配置项 Title / Count。
| 成员 / API | 说明 |
|---|---|
[DataContract] / [DataMember] |
标在类型与要参与序列化的属性/字段上;未标 DataMember 的成员默认不输出 |
DataContractJsonSerializer(Type) |
构造序列化器,参数为根类型 |
WriteObject(Stream, object) |
把对象写入流(UTF-8 JSON) |
ReadObject(Stream) |
从流反序列化为对象,再转型 |
C#
using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Text;
[DataContract]
public class AppConfig
{
[DataMember]
public string Title { get; set; }
[DataMember]
public int Count { get; set; }
}
public static class JsonDcHelper
{
public static string ToJson(AppConfig cfg)
{
DataContractJsonSerializer ser =
new DataContractJsonSerializer(typeof(AppConfig));
using (MemoryStream ms = new MemoryStream())
{
ser.WriteObject(ms, cfg);
return Encoding.UTF8.GetString(ms.ToArray());
}
}
public static AppConfig FromJson(string json)
{
DataContractJsonSerializer ser =
new DataContractJsonSerializer(typeof(AppConfig));
byte[] bytes = Encoding.UTF8.GetBytes(json);
using (MemoryStream ms = new MemoryStream(bytes))
{
return (AppConfig)ser.ReadObject(ms);
}
}
}
// 使用:
// string json = JsonDcHelper.ToJson(new AppConfig { Title = "Demo", Count = 3 });
// AppConfig cfg = JsonDcHelper.FromJson(json);
VB.NET
Imports System
Imports System.IO
Imports System.Runtime.Serialization
Imports System.Runtime.Serialization.Json
Imports System.Text
<DataContract>
Public Class AppConfig
<DataMember>
Public Property Title As String
<DataMember>
Public Property Count As Integer
End Class
Public Module JsonDcHelper
Public Function ToJson(cfg As AppConfig) As String
Dim ser As New DataContractJsonSerializer(GetType(AppConfig))
Using ms As New MemoryStream()
ser.WriteObject(ms, cfg)
Return Encoding.UTF8.GetString(ms.ToArray())
End Using
End Function
Public Function FromJson(json As String) As AppConfig
Dim ser As New DataContractJsonSerializer(GetType(AppConfig))
Dim bytes As Byte() = Encoding.UTF8.GetBytes(json)
Using ms As New MemoryStream(bytes)
Return CType(ser.ReadObject(ms), AppConfig)
End Using
End Function
End Module
' 使用:
' Dim json As String = JsonDcHelper.ToJson(New AppConfig With {.Title = "Demo", .Count = 3})
' Dim cfg As AppConfig = JsonDcHelper.FromJson(json)
JSON · Newtonsoft.Json
引用 Newtonsoft.Json.dll 后,最常用 JsonConvert.SerializeObject / DeserializeObject<T>。普通 POCO 一般不必加特性。
| API | 说明 |
|---|---|
JsonConvert.SerializeObject(object) |
对象 → JSON 字符串 |
JsonConvert.DeserializeObject<T>(string) |
JSON 字符串 → 类型 T |
JsonSerializerSettings |
可选:空值处理、日期格式、缺失成员等 |
[JsonProperty("name")] |
属性名与 JSON 键不一致时映射 |
C#
using System;
using Newtonsoft.Json;
public class AppConfig
{
public string Title { get; set; }
public int Count { get; set; }
}
public static class JsonNsHelper
{
public static string ToJson(AppConfig cfg)
{
return JsonConvert.SerializeObject(cfg);
}
public static AppConfig FromJson(string json)
{
return JsonConvert.DeserializeObject<AppConfig>(json);
}
}
// 使用:
// string json = JsonNsHelper.ToJson(new AppConfig { Title = "Demo", Count = 3 });
// AppConfig cfg = JsonNsHelper.FromJson(json);
// MessageBox.Show(cfg.Title);
VB.NET
Imports System
Imports Newtonsoft.Json
Public Class AppConfig
Public Property Title As String
Public Property Count As Integer
End Class
Public Module JsonNsHelper
Public Function ToJson(cfg As AppConfig) As String
Return JsonConvert.SerializeObject(cfg)
End Function
Public Function FromJson(json As String) As AppConfig
Return JsonConvert.DeserializeObject(Of AppConfig)(json)
End Function
End Module
' 使用:
' Dim json As String = JsonNsHelper.ToJson(New AppConfig With {.Title = "Demo", .Count = 3})
' Dim cfg As AppConfig = JsonNsHelper.FromJson(json)
' MessageBox.Show(cfg.Title)
提示:发布时确认
bin\Debug(或当前配置)下存在 Newtonsoft.Json.dll。缺文件时运行会报找不到程序集。
XML · XmlSerializer
把对象写成 XML 字符串,或从字符串/文件读回。根元素名默认取类型名;可用 [XmlRoot] / [XmlElement] 调整。
| API / 特性 | 说明 |
|---|---|
XmlSerializer(Type) |
构造序列化器;首次创建可能稍慢(生成临时程序集) |
Serialize(TextWriter, object) |
对象 → XML 文本 |
Deserialize(TextReader) |
XML 文本 → 对象,再转型 |
[XmlRoot] / [XmlElement] / [XmlAttribute] |
控制根名、元素名、属性名(按需) |
C#
using System;
using System.IO;
using System.Text;
using System.Xml.Serialization;
public class AppConfig
{
public string Title { get; set; }
public int Count { get; set; }
}
public static class XmlHelper
{
public static string ToXml(AppConfig cfg)
{
XmlSerializer ser = new XmlSerializer(typeof(AppConfig));
StringBuilder sb = new StringBuilder();
using (StringWriter writer = new StringWriter(sb))
{
ser.Serialize(writer, cfg);
return sb.ToString();
}
}
public static AppConfig FromXml(string xml)
{
XmlSerializer ser = new XmlSerializer(typeof(AppConfig));
using (StringReader reader = new StringReader(xml))
{
return (AppConfig)ser.Deserialize(reader);
}
}
public static void SaveFile(string path, AppConfig cfg)
{
File.WriteAllText(path, ToXml(cfg), Encoding.UTF8);
}
public static AppConfig LoadFile(string path)
{
string xml = File.ReadAllText(path, Encoding.UTF8);
return FromXml(xml);
}
}
VB.NET
Imports System
Imports System.IO
Imports System.Text
Imports System.Xml.Serialization
Public Class AppConfig
Public Property Title As String
Public Property Count As Integer
End Class
Public Module XmlHelper
Public Function ToXml(cfg As AppConfig) As String
Dim ser As New XmlSerializer(GetType(AppConfig))
Dim sb As New StringBuilder()
Using writer As New StringWriter(sb)
ser.Serialize(writer, cfg)
Return sb.ToString()
End Using
End Function
Public Function FromXml(xml As String) As AppConfig
Dim ser As New XmlSerializer(GetType(AppConfig))
Using reader As New StringReader(xml)
Return CType(ser.Deserialize(reader), AppConfig)
End Using
End Function
Public Sub SaveFile(path As String, cfg As AppConfig)
File.WriteAllText(path, ToXml(cfg), Encoding.UTF8)
End Sub
Public Function LoadFile(path As String) As AppConfig
Dim xml As String = File.ReadAllText(path, Encoding.UTF8)
Return FromXml(xml)
End Function
End Module
注意与易错点
| 点 | 说明 |
|---|---|
| 编码 | 读写文件时统一 UTF-8(或与对端约定一致);中文乱码多半是编码不一致。 |
| DataContract 漏标 | 未标 [DataMember] 的属性不会出现在 JSON 里,反序列化后为默认值。 |
| XmlSerializer 约束 | 需要公共无参构造函数与可读写公共属性;接口、只读集合等常导致运行时异常。 |
| Newtonsoft 未复制 | 引用了 DLL 但「本地复制」为 False,或发布漏拷贝,运行时报找不到程序集。 |
| NuGet | LCode 主界面 NuGet暂不支持,待更新完善;第三方库一律浏览引用本地 DLL。 |
| C# 语言版本 | LCode / .NET 4.8 按 C# 5.0:勿用 $"…"、nameof、?. 等。 |