【问题标题】:Controlling Namespace Prefixes in WCF XML Output控制 WCF XML 输出中的命名空间前缀
【发布时间】:2015-01-28 17:05:33
【问题描述】:

我的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】:

这里的问题如下:

  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"。这与其父元素的默认命名空间不同,因此必须指定覆盖命名空间。 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 无法立即实现此级别的控制。您必须要么 implement IXmlSerializable 手动完成,要么 switch to XmlSerializer 并使用 XmlElement 属性装饰您的数组。

【讨论】:

  • 非常感谢您的详细回答和相关链接。对于问题#2,这确实是我正在寻找的,抱歉不清楚。我将考虑为此使用 XmlSerializer - 我之前对此有一点经验。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-28
  • 2019-12-20
  • 1970-01-01
相关资源
最近更新 更多