简体   繁体   中英

C# WebAPI serialize a List of Strings

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.

  1. Create a data structure

     [XmlRoot("Merchant")] public class Merchant { [XmlArray("Cuisines"), XmlArrayItem("Cuisine")] public List<String> WebCuisine { get; set; } } 
  2. 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.

  1. 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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM