12

I am getting the following response from a standard MVC 4 WebApi project;

<ArrayOfProduct xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Product>
<Id>1</Id>
<Name>Tomato Soup</Name>
<Category>Groceries</Category>
<Price>1</Price>
</Product>
</ArrayOfProduct>

I am trying to make it so that it returns

<Products>
<Product>
<Id>1</Id>
<Name>Tomato Soup</Name>
<Category>Groceries</Category>
<Price>1</Price>
</Product>
</Products>

I have found many reference to various methods that supposedly solve this, none work;

Changing the default serializer does not work.

Creating a customer serializer for Product does not work.

Creating a new class that has List<Product> exposed with suitable XmlRoot and XmlElement attributes does not work.

Adding Datacontract attributes does not work.

Adding CollectionDatacontract attributes does not work.

This appears to be so simple to everyone else, except me!

Maggie Ying
  • 10,095
  • 2
  • 33
  • 36
ChrisBint
  • 12,773
  • 6
  • 40
  • 62
  • Have you tried using the setting [shown in this SO question and answer](http://stackoverflow.com/questions/12263345/asp-net-web-api-xml-serialization-arrayof). Also, are you using the release version of the Web API? – Sixto Saez Oct 24 '12 at 19:52
  • Yes, tried that and yes, it is release version. – ChrisBint Oct 24 '12 at 19:54

1 Answers1

16

Try using the XmlSeriazlier instead:

config.Formatters.XmlFormatter.UseXmlSerializer = true;

And then try defining a class that derives from the collection of Product, and use [XmlRoot("Products")] to rename the element name from 'ArrayOfProduct' to 'Products'.

For example, instead of using List, use the class Products:

[XmlRoot("Products")]
public class Products : List<Product> { }

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Category { get; set; }
    public double Price { get; set; }
}

ApiController's action:

    public Products Get()
    {
        return new Products()
        {
            new Product() 
            {
                Id = 1,
                Name = "Tomato Soup", 
                Category = "Groceries",
                Price = 1
            }
        };
    }
Maggie Ying
  • 10,095
  • 2
  • 33
  • 36
  • Hi. Is there a way to to what you did but also change the `Product` xml element to something else? I cannot find a way to set the right attribute on the class to change the name... – Tallmaris Feb 20 '13 at 14:18
  • 2Tallmaris: use [DataContract] attribute to decorate a class or/and properties – Romko Apr 09 '13 at 08:31
  • 1
    What is `config` in your code? Do you mean `GlobalConfiguration.Configuration.Formatters.XmlFormatter.UseXmlSerializer = true;` ? – Patrick Szalapski Jan 27 '15 at 18:09
  • 1
    `config` is the argument that gets passed to method `Register(HttpConfiguration config)` in `App_Start/WebApiConfig`. – Genti Saliu Oct 20 '15 at 16:36
  • 2
    works good, still struggling to remove xmlns. xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" any idea? I tried [XmlRoot("Orders", Namespace=null)] that did not work – Shahdat Feb 01 '16 at 21:41
  • To remove namespace go here http://stackoverflow.com/questions/13860491/how-to-remove-namespace-from-web-api-response – Shahdat Feb 01 '16 at 21:58
  • In this way the help pages does no work anymore – Perry Nov 15 '21 at 08:18