Problem:
Whenever
we try to return list of an object from API we get an xml response where root
element is ArrayOfYourObjectName that we like to be some plural
form of our object name e.g. if our object name is Student then generated xml’s
root element’s name should be Students instead of ArrayOfStudent.
Emulating the problem:
We will first create a
table for purpose of illustration as follows
CREATE TABLE [dbo].[MyTable] (
[Id]
INT IDENTITY (1, 1) NOT NULL,
[Name]
VARCHAR
(100) NOT NULL,
[Email]
VARCHAR
(100) NOT NULL,
[Gender] CHAR (1) NULL,
[Phone]
VARCHAR
(20) NULL,
PRIMARY KEY CLUSTERED ([Id] ASC)
);
Add some dummy entries in table.
Now into our MVC web API project add a new class file and
create a class as follows
public class Employee
{
private string _gender;
[Display(Name = "Employee Id")]
public int Id{get;set;}
[Display(Name = "Name")]
[Required]
[StringLength(100)]
public string Name{get;set;}
[Display(Name = "Email")]
[Required]
[StringLength(100)]
public string Email{get;set;}
[StringLength(20)]
public string Phone{get;set;}
public string Gender{
get
{
return _gender;
}
set
{
switch (value)
{
case "M":
_gender = "Male";
break;
case "F":
_gender = "Female";
break;
default:
_gender = "Not
Disclosed";
break;
}
}
}
}
public
class Employees : List<Employee>
{
}
Now add Entity model with name say MyDatabaseEntities
go to Value Controller which usually created by default
and edit get method to resemble below
public Employees Get()
{
List<Employee> d =(from m in new MyDatabaseEntities().MyTables
select new Employee() { Id = m.Id, Name
= m.Name, Email = m.Email, Phone = m.Phone, Gender = m.Gender }).ToList<Employee>();
Employees dd = new Employees();
dd.AddRange(d);
return dd;
}
Now run the application and visit api/values result will be like
<ArrayOfEmployee xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/MvcApplication1.Models">
<Employee>
<Email>surendra@gmail.com</Email>
<Gender>Male</Gender>
<Id>3</Id>
<Name>surendra</Name>
<Phone>9890968645</Phone>
</Employee>
<Employee>
<Email>rajendra@gmail.com</Email>
<Gender>Male</Gender>
<Id>4</Id>
<Name>rajendra</Name>
<Phone>9890964645</Phone>
</Employee>
<Employee>
<Email>sunidhi@gmail.com</Email>
<Gender>Female</Gender>
<Id>5</Id>
<Name>sunidhi</Name>
<Phone>9890564645</Phone>
</Employee>
<Employee>
<Email>nidhi@gmail.com</Email>
<Gender>Female</Gender>
<Id>6</Id>
<Name>nidhi</Name>
<Phone>9880564645</Phone>
</Employee>
<Employee>
<Email>shirin@gmail.com</Email>
<Gender>Female</Gender>
<Id>7</Id>
<Name>shirin</Name>
<Phone>9880464645</Phone>
</Employee>
<Employee>
<Email>nilima@gmail.com</Email>
<Gender>Female</Gender>
<Id>8</Id>
<Name>nilima</Name>
<Phone>9680464645</Phone>
</Employee>
</ArrayOfEmployee>
The XML response we got has root element ArrayOfEmployee which
might be undesired behavior.
You will get similar response on below variant of our api action
public LIST<Employee> Get()
{
List<Employee> d =(from m in new MyDatabaseEntities().MyTables
select new Employee() { Id = m.Id, Name
= m.Name, Email = m.Email, Phone = m.Phone, Gender = m.Gender }).ToList<Employee>();
return d;
}
Objective:
Our aim is to replace ArrayOfEmployee root
element name by more suitable name say Employees.
Solution:
MVC uses DataContractSerializer for
serializing data since version 4.0 and for earlier version XmlSerializer .
If using MVC 4.0 or
latter change employees class as
[CollectionDataContract(Name = " Employees", ItemName = " Employee")]
public class Employees : List<Employee>
{
}
Now visit api/values it will call our get action and
result will be
<Employees xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/MvcApplication1.Models">
<Employee>
<Email>jitendra@gmail.com</Email>
<Gender>Male</Gender>
<Id>2</Id>
<Name>jitendra</Name>
<Phone>9890868645</Phone>
</Employee>
<Employee>
<Email>surendra@gmail.com</Email>
<Gender>Male</Gender>
<Id>3</Id>
<Name>surendra</Name>
<Phone>9890968645</Phone>
</Employee>
<Employee>
<Email>rajendra@gmail.com</Email>
<Gender>Male</Gender>
<Id>4</Id>
<Name>rajendra</Name>
<Phone>9890964645</Phone>
</Employee>
<Employee>
<Email>sunidhi@gmail.com</Email>
<Gender>Female</Gender>
<Id>5</Id>
<Name>sunidhi</Name>
<Phone>9890564645</Phone>
</Employee>
<Employee>
<Email>nidhi@gmail.com</Email>
<Gender>Female</Gender>
<Id>6</Id>
<Name>nidhi</Name>
<Phone>9880564645</Phone>
</Employee>
<Employee>
<Email>shirin@gmail.com</Email>
<Gender>Female</Gender>
<Id>7</Id>
<Name>shirin</Name>
<Phone>9880464645</Phone>
</Employee>
<Employee>
<Email>nilima@gmail.com</Email>
<Gender>Female</Gender>
<Id>8</Id>
<Name>nilima</Name>
<Phone>9680464645</Phone>
</Employee>
</Employees>
If MVC version is less than 4.0 then go to configuration (WebAPiConfig.cs)
and add line
config.Formatters.XmlFormatter.UseXmlSerializer
= true;
which means xml serialization is done using legacy xml Serializer
change our employees class as
[XmlRoot("Employees")]
//[CollectionDataContract(Name
= "Employees", ItemName = "Employee")]
public class Employees : List<Employee>
{
}
This will set root element name to “Employees” whenever object of
this class is serialized into xml.
Now visit /Api/Values resultant xml will be
<Employees xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Employee>
<Id>3</Id>
<Name>surendra</Name>
<Email>surendra@gmail.com</Email>
<Phone>9890968645</Phone>
<Gender>Male</Gender>
</Employee>
<Employee>
<Id>4</Id>
<Name>rajendra</Name>
<Email>rajendra@gmail.com</Email>
<Phone>9890964645</Phone>
<Gender>Male</Gender>
</Employee>
<Employee>
<Id>5</Id>
<Name>sunidhi</Name>
<Email>sunidhi@gmail.com</Email>
<Phone>9890564645</Phone>
<Gender>Female</Gender>
</Employee>
<Employee>
<Id>6</Id>
<Name>nidhi</Name>
<Email>nidhi@gmail.com</Email>
<Phone>9880564645</Phone>
<Gender>Female</Gender>
</Employee>
<Employee>
<Id>7</Id>
<Name>shirin</Name>
<Email>shirin@gmail.com</Email>
<Phone>9880464645</Phone>
<Gender>Female</Gender>
</Employee>
<Employee>
<Id>8</Id>
<Name>nilima</Name>
<Email>nilima@gmail.com</Email>
<Phone>9680464645</Phone>
<Gender>Female</Gender>
</Employee>
</Employees>
As desired
result is similar ,difference in xml is minor; checkout where xml varies own
yourself, though it will not make much difference to client consuming this web api.
Thanks, Happy Coding.
No comments:
Post a Comment