Introduction
Entity Framework’s entity (which has a relationship with other entities) cannot serialize with .NET Framework’s existing object like JavascriptSerializer
or DataContract
JSON Serializer or JsonResult. So I needed to solve that problem by myself.
Background
In one of our projects, we used ASP.NET MVC for presentation/business logic layer and Entity framework for data access layer. At that time I faced the problem. I needed to call server side methods from client side JavaScript with the help of XMLHttp
request. In the client side, we used JQuery (JavaScript library). The server side methods needed to return data with Jason format. At first I tried to use JsonResult (MVC framework) to transform that data to JSON format, then one error message was thrown. The error message was “Circular Reference error”. Then I used JavascriptSerializer
class. But the same thing occurred. Then I tried DataContract JSON Serializer. I got the same error once again.
I was wondering what I should do. I first started Googling to solve my problem. There I found that Entity framework’s Entity serialization had some problem with the existing JSON Serializer provided by the .NET Framework. So, I started thinking of writing my own small serializer to solve and use Entity framework with JSON.
Solution
public class CustomJSonSerializer
{
public static string JsonSerialize<T>(T obj) where T : class
{
var sb = new StringBuilder("{");
var parentType = obj.GetType();
var ms = parentType.GetMembers().Where(v => v.MemberType
== MemberTypes.Property).ToList<MemberInfo>();
const string doubleQuote = "\"";
var counter = 0;
var stringTypes = new List<String> { "String", "Guid",
"Boolean" };
var ignoreEntityTypes = new List<String> { "EntityReference`1",
"EntityCollection`1", "EntityState",
"EntityKey", "EntitySetName" };
foreach (PropertyInfo p in ms)
{
counter++;
var propertyName = p.Name;
var propertyType = p.PropertyType;
var propertyValue = p.GetValue(obj, null);
if (ignoreEntityTypes.Contains(propertyType.Name))
{
continue;
}
if (stringTypes.Contains(propertyType.Name))
{
if (propertyValue == null)
{
sb.Append(doubleQuote + propertyName + doubleQuote +
":" + "null");
}
else
{
sb.Append(doubleQuote + propertyName + doubleQuote +
":" + doubleQuote + propertyValue.ToString() + doubleQuote);
}
}
else if (propertyType != null && propertyType.IsPrimitive)
{
sb.Append(doubleQuote + propertyName + doubleQuote
+ ":" + propertyValue.ToString());
}
else if (propertyType.Name == "DateTime")
{
var dt = (DateTime)propertyValue;
sb.Append(doubleQuote + propertyName
+ doubleQuote + ":"
+ "new Date(" + dt.Ticks.ToString() + ")");
}
else
{
if (propertyValue != null)
{
sb.Append(doubleQuote + propertyType.Name + doubleQuote + ":");
sb.Append(JsonSerialize(propertyValue));
}
else
{
continue;
}
}
if (counter < ms.Count)
{
sb.Append(",");
}
}
sb.Append("}");
var result = sb.ToString().Replace(",}", "}");
return result;
}
Limitation
I did not test it with very complex scenarios. So issues may arise. Still, I do not know how the JSON Serializer handles datetime. I use the Tick
property of the DateTime
method. It may be incorrect.
Conclusion
I solved my problem in this way. I hope it will work for you if you need to work with Entity framework and JSON format.
History
- 29th April, 2009: Initial post