Skip to main content

Coding Stories V - Serialization with XmlArrayItem

Serialization, almost all applications need this feature. Nowadays serialization can be in different formats. The trend now is to use JSON, but there are many applications that uses XML.
Let’s look over the following code:
public class Car
{
  public string Id { get; set; }
}
public class City
{
  [XmlArray("Cs")]
  [XmlArrayItem("C")]
  public List<Car> RegisterCars { get; set; }
}
...
XmlSerializer serializer = new XmlSerializer(typeof(City));
serializer.Serialize(writer, city);
Output:
<city>
  <Cs>
    <c>
      <id>1</id>
    <c>
    <c>
      <id>2</id>
    <c>
  <Cs>
</city>
Even if the code compiles, works perfectly, there is a small thing that can affect us. Because we use XmlArrayItem attribute, each node from the list will be named “C”. If we will need to deserialize only a C node then we will have a surprise.
This cannot be done with the default XmlSerializer class.
XmlSerializer serializer = new XmlSerializer(typeof(Car));
serializer.Deserialize("<c><id>1</id></c>");
This will expect a node named “Car”, that cannot be found there.
Because of this, when we need to control the name of the nodes from a list and I recommend to not use the XmlArrayItem. A better approach is with [XmlRoot(ElementName = "c")] on the Car class. Using this approach, we will be able to deserialize a child node of the list without having to deserialize all the list.
The final code will look like this:
[XmlRoot(ElementName = "c")]
public class Car
{
  public string Id { get; set; }
}
public class City
{
  [XmlArray("Cs")]
  public List<Car> RegisterCars { get; set; }
}
Even if this is a small thing, on a big project this can affect how different components deserialize the content. Deciding how items need to be serialized is an important step that needs to be done from the beginning.

Comments

Popular posts from this blog

How to check in AngularJS if a service was register or not

There are cases when you need to check in a service or a controller was register in AngularJS.
For example a valid use case is when you have the same implementation running on multiple application. In this case, you may want to intercept the HTTP provider and add a custom step there. This step don’t needs to run on all the application, only in the one where the service exist and register.
A solution for this case would be to have a flag in the configuration that specify this. In the core you would have an IF that would check the value of this flag.
Another solution is to check if a specific service was register in AngularJS or not. If the service was register that you would execute your own logic.
To check if a service was register or not in AngularJS container you need to call the ‘has’ method of ‘inhector’. It will return TRUE if the service was register.
if ($injector.has('httpInterceptorService')) { $httpProvider.interceptors.push('httpInterceptorService&#…

ADO.NET provider with invariant name 'System.Data.SqlClient' could not be loaded

Today blog post will be started with the following error when running DB tests on the CI machine:
threw exception: System.InvalidOperationException: The Entity Framework provider type 'System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer' registered in the application config file for the ADO.NET provider with invariant name 'System.Data.SqlClient' could not be loaded. Make sure that the assembly-qualified name is used and that the assembly is available to the running application. See http://go.microsoft.com/fwlink/?LinkId=260882 for more information. at System.Data.Entity.Infrastructure.DependencyResolution.ProviderServicesFactory.GetInstance(String providerTypeName, String providerInvariantName) This error happened only on the Continuous Integration machine. On the devs machines, everything has fine. The classic problem – on my machine it’s working. The CI has the following configuration:

TeamCity.NET 4.51EF 6.0.2VS2013
It seems that there …

Entity Framework (EF) TransactionScope vs Database.BeginTransaction

In today blog post we will talk a little about a new feature that is available on EF6+ related to Transactions.
Until now, when we had to use transaction we used ‘TransactionScope’. It works great and I would say that is something that is now in our blood.
using (var scope = new TransactionScope(TransactionScopeOption.Required)) { using (SqlConnection conn = new SqlConnection("...")) { conn.Open(); SqlCommand sqlCommand = new SqlCommand(); sqlCommand.Connection = conn; sqlCommand.CommandText = ... sqlCommand.ExecuteNonQuery(); ... } scope.Complete(); } Starting with EF6.0 we have a new way to work with transactions. The new approach is based on Database.BeginTransaction(), Database.Rollback(), Database.Commit(). Yes, no more TransactionScope.
In the followi…