2010-02-02 26 views
1

我正在使用REST端點編寫ASP.NET MVC 2站點。我想通過Rails Web應用程序中的ActiveResource使用此服務。Rails兼容.NET xml序列化

到目前爲止,我已經設法在ASP.NET MVC中獲得與ActiveResource約定相匹配的路由設置。但是,我遇到的問題是將ActiveResource發送給REST服務的數據反序列化。

似乎Rails的xml序列化與.NET完全不同(但我一直無法找到這些在任何地方記錄的約定)。例如,像這樣的.NET類:

public class Person 
{ 
    public string first_name { get; set; } 
    public string last_name { get; set; } 
    public bool active { get; set; } 
} 

這裏有一些差異:

  1. .NET序列化的根作爲<人>,而軌不<人>
  2. 。 NET添加命名空間,而軌道不
  3. .NET序列化屬性,如< first_name> rails does < first name>
  4. .NET序列化布爾作爲<活性>而導軌確實<活性類型=「布爾」>

數4似乎不會引起任何問題,但其他3原因.NET不反序列化消息。您可以通過使用XmlRoot和XmlElement屬性修飾對象來解決這些問題。但這是容易出錯和乏味的。

有誰知道一個更好的方式來反序列化.NET中已被序列化的Rails的ActiveResource的XML?

+0

'as rails while'是什麼意思?單詞的順序令我困惑。 – smaclell 2010-02-02 16:46:13

+0

對不起,我忘了逃避標籤,所以他們沒有出現。現在修復。 – 2010-02-02 17:25:27

回答

2

這可以使用XmlAttributeOverrides來實現。

下面是一個基本的例子,GetOverrides()是重要的部分:

public class RailsXmlSerializer 
{ 
    private Type type; 

    public RailsXmlSerializer(Type type) 
    { 
    this.type = type; 
    } 

    public void Serialize(Stream stream, object o) 
    { 
    XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); 
    ns.Add("", ""); 

    XmlSerializer xmlSerializer = new XmlSerializer(type, GetOverrides(type)); 
    xmlSerializer.Serialize(stream, o, ns); 
    } 

    public object Deserialize(Stream stream) 
    { 
    XmlSerializer xmlSerializer = new XmlSerializer(type, GetOverrides(type)); 
    return xmlSerializer.Deserialize(stream); 
    } 

    private XmlAttributeOverrides GetOverrides(Type type) 
    { 
    XmlAttributeOverrides overrides = new XmlAttributeOverrides(); 

    XmlAttributes classAttributes = new XmlAttributes(); 
    classAttributes.XmlType = new XmlTypeAttribute(type.Name.ToLower()); 
    overrides.Add(type, classAttributes); 

    foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(type)) 
    { 
     XmlAttributes propertyAttributes = new XmlAttributes(); 
     propertyAttributes.XmlElements.Add(new XmlElementAttribute(property.Name.ToLower().Replace('_', '-'))); 
     overrides.Add(type, property.Name, propertyAttributes); 
    } 

    return overrides; 
    } 
} 

顯然,這需要一個更強大的實施,可能爲一個裝飾,錯誤和類型檢查。當然,GetOverrides()也可以定製,以提供您想要的特定輸出。話雖這麼說,這裏給出一個樣本Person對象的輸出結果:給予此輸入

<?xml version="1.0" encoding="utf-16"?> 
<person> 
    <first-name>Jason</first-name> 
    <last-name>Bourne</last-name> 
    <active>true</active> 
</person> 

而且,還進行反序列化正確地提供合適的Person對象。

1

是的。

[XmlType("person", // issue #1 
    Namespace="")] // issue #2 
public class Person 
{ 
    [XmlElement("first-name")] // issue #3 
    public string first_name { get; set; } 

    [XmlElement("last-name")] // issue #3 
    public string last_name { get; set; } 

    public bool active { get; set; } 
} 
+0

我在問題中指出這種方法可行,但容易出錯且乏味。我正在尋找一種更好的方式,不需要每個物體都要裝飾。有任何想法嗎?謝謝。 – 2010-02-03 15:43:47

+0

您可以使用一個特殊的XmlSerializer實例化一個XmlAttributeOverrides對象。您必須動態構建XmlAttributeOverrides來處理下劃線到破折號的約定以及無用的約定。它將是任何類型對象的單個序列化程序類。 – Cheeso 2010-02-03 21:04:08