C#如何将SmtpData与Proxy类序列化为同层级JSON
解决方法
首先明确:你当前的SmtpData类仅定义了嵌套的Proxy类,但没有声明该类型的实例成员,所以序列化时自然不会包含Proxy相关字段。要实现扁平化JSON输出,需要先给SmtpData添加Proxy类型的实例属性,再通过以下两种方式实现字段平级:
方案一:匿名类组合(简单直接,无需复用序列化逻辑)
步骤1:修改SmtpData类,添加Proxy实例字段
public class SmtpData { public string id { get; set; } public string settingName { get; set; } public string host { get; set; } public int port { get; set; } public string username { get; set; } public string password { get; set; } public string senderName { get; set; } public string senderEmail { get; set; } public string senderMessageIdDomain { get; set; } public string senderReplyTo { get; set; } public string senderListUnsubscribe { get; set; } public bool isSecure { get; set; } public bool isUseProxy { get; set; } // 添加Proxy类型的实例字段,用于存储代理数据 public Proxy ProxySettings { get; set; } public class Proxy { public string proxyhost { get; set; } public int proxyport { get; set; } public string proxyusername { get; set; } public string proxypassword { get; set; } } }
步骤2:修改序列化代码,用匿名类合并所有字段
public void SaveSmtp(SmtpData data) { // 用匿名类将SmtpData和Proxy的字段合并到同一层级 var flattenedData = new { data.id, data.settingName, data.host, data.port, data.username, data.password, data.senderName, data.senderEmail, data.senderMessageIdDomain, data.senderReplyTo, data.senderListUnsubscribe, data.isSecure, data.isUseProxy, // 处理Proxy为null的情况,避免空引用异常 proxyhost = data.ProxySettings?.proxyhost, proxyport = data.ProxySettings?.proxyport ?? 0, proxyusername = data.ProxySettings?.proxyusername, proxypassword = data.ProxySettings?.proxypassword }; var dataJson = JsonConvert.SerializeObject(flattenedData); string resultPath = Path.Combine(Helpers.SmtpPath, $"{data.id}.conf"); File.WriteAllText(resultPath, dataJson); }
方案二:自定义ContractResolver(适合多次复用场景)
如果需要在多个地方复用扁平化序列化逻辑,可以自定义ContractResolver自动处理嵌套字段的扁平化:
步骤1:添加自定义ContractResolver
public class FlattenProxyContractResolver : DefaultContractResolver { protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) { var property = base.CreateProperty(member, memberSerialization); // 隐藏SmtpData的ProxySettings字段,不直接序列化它 if (member.DeclaringType == typeof(SmtpData) && member.Name == nameof(SmtpData.ProxySettings)) { property.ShouldSerialize = _ => false; } return property; } protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization) { var properties = base.CreateProperties(type, memberSerialization); // 为SmtpData添加Proxy类的所有属性,实现扁平化 if (type == typeof(SmtpData)) { var proxyProperties = base.CreateProperties(typeof(SmtpData.Proxy), memberSerialization); foreach (var proxyProp in proxyProperties) { var newProp = new JsonProperty { PropertyName = proxyProp.PropertyName, PropertyType = proxyProp.PropertyType, Readable = true, Writable = true, ValueProvider = new ProxyValueProvider(proxyProp.ValueProvider) }; properties.Add(newProp); } } return properties; } // 自定义值提供器,从ProxySettings中读取/设置字段值 private class ProxyValueProvider : IValueProvider { private readonly IValueProvider _proxyValueProvider; public ProxyValueProvider(IValueProvider proxyValueProvider) { _proxyValueProvider = proxyValueProvider; } public object GetValue(object target) { var smtpData = (SmtpData)target; if (smtpData.ProxySettings == null) { // Proxy为空时返回对应类型的默认值 return _proxyValueProvider.PropertyType.IsValueType ? Activator.CreateInstance(_proxyValueProvider.PropertyType) : null; } return _proxyValueProvider.GetValue(smtpData.ProxySettings); } public void SetValue(object target, object value) { var smtpData = (SmtpData)target; if (smtpData.ProxySettings == null) { smtpData.ProxySettings = new SmtpData.Proxy(); } _proxyValueProvider.SetValue(smtpData.ProxySettings, value); } } }
步骤2:修改序列化代码使用自定义Resolver
public void SaveSmtp(SmtpData data) { var jsonSettings = new JsonSerializerSettings { ContractResolver = new FlattenProxyContractResolver() }; var dataJson = JsonConvert.SerializeObject(data, jsonSettings); string resultPath = Path.Combine(Helpers.SmtpPath, $"{data.id}.conf"); File.WriteAllText(resultPath, dataJson); }
内容的提问来源于stack exchange,提问作者Oleg Buga
相关产品推荐
相关产品推荐

