This should be a relatively easy question I derped online for a while and still can't find a solution.
Right now my webapi returns an output like this
<Merchant>
<Cuisine xmlns:d3p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<d3p1:string>Japanese</d3p1:string>
<d3p1:string>Korean</d3p1:string>
<d3p1:string>French</d3p1:string>
</Cuisine>
</Merchant>
I want it to return like this
<Merchant>
<Cuisines>
<Cuisine>Japanese</Cuisine>
<Cuisine>Korean</Cuisine>
<Cuisine>French</Cuisine>
</Cuisines>
</Merchant>
What is the easiest way to accomplish such a task?
So basically there is two things I want to do
1)Get rid of the namespace xmlns:d3p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays"
2)change the name of outter element from
<Cuisine>
to
<Cuisines>
3)Change the name of inner element from
<d2p1:string>
to
<Cuisine>
And my datamember within the Merchant class is like this
[DataMember(EmitDefaultValue = false)]
public List<String> WebCuisine { get; set; }
Thank you in advnace
You have to use your own serializer.
Create a data structure
[XmlRoot("Merchant")]
public class Merchant
{
[XmlArray("Cuisines"), XmlArrayItem("Cuisine")]
public List<String> WebCuisine { get; set; }
}
Create a class inherited from XmlObjectSerializer
public class MerchantSerializer : XmlObjectSerializer
{
XmlSerializer serializer;
public MerchantSerializer()
{
this.serializer = new XmlSerializer(typeof(Merchant));
}
public override void WriteObject(XmlDictionaryWriter writer, object graph)
{
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", "");
serializer.Serialize(writer, graph, ns);
}
public override bool IsStartObject(XmlDictionaryReader reader)
{
throw new NotImplementedException();
}
public override object ReadObject(XmlDictionaryReader reader, bool verifyObjectName)
{
throw new NotImplementedException();
}
public override void WriteEndObject(XmlDictionaryWriter writer)
{
throw new NotImplementedException();
}
public override void WriteObjectContent(XmlDictionaryWriter writer, object graph)
{
throw new NotImplementedException();
}
public override void WriteStartObject(XmlDictionaryWriter writer, object graph)
{
throw new NotImplementedException();
}
}
As you can see I am only interested to write , but not to read. However, you can easy implement ReadObject if you need.
After in WebApiConfig in public static void Register(HttpConfiguration config)
you add
config.Formatters.XmlFormatter.SetSerializer<Merchant>(new MerchantSerializer());
And you should get
<Merchant>
<Cuisines>
<Cuisine>Japanese</Cuisine>
<Cuisine>Korean</Cuisine>
<Cuisine>French</Cuisine>
</Cuisines>
</Merchant>
I don't know if this will help anyone but I took the Merchant Serializer and modified it into a Generic Serializer
using System;
using System.Runtime.Serialization;
using System.Xml;
using System.Xml.Serialization;
namespace NoNamespaceXml
{
public class GenericSerializer : XmlObjectSerializer
{
#region Private Variables
private XmlSerializer serializer;
#endregion
#region Constructor
/// <summary>
/// Create a new instance of a GenericSerializer
/// </summary>
/// <param name="objectToSerialize"></param>
public GenericSerializer (object objectToSerialize)
{
// If the objectToSerialize object exists
if (objectToSerialize != null)
{
// Create the Serializer
this.Serializer = new XmlSerializer(objectToSerialize.GetType());
}
}
#endregion
#region Methods
#region IsStartObject(XmlDictionaryReader reader)
/// <summary>
/// This method Is Start Object
/// </summary>
public override bool IsStartObject(XmlDictionaryReader reader)
{
throw new NotImplementedException();
}
#endregion
#region ReadObject(XmlDictionaryReader reader, bool verifyObjectName)
/// <summary>
/// This method Read Object
/// </summary>
public override object ReadObject(XmlDictionaryReader reader, bool verifyObjectName)
{
throw new NotImplementedException();
}
#endregion
#region WriteEndObject(XmlDictionaryWriter writer)
/// <summary>
/// This method Write End Object
/// </summary>
public override void WriteEndObject(XmlDictionaryWriter writer)
{
throw new NotImplementedException();
}
#endregion
#region WriteObject(XmlDictionaryWriter writer, object graph)
/// <summary>
/// This method Write Object
/// </summary>
public override void WriteObject(XmlDictionaryWriter writer, object graph)
{
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", "");
serializer.Serialize(writer, graph, ns);
}
#endregion
#region WriteObjectContent(XmlDictionaryWriter writer, object graph)
/// <summary>
/// This method Write Object Content
/// </summary>
public override void WriteObjectContent(XmlDictionaryWriter writer, object graph)
{
throw new NotImplementedException();
}
#endregion
#region WriteStartObject(XmlDictionaryWriter writer, object graph)
/// <summary>
/// This method Write Start Object
/// </summary>
public override void WriteStartObject(XmlDictionaryWriter writer, object graph)
{
throw new NotImplementedException();
}
#endregion
#endregion
#region Properties
#region HasSerializer
/// <summary>
/// This property returns true if this object has a 'Serializer'.
/// </summary>
public bool HasSerializer
{
get
{
// initial value
bool hasSerializer = (this.Serializer != null);
// return value
return hasSerializer;
}
}
#endregion
#region Serializer
/// <summary>
// This property gets or sets the value for 'Serializer'.
/// </summary>
public XmlSerializer Serializer
{
get { return serializer; }
set { serializer = value; }
}
#endregion
#endregion
}
#endregion
}
Then all you have to do is register any types you want to use this serializser:
// Set the Serializer for certain objects
GlobalConfiguration.Configuration.Formatters.XmlFormatter.SetSerializer<NetworkSearchResponse>(serializer);
GlobalConfiguration.Configuration.Formatters.XmlFormatter.SetSerializer<SynxiBooleanResponse>(serializer);