2009-06-03 49 views
49

我需要將JSON中表示的一些JavaScript對象反序列化爲適當的C#類。鑑於自動屬性的好處,我寧願讓它們在這些類中,而不是隻有字段。不幸的是,.NET序列化引擎(至少默認情況下)完全忽略了反序列化的自動屬性,而只關心後臺字段,這在JavaScript對象中顯然不存在。JSON的C#自動屬性反序列化

鑑於有no standard way to name backing fields,說實話,我甚至不想打擾「讓我們創建一個看起來像C#的支持字段的JavaScript對象」的方法,因爲它聽起來有點骯髒,唯一的辦法是我可以將JavaScript字段序列化爲C#自動屬性(如果我可以強制序列化引擎以某種方式忽略後備字段並直接使用該屬性)。不幸的是,我無法弄清楚這是如何完成的,或者是否可以完成。任何想法,將不勝感激。

編輯:下面是一個例子:

的Javascript:

function Cat() 
{ 
    this.Name = "Whiskers"; 
    this.Breed = "Tabby"; 
} 
var cat = new Cat(); 

然後,這是序列化到 「{名稱: '威威'}」。

C#的類:

[Serializable()] 
public class Cat 
{ 
    public string Name { get; set; } 
    public string Breed { get; set; } 
} 

和反序列化碼,即失敗:

new DataContractJsonSerializer(typeof(Cat)).ReadObject(inputStream); 

而且它是從異常顯而易見的是,因爲它正在尋找支持字段失敗。

EDIT2:這裏是例外,如果這能幫助(沒有內部異常):

System.Runtime.Serialization.SerializationException

「的數據合同類型 'Test.Cat' 不能因爲 所需的數據成員 '<Name>k__BackingField, <Breed>k__BackingField'不是 找到了。「

+0

你可以發表你的意思嗎? – 2009-06-03 16:09:03

+0

@John Saunders - 假設我有一個名爲「Cat」的JavaScript對象,其名稱爲「Name」,字段值爲「Whiskers」。假設這是用JSON表示的。我想抓住這個JSON並將其序列化爲C#Cat類的實例(由我編寫),以便序列化過程用「Whiskers」填充實例的自動屬性「Name」。 – 2009-06-03 16:11:45

+0

...但問題是序列化程序正在尋找後臺字段(例如「 k_backingField」,但不一定使用此名稱),而不是「名稱」 – 2009-06-03 16:14:04

回答

79

這裏發生了什麼是反串行器試圖猜測你的支持字段的名稱。 您可以通過添加顯式映射(DataContract /數據成員屬性)是這樣解決這個問題:

[DataContract] 
public class Cat 
{ 
    [DataMember] 
    public string Name { get; set; } 

    [DataMember] 
    public string Breed { get; set; } 
} 
20

您可以在System.Web.Script.Serialization命名空間中找到JavaScriptSerializer做到這一點:

JavaScriptSerializer serializer = new JavaScriptSerializer(); 
Cat c = serializer.Deserialize<Cat>(jsonString); 

我POCO自動對象的屬性,這工作得很好。

編輯:我寫了大約JSON Serializers in .NET比較這個序列化程序與DataContractJsonSerializer

1

我假設你通過Web服務傳遞數據。如果使用未註釋掉ScriptMethod屬性的WebService類,則Web服務方法可以本機讀取JSON。他們甚至使用上面提到的相同的JavaScriptSerializer。如果你使用WCF,我對邏輯更加模糊。

但請確保您的JSON對象正在爲您班級中的每個屬性返回數據。在你的錯誤中,提到了一個不屬於你的例子的品種屬性。

此外,在JavaScript方面,做到JavaScript的動態特性,很容易爲對象添加新的屬性。這有時會導致循環引用。您應該刪除您可能添加的任何額外數據(就像通過Web方法發送數據一樣,然後在完成後再添加)。

5

baretta's answer解決k__BackingField臃腫我。只是一個很小的附錄,你可以裝飾這個類來自動序列化到以類似的方式XML或JSON:

[Serializable, XmlRoot, DataContract] 
public class Cat 
{ 
    [XmlElement] 
    [DataMember] 
    public string Name { get; set; } 
    [XmlElement] 
    [DataMember] 
    public string Breed { get; set; } 
} 

...然後使用DataContractJsonSerializer或XmlSerializer的爲您的端點做準備。