0

我从不同的来源获取 json 格式的数据,并试图将它们映射到实现相同接口的对象。

json 变量在提要 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;}
}

在提要 2 中,对象如下所示:

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

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

编辑:

我像这样序列化它

            var serializer = new DataContractJsonSerializer(ClassA);

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

2 回答 2

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);
    }
}
于 2012-11-13T16:55:34.830 回答
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.FeedType或者ns2.FeedType

于 2012-11-13T16:35:37.747 回答