Reputation: 1851
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
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
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
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:
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