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

问题描述 投票:0回答:1

我的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 看来很混乱。

课程:

[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;
}
c# xml wcf automapper
1个回答
4
投票

这里的问题如下:

  1. 您有一些与

    executeSelectSP2Response
    相对应的外部类(在您的问题中未显示),在序列化时被放置在默认命名空间
    "http://tempuri.org/"
    中。 您可能不想要这个,因为它是 ASP.Net Web Services 的 测试默认命名空间 并且您需要将其替换为公司特定的命名空间。

    有关替换它的说明,请参阅如何从服务 WSDL 中消除 tempuri.orgWCF 服务命名空间(摆脱 tempuri.org)

  2. 所示类的

    DataContract
    属性没有
    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
    是一些静态类,例如:

    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
    无法立即实现这种级别的控制。 您必须 实现
    IXmlSerializable
    并手动执行,或者 切换到
    XmlSerializer
    并使用
    XmlElement
    属性装饰您的数组。

© www.soinside.com 2019 - 2024. All rights reserved.