我最近遇到了这类问题,需要使用具有动态数据协定的 API,因此我开发了一个名为 SerializationInterceptor 的包。这是 GitHub 链接:https://github.com/Dorin-Mocan/SerializationInterceptor/wiki。您还可以使用 Nuget 包管理器安装包。
下面的示例使用 Newtonsoft.Json 进行序列化/反序列化。当然你可以使用任何其他工具,因为这个包不依赖任何工具。
你可以做的是创建一个拦截器:
public class JsonPropertyInterceptorAttribute : SerializationInterceptor.Attributes.InterceptorAttribute
{
public JsonPropertyInterceptorAttribute(string interceptorId)
: base(interceptorId, typeof(JsonPropertyAttribute))
{
}
protected override SerializationInterceptor.Attributes.AttributeBuilderParams Intercept(SerializationInterceptor.Attributes.AttributeBuilderParams originalAttributeBuilderParams)
{
object value;
switch (InterceptorId)
{
case "some id":
// For DESERIALIZATION you first need to deserialize the object here having the prop Source unmapped(we'll invoke the proper deserialization later to have Source prop mapped to the correct Json key),
// then get the value of the prop Type and assign it to variable from below.
// For SERIALIZATION you need somehow to have here access to the object you want to serialize and get
// the value of the Type prop and assign it to variable from below.
value = "the value of Type prop";
break;
default:
return originalAttributeBuilderParams;
}
originalAttributeBuilderParams.ConstructorArgs = new[] { value };
return originalAttributeBuilderParams;
}
}
然后将拦截器放在Source prop上:
public class MyRequest
{
[JsonProperty("type")]
public string Type { get; set; }
[JsonPropertyInterceptor("some id")]
[JsonProperty("source")]
public string Source { get; set; }
}
然后你像这样调用正确的序列化/反序列化:
var serializedObj = SerializationInterceptor.Interceptor.InterceptSerialization(obj, objType, (o, t) =>
{
var serializer = new JsonSerializer { ReferenceLoopHandling = ReferenceLoopHandling.Ignore };
using var stream = new MemoryStream();
using var streamWriter = new StreamWriter(stream);
using var jsonTextWriter = new JsonTextWriter(streamWriter);
serializer.Serialize(jsonTextWriter, o, t);
jsonTextWriter.Flush();
return Encoding.Default.GetString(stream.ToArray());
})
var deserializedObj = SerializationInterceptor.Interceptor.InterceptDeserialization(@string, objType, (s, t) =>
{
var serializer = new JsonSerializer();
using var streamReader = new StreamReader(s);
using var jsonTextReader = new JsonTextReader(streamReader);
return serializer.Deserialize(jsonTextReader, t);
});