控制 WCF XML 输出中的命名空间前缀

Controlling Namespace Prefixes in WCF XML Output

我的WCF服务目前的输出如下(下面只展示了一部分):

<s:Body>
  <executeSelectSP2Response xmlns="http://tempuri.org/">
     <executeSelectSP2Result xmlns:a="http://schemas.datacontract.org/2004/07/WCF_Services.DataContract" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
        <a:Rows>
           <a:RowDetail>
              <a:Fields>
                 <a:FieldDetail>
                    <a:name>STATE_CD</a:name>
                    <a:value>1</a:value>
                 </a:FieldDetail>
                 <a:FieldDetail>
                    <a:name>STATE_CD_TXT</a:name>
                    <a:value>Alabama</a:value>
                 </a:FieldDetail>
                 <a:FieldDetail>
                    <a:name>STATE_CD_SHORT_TXT</a:name>
                    <a:value>AL</a:value>
                 </a:FieldDetail>
              </a:Fields>
           </a:RowDetail>

在示例中,"RowDetail" 元素针对美国的每个州重复。

我有两个问题:

  1. 如何删除标签中的 "a:" 前缀。我假设我需要更改 xmlns 设置,但我不确定如何在不引发错误的情况下执行此操作。我查看了其他线程,但无法正常运行。

  2. 是否可以从输出中删除多余的元素,即 "Rows" 和 "Fields"?我明白为什么他们在那里 - 这是由于我如何设置我的 类(在下面发布),但是看 IMO 很乱。

类:

[DataContract]
public class Results2Detail
{
    [DataMember]
    public RowDetail[] Rows;
}

[DataContract]
public class RowDetail
{
    [DataMember]
    public FieldDetail[] Fields;
}

[DataContract]
public class FieldDetail
{
    [DataMember]
    public String name;
    [DataMember]
    public String value;
}

这里的问题如下:

  1. 您有一些外部 class 对应于 executeSelectSP2Response (未在您的问题中显示),在序列化时被放置在默认名称空间 "http://tempuri.org/" 中。您可能不想要它,因为它是 test default namespace for ASP.Net Web Services 并且您应该将其替换为公司特定的命名空间。

    有关替换它的说明,请参阅 here or here

  2. DataContract attributes for the classes shown have no NameSpace property, so by default your classes are all to be serialized into the namespace "http://schemas.datacontract.org/2004/07/Clr.Namespace"。这与其父元素的默认命名空间不同,因此必须指定覆盖命名空间。 a: 前缀引用 xmlns:a="http://schemas.datacontract.org/2004/07/WCF_Services.DataContract" 属性并指定每个如此标记的元素属于该命名空间。

    如果要指定 Results2Detail 等。阿尔。不属于特定命名空间(即从其父级继承其命名空间),您可以这样做:

    [DataContract(Namespace="")]
    public class Results2Detail
    {
        [DataMember]
        public RowDetail[] Rows;
    }
    
    [DataContract(Namespace = "")]
    public class RowDetail
    {
        [DataMember]
        public FieldDetail[] Fields;
    }
    
    [DataContract(Namespace = "")]
    public class FieldDetail
    {
        [DataMember]
        public String name;
        [DataMember]
        public String value;
    }
    

    如果你想要一个特定的命名空间,你可以做 [DataContract(Namespace = Namespaces.CompanyNameSpace)] 其中 Namespaces 是一些静态的 class 比如:

    public static class Namespaces
    {
        const string CompanyNameSpace = "http://company.namespace.org"; // or whatever.
    }
    
  3. 您的问题 #2 不清楚。您是说您希望数组显示为单级元素而不是两级嵌套元素,即:

    <executeSelectSP2Result>
        <RowDetail>
            <FieldDetail>
            </FieldDetail>
        </RowDetail>
        <RowDetail>
            <FieldDetail>
            </FieldDetail>
        </RowDetail>
    </executeSelectSP2Result>
    

    如果是这样,那么不,DataContractSerializer 无法立即实现这种控制级别。您必须 implement IXmlSerializable and do it manually, or switch to XmlSerializer and decorate your arrays with the XmlElement 属性。