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.FeedTypens2.FeedType

于 2012-11-13T16:35:37.747 に答える