Karthik Bammidi
Karthik Bammidi

Reputation: 1851

How to serialize xml into desired format in asp.net web api

I am working on asp.net mvc 4 web api. I have a class like,

public class Quiz
{
public int QuizId{get; set;}
public string title{get; set;}
...
...
}

and now i am trying to retrieve list of quizs so i wrote like,

public List<Quiz> GetQuizs()
{
return repository.ListQuizs();
}

i need xml response so i have made configuration in webapi.config file like,

config.Formatters.XmlFormatter.UseXmlSerializer = true;

and i got a response like,

<ArrayOfQuiz xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Quiz>
<QuizId>4</QuizId>
<title>Master Minds</title>
</Quiz>
<Quiz>
<QuizId>5</QuizId>
<title>Master Minds</title>
</Quiz>
</ArrayOfQuiz>

but i want the response like

<Quizs>
<Quiz>
<QuizId>4</QuizId>
<title>Master Minds</title>
</Quiz>
<Quiz>
<QuizId>5</QuizId>
<title>Master Minds</title>
</Quiz>
</Quiz>

i have tried like,

public class quizs:List<Quiz>{}
public class Quiz
{
//properties here
}

but i am unable to load list of quizs into quizs class. please guide me.

Upvotes: 3

Views: 12599

Answers (3)

Pitchai P
Pitchai P

Reputation: 1317

You can remove the namespace. Just create a CustomXmlFormatter to remove the namespace from the root element.

public class IgnoreNamespacesXmlMediaTypeFormatter : XmlMediaTypeFormatter
{
public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)
{
    try
    {
        var task = Task.Factory.StartNew(() =>
        {
            var xns = new XmlSerializerNamespaces();
            var serializer = new XmlSerializer(type);
            xns.Add(string.Empty, string.Empty);
            serializer.Serialize(writeStream, value, xns);
        });

        return task;
    }
    catch (Exception)
    {
        return base.WriteToStreamAsync(type, value, writeStream, content, transportContext);
    }
}
}

Upvotes: 3

Darrel Miller
Darrel Miller

Reputation: 142014

Create a class called QuizList and implement IXmlSerializable and you can define exactly how you want your XML to look.

IMHO it is a really bad idea to expose wire formats that are dependent on the internal implementations of a .Net type serializer. The whole idea of serializers is that when you want to deserialize the object you need to have the same serializer library and the same types available to reconstitute the object. What happens if your client isn't on the .net platform?

Upvotes: 2

Mark Jones
Mark Jones

Reputation: 12184

Is there any reason why you are using the XmlSerializer over the DataContract serialiszer?

If not you can achieve what you want like so:

  1. Remove config.Formatters.XmlFormatter.UseXmlSerializer = true; from your config
  2. Add a reference to System.Runtime.Serialisation
  3. Declare your class and controller

Code

[DataContract(Namespace = "")]
public class Quiz
{
    [DataMember]
    public int QuizId { get; set; }
    [DataMember(Name = "title")]
    public string Title { get; set; }
}

[CollectionDataContract(Name = "Quizs", Namespace = "")]
public class QuizCollection : List<Quiz>
{
}

public class QuizsController : ApiController
{
    public QuizCollection Get()
    {
        return new QuizCollection
                       {
                           new Quiz {QuizId = 4, Title = "Master Minds"},
                           new Quiz {QuizId = 5, Title = "Another Title"}
                       };
    }
}

Finally call your service using the html header "accept : application/xml"

And your result should be like:

<Quizs xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <Quiz>
        <QuizId>4</QuizId>
        <title>Master Minds</title>
        </Quiz>
    <Quiz>
        <QuizId>5</QuizId>
        <title>Another Title</title>
    </Quiz>
</Quizs>

Regarding your namespaces NB. how they are set to namespace = "" in attributes to remove them. You are going to strugle to remove xmlns:i="http://www.w3.org/2001/XMLSchema-instance" it needs to be there to allow the XML to handle null values.

For more information on the datacontract serializers support for collections see here

Upvotes: 10

Related Questions