2012-03-13 98 views
7

ServiceStack xml反序列化最简单的方法是xml包含名称空间。但是,我收到的XML不包含名称空间。最简单的工作示例:XML反序列化仅适用于xml中的名称空间

[Serializable] 
public class test 
{ 

} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     string xml="<test xmlns=\"http://schemas.datacontract.org/2004/07/\"></test>"; 
     var result = ServiceStack.Text.XmlSerializer.DeserializeFromString<test>(xml); 
    } 
} 

但是,那不是我想要的。我想下面的反序列化,因为这是XML我从几个服务获得:

string xml="<test></test>"; 

但是,这使我有以下错误:

DeserializeDataContract: Error converting type: Error in line 1 position 7. 
Expecting element 'test' from namespace 
'http://schemas.datacontract.org/2004/07/'.. 
Encountered 'Element' with name 'test', namespace ''. 

我想:

[Serializable] 
[XmlRoot("test", Namespace = "")] 
public class test 

我无法创建新的序列化程序,因为ServiceStack.Text.XmlSerializer是静态的。我需要选择Microsoft XmlSerializer或ServiceStack(不是两者)。意思是:如果我无法得到这个简单的例子,我需要跳过ServiceStack包中非常有用的部分。我想要的最后一件事是在传入的xml中注入一些虚拟名称空间。

回答

23

ServiceStack使用.NET的XML DataContractSerializer的序列化XML删除您需要或者命名空间设置为一个空字符串,命名空间:

[DataContract(Namespace="")] 
public class test { ... } 

但随后你必须标记你想用连载的每个属性[DataMember]属性。更好的选择是在你的Assembly.cs文件中添加和组装属性来指定一个C#命名空间下所有类型的一个空的命名空间,如:

[assembly: ContractNamespace("", ClrNamespace = "MyServiceModel.DtoTypes")] 

注意:您可以删除[Serializable]属性 - 它不被任何ServiceStack的序列化器使用。同样,所有XmlSerializer属性(如[XmlRoot])都是无用的,因为ServiceStack使用.NET的DataContractSerializer而不是Microsoft早期的XmlSerializer。

+0

谢谢!那是我需要的缺失链接!我以某种方式无法找到像ServiceStack这样的正确文档... – user1154148 2012-03-14 10:12:02

+0

您没有编写自己的XML解串器的任何原因?微软似乎只需要这种魔术酱配置就可以使它工作,而不像你的JSON串行器/解串器,它只是起作用。 – JasonD 2012-11-02 18:19:49

+0

@JasonD是的,我不喜欢没有理由的NIH'ing,我更喜欢不使用XML。 MS的XML DCS对于XML来说也是非常有效的,但它所需要的努力没有什么好处。 – mythz 2012-11-02 19:03:22