【问题标题】:XML deserializing only works with namespace in xmlXML 反序列化仅适用于 xml 中的命名空间
【发布时间】:2012-03-30 04:32:14
【问题描述】:

让 ServiceStack 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 中注入一些虚拟命名空间。

【问题讨论】:

    标签: c# namespaces servicestack xmlserializer


    【解决方案1】:

    ServiceStack 使用 .NET 的 Xml DataContractSerializer 来序列化 XML 以删除命名空间,您需要将命名空间设置为空字符串:

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

    但是,您必须使用 [DataMember] 属性标记要序列化的每个属性。更好的选择是通过在 Assembly.cs 文件中添加和 Assembly 属性来为 C# 命名空间下的所有类型指定一个空命名空间,例如:

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

    注意:您可以删除 [Serializable] 属性 - ServiceStack 的任何序列化程序都不会使用它。此外,像 [XmlRoot] 这样的所有 XmlSerializer 属性都是无用的,因为 ServiceStack 使用 .NET 的 DataContractSerializer 而不是 Microsoft 早期的 XmlSerializer。

    【讨论】:

    • 您没有编写自己的 XML 反序列化器的任何原因?微软似乎只需要这种类型的魔法酱配置来使其工作,不像你的 JSON 序列化器/反序列化器,它可以工作。
    • @JasonD 是的,我不喜欢没有充分理由的 NIH,而且我不喜欢使用 XML。 MS 的 XML DCS 对 XML 也有很好的性能,但它所需要的工作量几乎没有什么好处。
    猜你喜欢
    • 1970-01-01
    • 2013-05-02
    • 2015-11-03
    • 2021-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-17
    相关资源
    最近更新 更多