1

I have created an api that gives the output in form of xml. It is used to give sitemap for the website. It just includes the following code

public class SitemapApiController : ApiController
{
    public urlset GetSitemap()
    {
        // code for data access etc
        return urlsetObj;
    }
}

the urlset class is very simple

[XmlRoot("urlset")]
public class urlset: List<url>
{
}

the url class is as follows

public class url
{

    public string loc { get; set; }
    public DateTime lastmod { get; set; }        
    public double priority { get; set; }
}

Now my problem is that output is coming as

<arrayofurls>
         <url>.....

while i want it to be

<urlset>
     <url>....

I have read the similar posts for this, but to no relief. As stated in Modify the xml array element name in serialized ASP.NET WebAPI object post, if i use

[XmlArray("urlset")]

atribute over api controller, then it gives error that attribute "XmlArray" is not valid in this declaration type. Pls help me so that i can return valid sitemap from the api.

Edit
The output according to this is still a bit different. Now it shows

<urlset>
    <url>
        <url>
            <loc>
        <url>........ 

There is an extra needless url attribute as parent of all the url attributes.

Community
  • 1
  • 1
It's a trap
  • 1,333
  • 17
  • 39

1 Answers1

2

UPDATED

It took a little bit of work, but I believe I found what you are looking for.

A WebApi project should serialize XML using the namespace System.Runtime.Serialization, not the namespace System.Xml.Serialization.

Using this new serialization method, it becomes extremely simple to output the results exactly as you want.

The api controller GET method:

public urlset Get()
{
    return new urlset
    {
        new url { loc = "1" },
        new url { loc = "2" },
        new url { loc = "3" }
    };
}

The urlset class:

[CollectionDataContract(Name ="urlset", Namespace ="")]
public class urlset:List<url>
{
}

The url class:

[DataContract(Namespace = "")]
public class url
{
    [DataMember]
    public string loc { get; set; }
    [DataMember]
    public DateTime lastmod { get; set; }
    [DataMember]
    public double priority { get; set; }
}

The output:

<urlset xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <url>
        <lastmod>2016-10-19T08:07:28.6867397-07:00</lastmod>
        <loc>1</loc>
        <priority>0</priority>
    </url>
    <url>
        <lastmod>2016-10-15T08:07:28.6867397-07:00</lastmod>
        <loc>2</loc>
        <priority>0</priority>
    </url>
    <url>
        <lastmod>2016-09-20T08:07:28.6867397-07:00</lastmod>
        <loc>3</loc>
        <priority>0</priority>
    </url>
</urlset>

I realize the example you give in your question does not have the xmlns attribute in the root node. However, it seems there is no "easy" way to remove that.

Here are the resources I used to arrive at this solution:

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

MSDN: Collection Types in Data Contracts

Community
  • 1
  • 1
Shai Cohen
  • 6,074
  • 4
  • 31
  • 54
  • this is giving the same error "the xmlarray is not valid on this declaration type". – It's a trap Oct 16 '16 at 16:20
  • I apologize. I sent that out too quickly. Fixing the answer now. – Shai Cohen Oct 16 '16 at 17:28
  • Hi. the output is still a bit different from what i need. Pls check the edit which i made in the question. – It's a trap Oct 17 '16 at 15:31
  • Thanks sir. I am overwhelmed seeing that even after so many days, you tried so hard. Another thing i want to add is that i didn't want to get rid of "xmlns" attribute. I just didn't write it for the purpose of simplicity. – It's a trap Oct 22 '16 at 13:00
  • Great! Glad we finally found the solution. Yes, it was a challenge, but well worth it:) – Shai Cohen Oct 22 '16 at 16:08