首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> ASP.NET 基礎

C# 透過 Microsoft.JScript 引擎解析 JSON:舊版相容方案與現代替代

     編輯:ASP.NET 基礎

歷史背景

.NET Framework 3.5 之前無內建 JSON 序列化器,常見做法有:

  • JavaScriptSerializer (System.Web.Extensions, 3.5 SP1)
  • DataContractJsonSerializer (System.Runtime.Serialization, 3.5)
  • 呼叫 JScript 引擎 eval() (本文方案)
  • 第三方 Json.NET (Newtonsoft.Json, 2006 年釋出)

本文方案:C# 託管 JScript Eval

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__ 等

現代標準替代方案 (強烈建議)

1. System.Text.Json (.NET Core 3.0+ / .NET 5+ 內建)

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);

2. Newtonsoft.Json (Json.NET) - 生態系最完整

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());

3. JavaScriptSerializer (ASP.NET 專案、無額外套件)

using System.Web.Script.Serialization;

var serializer = new JavaScriptSerializer();
var dict = serializer.Deserialize>>(json);
var names = dict["users"].Keys.ToArray();

效能基準參考 (簡單物件 1KB)

System.Text.Json        : ~ 0.02 ms
Newtonsoft.Json         : ~ 0.05 ms
JavaScriptSerializer    : ~ 0.15 ms
JScript Eval (本文)     : ~ 15 ms  (慢 1000 倍)

遷移清單

  1. 移除 Microsoft.JScript、Microsoft.Vsa 參考。
  2. 安裝 System.Text.Json (內建) 或 Newtonsoft.Json NuGet。
  3. 將 GetPropertyNames 改為 JsonDocument 或 JObject 解析。
  4. 補上單元測試覆蓋邊界案例 (空物件、巢狀、陣列、null、Unicode)。
  5. 移除舊版相容程式碼,減少攻擊面與維護成本。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved