如何从不同的来源解析json到枚举

时间:2012-11-13 16:15:52

标签: c# .net datacontractjsonserializer

我从不同来源获取json格式的数据,我正在尝试将它们映射到实现相同界面的对象。

json变量在feed 1中看起来像这样:

{"identifier": 232, "type": "Feed1"}

我正在使用这个对象序列化它:

   [DataContract]
    public class Class A : InterfaceA
    {

        [DataMember(Name = "identifier")]
        public int Id{ get; set; }

        [DataMember(Name = "type")]
        public FeedType Type { get; set; }
    }

    [DataContract]
    public enum FeedType
    {
        [EnumMember(Value = "Feed1")]
        FeedA,
        [EnumMember(Value = "Feed2")]
        FeedB,
        [EnumMember(Value = "Feed3")]
        FeedC
    }

界面如下所示:

public interface InterfaceA
{
   int Id {get;set;}
   FeedType Type{get;set;}
}

在Feed 2中,对象如下所示:

{"identifier": 232, "feedType": "A"}

如何创建另一个实现相同接口的对象并返回相同的枚举?如何设置DataContract?

编辑:

我像这样序列化

            var serializer = new DataContractJsonSerializer(ClassA);

            var ms = new MemoryStream(Encoding.Unicode.GetBytes(json));
            var serializedObject = serializer.ReadObject(ms);

2 个答案:

答案 0 :(得分:1)

我将使用Json.Net给出答案(当然,如果您愿意使用其他序列化程序)

string json = @"{""identifier"": 232, ""type"": ""Feed2""}";
var classa = JsonConvert.DeserializeObject<ClassA>(json);

public interface InterfaceA
{
    int Id { get; set; }
    FeedType Type { get; set; }
}

public class ClassA : InterfaceA
{
    [JsonProperty("identifier")]
    public int Id{ get; set; }

    [JsonConverter(typeof(MyConverter))] //<--- !!!
    [JsonProperty("type")]
    public FeedType Type { get; set; }
}

[DataContract]
public enum FeedType
{
    [EnumMember(Value = "Feed1")]
    FeedA,
    [EnumMember(Value = "Feed2")]
    FeedB,
    [EnumMember(Value = "Feed3")]
    FeedC
}

这是类型转换器类

public class MyConverter : Newtonsoft.Json.Converters.StringEnumConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(FeedType);
    }


    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var field = objectType.GetFields()
            .First(f => f.GetCustomAttributes(false)
                         .Any(a=>a.GetType()==typeof(EnumMemberAttribute) &&
                                 ((EnumMemberAttribute)a).Value.Equals(reader.Value))); 



        return field.GetValue(null);
    }
}

答案 1 :(得分:0)

所以如果你想要一个B级

[DataContract]
    public class ClassB : InterfaceA
    {

        [DataMember(Name = "identifier")]
        public int Id{ get; set; }

        [DataMember(Name = "type")]
        public FeedType Type { get; set; }
    }

var serializer = new DataContractJsonSerializer(ClassB);

            var ms = new MemoryStream(Encoding.Unicode.GetBytes(json));
            var serializedObject = serializer.ReadObject(ms);
那是吗?!如果你想重用代码,你可以使用泛型:

public T SerialiseObject<T>(string json) where T : InterfaceA
{
var serializer = new DataContractJsonSerializer(T);

var ms = new MemoryStream(Encoding.Unicode.GetBytes(json));
 return (T)serializer.ReadObject(ms);
}

然后调用它:

SerialiseObject<ClassA>(json);
SerialiseObject<ClassB>(json);

更全面地解释你没有

public class ClassA : InterfaceA
{
 public ns1.FeedType Type{get; set;}
}

public class ClassB : InterfaceA
{
  public ns2.FeedType Type{get; set;}
}

这不会编译,因为InterfaceA期望ns1.FeedTypens2.FeedType