2017-02-17 88 views
0

在我的API,我想给消费者发送属性作为一个字符串标识符或对象的选项,例如:基于JSON令牌类型有条件反序列化属性

{ 
    "source": "token_xyz" 
} 

或者

{ 
    "source": { 
     "name": "test" 
    } 
} 

根据类型(字符串或对象),我想设置我的类中的特定属性:

public class MyRequest 
{  
    [JsonProperty("source")] 
    public SourceUser SourceUser { get; set; } 

    [JsonProperty("source")] 
    public string SourceToken { get; set; } 
} 

正如你所看到的,我尝试用JsonProperty("source")装饰两个属性,但不幸的是这不起作用 - 对象无法反序列化。

如何反序列化到基于JSON类型的相应属性?

回答

1

Json.NET不支持具有相同的合同属性名的两个属性,可能是因为,在解释JSON RFC

他们的名字都是独特的是在这个意义上 所有互操作的对象接收该对象的软件实现将同意 名称 - 值映射。当一个对象中的名字不是唯一的时候,接收这样的对象的软件的行为是 不可预知的。

因此,您将需要某种custom JsonConverter来反序列化您的"source"属性。一个简单的方法做,这是转换器适用于私人Source属性,设置&得到任何SourceUserSourceToken酌情:

public class MyRequest 
{ 
    [JsonConverter(typeof(SourceConverter))] 
    [JsonProperty] 
    object Source 
    { 
     get 
     { 
      // Possibly throw an exception if both are non-null? 
      return SourceUser ?? (object)SourceToken; 
     } 
     set 
     { 
      SourceUser = value as SourceUser; 
      SourceToken = value as string; 
     } 
    } 

    [JsonIgnore] 
    public SourceUser SourceUser { get; set; } 

    [JsonIgnore] 
    public string SourceToken { get; set; } 
} 

class SourceConverter : JsonConverter 
{ 
    public override bool CanConvert(Type objectType) 
    { 
     throw new NotImplementedException("This converter is intended to be applied with [JsonConverter(typeof(SourceConverter))]"); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     if (reader.TokenType == JsonToken.Null) 
      return null; 
     else if (reader.TokenType == JsonToken.StartObject) 
      return serializer.Deserialize<SourceUser>(reader); 
     else 
      return (string)JValue.Load(reader); 
    } 

    public override bool CanWrite { get { return false; } } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     throw new NotImplementedException(); 
    } 
} 

样品fiddle

相关问题