如何使用转换器在另一个自定义转换器

时间:2017-07-19 08:33:43

标签: c# json.net

我有一个自定义JSON转换器,因为第三方API只接受特定结构。

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
{
   var bodyRequest = (IRequest) value;
   writer.WriteStartObject();
   writer.WritePropertyName(bodyRequest.RequestName);
   writer.WriteStartObject();
   writer.WritePropertyName("-xmlns");
   writer.WriteValue("http://example.com");
   writer.WritePropertyName(bodyRequest.WrapperName);
   writer.WriteStartObject();

   var contractResolver = new CamelCasePropertyNamesContractResolver {
    IgnoreSerializableAttribute = false
   };
   var properties = value.GetType().GetProperties();

   foreach(var propertyInfo in properties) {
    if (HasAttribute(propertyInfo, typeof(JsonIgnoreAttribute))) {
     continue;
    }
    var propValue = propertyInfo.GetValue(value);    
    var propertyName = contractResolver.GetResolvedPropertyName(propertyInfo.Name);
    writer.WritePropertyName(propertyName);
    writer.WriteValue(propValue);

   }
   writer.WriteEndObject();
   writer.WriteEndObject();
   writer.WriteEndObject();
}

所以,我在WriteXXX方法的帮助下创建了strcuture,然后我得到了所有属性并将它们序列化。一切正常,但我需要处理枚举。例如,我们有以下请求模型:

public class ExampleRequest : IRequest
{
   public long Id{ get; set; }

   [JsonConverter(typeof(StringEnumConverter))]
   public CarType CarType { get; set; }

   public string RequestName => "Request";
   public string WrapperName => "SendData";
}

public enum CarType
{
   [EnumMember(Value = "NEW_CAR")
   New,
   [EnumMember(Value = "OLD_CAR")
   Old
}

目前,在序列化之后,我发现CarType的数值为0或1,我知道我使用了反射而忽略了StringEnumConverter。在这种情况下如何正确序列化?

1 个答案:

答案 0 :(得分:1)

在循环中,检查属性是否已应用JsonConverterAttribute。如果是这样,获取转换器的类型,实例化它,然后调用其WriteJson方法而不是直接写入值。否则,只需按原样写入值。

换句话说,替换这一行:

writer.WriteValue(propValue);

用这个:

var att = propertyInfo.GetCustomAttribute<JsonConverterAttribute>();
if (att != null)
{
    var converter = (JsonConverter)Activator.CreateInstance(att.ConverterType);
    converter.WriteJson(writer, propValue, serializer);
}
else
{
    writer.WriteValue(propValue);
}