您想要做的是将MyClass 的实例有条件地替换为serialization surrogate(即string 或字典),但是数据协定序列化不支持使用原语作为代理项,如解释的那样here 来自微软。
但是,由于您只需要序列化而不需要反序列化,因此您可以通过将 List<MyClass> 手动替换为代理 List<object> 来获得所需的输出,其中 MyClass 的实例在 @987654336 时被替换为字符串@ 为空,否则为 Dictionary<string, string>。然后手动construct 一个DataContractJsonSerializer 在DataContractJsonSerializerSettings 中使用以下值:
(请注意,DataContractJsonSerializerSettings、EmitTypeInformation 和 UseSimpleDictionaryFormat 都是 .NET 4.5 的新手。)
因此,您可以如下定义您的MyType:
public interface IHasSerializationSurrogate
{
object ToSerializationSurrogate();
}
public class MyClass : IHasSerializationSurrogate
{
public string foo;
public string bar;
// If you're not going to mark MyClass with data contract attributes, DataContractJsonSerializer
// requires a default constructor. It can be private.
MyClass() : this("", "") { }
public MyClass(string f, string b = "")
{
this.foo = f;
this.bar = b;
}
public object ToSerializationSurrogate()
{
if (string.IsNullOrEmpty(bar))
return foo;
return new Dictionary<string, string> { { foo, bar } };
}
}
然后介绍以下扩展方法:
public static partial class DataContractJsonSerializerHelper
{
public static string SerializeJsonSurrogateCollection<T>(this IEnumerable<T> collection) where T : IHasSerializationSurrogate
{
if (collection == null)
throw new ArgumentNullException();
var surrogate = collection.Select(i => i == null ? null : i.ToSerializationSurrogate()).ToList();
var settings = new DataContractJsonSerializerSettings
{
EmitTypeInformation = EmitTypeInformation.Never,
KnownTypes = surrogate.Where(s => s != null).Select(s => s.GetType()).Distinct().ToList(),
UseSimpleDictionaryFormat = true,
};
return DataContractJsonSerializerHelper.SerializeJson(surrogate, settings);
}
public static string SerializeJson<T>(this T obj, DataContractJsonSerializerSettings settings)
{
var type = obj == null ? typeof(T) : obj.GetType();
var serializer = new DataContractJsonSerializer(type, settings);
return SerializeJson<T>(obj, serializer);
}
public static string SerializeJson<T>(this T obj, DataContractJsonSerializer serializer = null)
{
serializer = serializer ?? new DataContractJsonSerializer(obj == null ? typeof(T) : obj.GetType());
using (var memory = new MemoryStream())
{
serializer.WriteObject(memory, obj);
memory.Seek(0, SeekOrigin.Begin);
using (var reader = new StreamReader(memory))
{
return reader.ReadToEnd();
}
}
}
}
并手动将您的列表序列化为 JSON,如下所示:
var json = list.SerializeJsonSurrogateCollection();
结果如下:
[{"foo":"bar"},"foo1",null,{"foo2":"bar2"}]
如果您确实需要对字符串进行转义(为什么?),您始终可以将结果字符串第二次序列化为 JSON,并使用DataContractJsonSerializer 生成双序列化结果:
var jsonOfJson = json.SerializeJson();
导致
"[{\"foo\":\"bar\"},\"foo1\",{\"foo2\":\"bar2\"}]"