2012-11-13 28 views
0

我從不同來源獲取json格式的數據,並試圖將它們映射到實現相同接口的對象。如何解析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;} 
} 

在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); 
+0

第一件事情,你不能創建接口的實例,所以你需要創建一個實際的類的實例,你有沒有想過使用一個通用的方法? – Liam

+0

您是否可以在其中包含實際將Json分流的代碼? – Liam

+0

@Liam我曾考慮泛型類型。但我希望它是相同類型的枚舉。 – johan

回答

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); 
    } 
} 
+0

完全如此,但我寧願不必swith串行器 – johan

+0

@johan正如你可以看到它比其他序列化器更能控制序列化/反序列化過程。 (BTW MVC4也使用它)。 –

+1

那麼,因爲我沒有得到任何其他答案,我想是最好的解決方案。謝謝 – johan

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

+0

謝謝,但我不認爲這回答我的問題。這將如何序列化第二個json響應中的「feedType」正確的枚舉? – johan

+0

FeedType在兩者中都是相同的類型?它需要是否會破壞接口聲明? – Liam

+0

我完全理解。但你的解決方案不會像JSON看起來不同。如果接口使用泛型類型,那麼您解釋爲不是函數解決方案將會起作用。 – johan