Controlling Namespace Prefixes in WCF XML Output

耗尽温柔 提交于 2020-01-02 07:11:14

问题


The current output of my WCF service is as follows (only a portion is shown below):

<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>

In the example, the "RowDetail" element is repeated for each US state.

I have two questions:

  1. How can I remove the "a:" prefix in the tags. I am assuming i need to change the xmlns setting, but I am not sure how to do this without throwing an error. I viewed other threads, but could not get it to work.

  2. Is it possible to remove the extraneous elements from the output, namely "Rows" and "Fields"? I understand why they are there - it is due to how I set up my classes (posted below), but it is messy to look at IMO.

Classes:

[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:


The issues here are as follows:

  1. You have some outer class corresponding to executeSelectSP2Response (not shown in your question) that is being placed in a default namespace "http://tempuri.org/" while being serialized. You probably don't want this since it is the test default namespace for ASP.Net Web Services and you are expected to replace it with a company-specific namespace.

    For instructions in replacing it, see here or here.

  2. The 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". This differs from the default namespace of their parent element so an override namespace must be specified. The a: prefixes refer to the xmlns:a="http://schemas.datacontract.org/2004/07/WCF_Services.DataContract" attribute and specifies that each element so tagged belongs in that namespace.

    If you want to specify that Results2Detail et. al. do not belong in a specific namespace (i.e. inherit their namespace from their parent) you can do:

    [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;
    }
    

    If you want a specific namespace, you can do [DataContract(Namespace = Namespaces.CompanyNameSpace)] where Namespaces is some static class like:

    public static class Namespaces
    {
        const string CompanyNameSpace = "http://company.namespace.org"; // or whatever.
    }
    
  3. Your question #2 is unclear. Are you saying you want your arrays to appear as a single level of elements rather than two nested levels of elements, i.e.:

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

    If so, then no, this level of control is not immediately possible with DataContractSerializer. You must either implement IXmlSerializable and do it manually, or switch to XmlSerializer and decorate your arrays with the XmlElement attribute.



来源:https://stackoverflow.com/questions/28198159/controlling-namespace-prefixes-in-wcf-xml-output

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!