C#中如何在单个字段映射string与string数组类型并使用单个DTO处理请求
可以使用单个DTO同时适配两类请求,以下是兼容DataContractSerializer的实现方案,无需依赖Newtonsoft.Json的Converter:
1. 定义兼容DTO结构
首先定义符合DataContract序列化规范的DTO类,Value属性声明为object类型以适配两种数据结构,同时新增辅助属性简化业务层调用:
using System.Collections.Generic; using System.Runtime.Serialization; [DataContract] public class OperationRequest { [DataMember(Name = "Operations")] public List<OperationItem> Operations { get; set; } } [DataContract] public class OperationItem { [DataMember(Name = "op")] public string Op { get; set; } [DataMember(Name = "path")] public string Path { get; set; } [DataMember(Name = "value")] public object Value { get; set; } /// 辅助属性:获取字符串类型的Value值 public string StringValue => Value as string; /// 辅助属性:获取数组类型的Value集合 public List<MemberValueItem> ArrayValue => Value as List<MemberValueItem>; /// 辅助判断:当前Value是否为字符串类型 public bool IsStringType => Value is string; /// 辅助判断:当前Value是否为数组类型 public bool IsArrayType => Value is List<MemberValueItem>; } [DataContract] public class MemberValueItem { [DataMember(Name = "value")] public string Value { get; set; } }
2. 反序列化配置
如果使用System.Text.Json作为序列化器(天然兼容DataContract注解规则),添加如下配置即可正常反序列化两类请求:
using System.Text.Json; using System.Text.Json.Serialization; var deserializeOptions = new JsonSerializerOptions { PropertyNameCaseInsensitive = true, Converters = { new JsonStringEnumConverter() } }; // 直接反序列化即可兼容两种结构 var request = JsonSerializer.Deserialize<OperationRequest>(requestJson, deserializeOptions);
如果是WCF场景下使用原生DataContractSerializer处理JSON请求,只需开启AllowNonSerializableTypes配置即可正常解析。
3. 业务逻辑调用示例
foreach (var operation in request.Operations) { if (operation.IsStringType) { // 处理字符串Value场景,例如替换displayName var updateValue = operation.StringValue; // 后续业务逻辑 } else if (operation.IsArrayType) { // 处理数组Value场景,例如移除成员 foreach (var memberItem in operation.ArrayValue) { var memberId = memberItem.Value; // 后续业务逻辑 } } }
方案说明
- 完全兼容DataContractSerializer规范,不会产生兼容性冲突
- 无需拆分多个DTO结构,同一套模型即可适配两类请求
- 辅助属性封装了类型转换逻辑,降低业务层代码冗余
内容的提问来源于stack exchange,提问作者Ashish Vishwakarma
相关产品推荐
相关产品推荐

