如何使用.NET解析jQuery编码的复杂URL参数为JSON对象
在.NET中解析jQuery编码的GET请求URL参数为JSON对象
刚好之前处理过类似的场景:jQuery的$.get方法发送复杂JSON对象时,会自动把嵌套结构、数组转成带方括号的URL参数格式,比如你给出的那种BillingSession[InvoiceDate]、invoices[]的形式。在.NET里其实有两种简单的方式来解析成对应的JSON对象,我给你详细说说:
方法一:利用ASP.NET模型绑定(最省心)
如果你是在ASP.NET MVC或者ASP.NET Core项目里,直接用模型绑定是最简单的方案——.NET的Web框架原生支持这种jQuery风格的参数格式,会自动帮你把URL参数映射到对应的实体类对象上。
步骤1:定义匹配参数结构的实体类
先根据你的参数结构创建对应的C#类:
// 嵌套的BillingSession对象 public class BillingSession { public DateTime InvoiceDate { get; set; } public string TestKey { get; set; } // 注意属性名和参数的testKey大小写对应,或用[JsonPropertyName]指定 } // 整体请求模型 public class RequestParamsModel { public BillingSession BillingSession { get; set; } public List<string> Invoices { get; set; } public string SessionDiary { get; set; } }
如果是ASP.NET Core,默认区分属性名和参数名的大小写,你可以在配置里开启PropertyNameCaseInsensitive = true,或者用[JsonPropertyName("testKey")]特性指定对应参数名。
步骤2:在控制器Action中直接使用模型作为参数
在你的API或MVC控制器里,直接把定义好的模型作为Action的参数,框架会自动完成绑定:
using Microsoft.AspNetCore.Mvc; using System.Text.Json; [ApiController] [Route("[controller]")] public class DemoController : ControllerBase { [HttpGet("url")] public IActionResult ParseParams(RequestParamsModel model) { // 此时model已经包含了URL里的所有参数值 // 如果需要转成JSON字符串,直接用JsonSerializer序列化即可 string jsonResult = JsonSerializer.Serialize(model); return Ok(jsonResult); } }
这样请求过来后,你拿到的model就是完全映射好的对象,直接使用或者转成JSON都很方便。
方法二:手动解析QueryString并转换为JSON(适合非Web场景)
如果你是在非Web环境(比如控制台程序、桌面应用)里需要解析这种URL参数,或者不想用模型绑定,可以手动解析QueryString,然后构建嵌套的字典结构,最后序列化为JSON。
实现代码示例
using System.Collections.Generic; using System.Text.Json; using System.Web; // ASP.NET框架用这个;如果是ASP.NET Core,用Microsoft.AspNetCore.WebUtilities.QueryHelpers public static class QueryParser { public static string ParseQueryToJson(string queryString) { var nestedDict = new Dictionary<string, object>(); // 解析QueryString为键值对集合 var queryParams = HttpUtility.ParseQueryString(queryString); foreach (string key in queryParams.AllKeys) { string value = queryParams[key]; ParseKeyIntoNestedDict(key, value, nestedDict); } // 把嵌套字典序列化为JSON字符串 return JsonSerializer.Serialize(nestedDict, new JsonSerializerOptions { WriteIndented = true }); } private static void ParseKeyIntoNestedDict(string key, string value, Dictionary<string, object> currentDict) { // 如果是普通键(不带方括号),直接加入字典 if (!key.Contains('[')) { currentDict[key] = value; return; } // 拆分带方括号的键,比如"BillingSession[InvoiceDate]"拆分成["BillingSession", "InvoiceDate"] var keyParts = key.Split(new[] { '[', ']' }, StringSplitOptions.RemoveEmptyEntries); var tempDict = currentDict; for (int i = 0; i < keyParts.Length; i++) { string part = keyParts[i]; // 处理数组项,比如"invoices[]"的情况 if (i == keyParts.Length - 1 && string.IsNullOrEmpty(part)) { string arrayKey = keyParts[i - 1]; // 如果字典里还没有这个数组,先创建列表 if (!tempDict.ContainsKey(arrayKey)) { tempDict[arrayKey] = new List<string>(); } ((List<string>)tempDict[arrayKey]).Add(value); return; } // 处理嵌套对象的层级 if (!tempDict.ContainsKey(part)) { tempDict[part] = new Dictionary<string, object>(); } tempDict = (Dictionary<string, object>)tempDict[part]; } // 最后一层的键值对 tempDict[keyParts[^1]] = value; } } // 使用示例 string queryString = "BillingSession%5BInvoiceDate%5D=2018-04-18T00%3A00%3A00.000&BillingSession%5BtestKey%5D=testVal&invoices%5B%5D=one&invoices%5B%5D=two&SessionDiary=diarynum"; string jsonOutput = QueryParser.ParseQueryToJson(queryString); Console.WriteLine(jsonOutput);
这段代码会把QueryString解析成嵌套字典,然后序列化成格式化好的JSON字符串,输出结果和你最初的opts对象结构一致。
内容的提问来源于stack exchange,提问作者Mark Nadig
相关产品推荐
相关产品推荐

