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:
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.
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;
}
The issues here are as follows:
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.The
DataContract
attributes for the classes shown have noNameSpace
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. Thea:
prefixes refer to thexmlns: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)]
whereNamespaces
is some static class like:public static class Namespaces { const string CompanyNameSpace = "http://company.namespace.org"; // or whatever. }
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 implementIXmlSerializable
and do it manually, or switch toXmlSerializer
and decorate your arrays with theXmlElement
attribute.
来源:https://stackoverflow.com/questions/28198159/controlling-namespace-prefixes-in-wcf-xml-output