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

时间:2015-01-28 17:05:34

标签: c# xml wcf automapper

我的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. 是否可以从输出中删除无关元素,即“行”和“字段”?我明白为什么他们在那里 - 这是由于我如何设置我的课程(如下所示),但看看IMO是很麻烦。

  3. 类:

    [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 个答案:

答案 0 :(得分:4)

这里的问题如下:

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

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

  2. 显示的类的DataContract属性没有NameSpace属性,因此by default your classes are all to be serialized into the namespace "http://schemas.datacontract.org/2004/07/Clr.Namespace"。这与其父元素的默认命名空间不同,因此必须指定override命名空间。 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,其中public static class Namespaces { const string CompanyNameSpace = "http://company.namespace.org"; // or whatever. } 是一些静态类,如:

    <executeSelectSP2Result>
        <RowDetail>
            <FieldDetail>
            </FieldDetail>
        </RowDetail>
        <RowDetail>
            <FieldDetail>
            </FieldDetail>
        </RowDetail>
    </executeSelectSP2Result>
    
  3. 你的问题#2不清楚。你是说你希望你的数组显示为单个元素级别而不是两个嵌套级别的元素,即:

    DataContractSerializer

    如果是,那么不,{{1}}不能立即实现这种控制水平。您必须implement IXmlSerializable并手动执行,或switch to XmlSerializer并使用XmlElement属性修饰数组。