以邮箱为对象键的JSON是否合法?能否通过Newtonsoft.Json序列化生成?
关于JSON结构的合理性
这种以业务字段作为对象键的JSON语法完全合法,实际开发中也有对应使用场景:如果消费端需要高频次根据邮箱检索用户信息,这种键值对结构的查找效率是O(1),远高于遍历数组的O(n),所以不能直接定义为"不合理"。
当然它的劣势也很明显:
- 强类型语言序列化、反序列化的成本比数组结构高
- 邮箱中如果存在特殊字符,部分解析器可能存在兼容问题
- 无法直接用统一的类结构映射所有用户字段,需要额外适配字典类型
关于Newtonsoft.Json生成对应结构的方案
完全不需要手动构造JSON,使用Dictionary<string, T>类型就可以直接实现该效果:Newtonsoft.Json序列化字典时,默认会将字典的Key作为JSON对象的属性名,字典的Value作为对应属性的值,正好匹配你需要的格式。
示例代码
首先定义对应的数据类:
// 用户地址类 public class MailingAddress { public string Street { get; set; } public string City { get; set; } public string State { get; set; } public string Zip { get; set; } } // 用户信息类 public class UserInfo { public string First_Name { get; set; } public string Last_Name { get; set; } public string Member_Id { get; set; } public MailingAddress Mailing_Address { get; set; } } // 报名信息类 public class Enrollment { public string Student { get; set; } public string Course_Ids { get; set; } } // 根对象类 public class ThirdPartyRequestDto { // 核心:用Dictionary承载用户集合,Key为邮箱,Value为用户信息 public Dictionary<string, UserInfo> users { get; set; } public List<Enrollment> enrollments { get; set; } }
构造数据并序列化:
var requestData = new ThirdPartyRequestDto { users = new Dictionary<string, UserInfo> { // 直接将邮箱作为字典的Key添加即可 { "example@company.com", new UserInfo { First_Name = "John", Last_Name = "Doe", Member_Id = "XX9008000", Mailing_Address = new MailingAddress { Street = "P O Box 111", City = "Red City", State = "CA", Zip = "99999" } } } }, enrollments = new List<Enrollment> { new Enrollment { Student = "example@company.com", Course_Ids = "369,370" } } }; // 直接序列化即可得到目标格式 string json = JsonConvert.SerializeObject(requestData, Formatting.Indented);
如果不想修改原有DTO结构(比如原有结构中users是带Email属性的List<UserInfo>),也可以自定义JsonConverter,在序列化阶段自动将列表转换为字典结构,不需要调整业务层代码。
内容的提问来源于stack exchange,提问作者joym8
相关产品推荐
相关产品推荐

