.NET Framework 3.5 之前無內建 JSON 序列化器,常見做法有:
JavaScriptSerializer (System.Web.Extensions, 3.5 SP1)DataContractJsonSerializer (System.Runtime.Serialization, 3.5)eval() (本文方案)Json.NET (Newtonsoft.Json, 2006 年釋出)using Microsoft.JScript;
using Microsoft.JScript.Vsa;
using Microsoft.Vsa;
public static class LegacyJsonParser
{
public static string[] GetPropertyNames(string json, string rootProperty)
{
// 組裝 JS 程式碼:function handleJson() { var j = ; var arr=[]; for(var k in j.rootProperty) arr.push(k); return arr; } handleJson();
string jsCode = $@"
function handleJson() {{
var j = {json};
var arr = [];
for (var k in j.{rootProperty}) arr.push(k);
return arr;
}}
handleJson();";
var engine = VsaEngine.CreateEngine();
object result = Eval.JScriptEvaluate(jsCode, engine);
// 結果為 JScript ArrayObject
var arr = (ArrayObject)result;
var list = new List();
for (int i = 0; i < (int)arr.length; i++)
list.Add(arr[i].ToString());
return list.ToArray();
}
}
string json = "{\"users\":{\"alice\":25,\"bob\":30,\"charlie\":35}}";
string[] names = LegacyJsonParser.GetPropertyNames(json, "users");
// names = ["alice", "bob", "charlie"]
| 問題 | 影響 |
|---|---|
| 需參考 Microsoft.JScript.dll | 非標準組件、部署麻煩、.NET Core 不支援 |
| 效能極差 | 每次呼叫建立 VsaEngine、編譯 JS、跨界封送 |
| 安全性風險 | JSON 字串若含惡意代碼可能被執行 (雖然僅 eval 物件字面值) |
| 錯誤處理困難 | JS 語法錯誤拋出 COMException,難以對應原始 JSON 位置 |
| 不支援現代 JSON 特性 | DateTime、Unicode、大數字、__proto__ 等 |
using System.Text.Json;
var doc = JsonDocument.Parse(json);
var names = doc.RootElement.GetProperty("users").EnumerateObject().Select(p => p.Name).ToArray();
// 或強型別
var users = JsonSerializer.Deserialize>(json);
using Newtonsoft.Json.Linq;
var jobj = JObject.Parse(json);
var names = jobj["users"].Children().Select(p => p.Name).ToArray();
// 或
var users = JsonConvert.DeserializeObject>(jobj["users"].ToString());
using System.Web.Script.Serialization;
var serializer = new JavaScriptSerializer();
var dict = serializer.Deserialize>>(json);
var names = dict["users"].Keys.ToArray();
System.Text.Json : ~ 0.02 ms Newtonsoft.Json : ~ 0.05 ms JavaScriptSerializer : ~ 0.15 ms JScript Eval (本文) : ~ 15 ms (慢 1000 倍)
Microsoft.JScript、Microsoft.Vsa 參考。System.Text.Json (內建) 或 Newtonsoft.Json NuGet。GetPropertyNames 改為 JsonDocument 或 JObject 解析。