Serializing Entity Framework Objects into JSON
public class GenericHandler : IHttpHandler
{
public class ASSystem
{
public string SID { get; set; }
public string Description { get; set; }
public string SystemName { get; set; }
}
public class ErrorObj
{
public string ErrorMessage { get; set; }
}
public void ProcessRequest(HttpContext context)
{
HttpContext.Current.Response.ContentType = "application/json";
HttpContext.Current.Response.ContentEncoding = Encoding.UTF8;
string query = HttpCo开发者_开发技巧ntext.Current.Request.QueryString["SID"];
SOFAEntities ctx = new SOFAEntities();
JavaScriptSerializer serializer = new JavaScriptSerializer();
try
{
AS_SYSTEM system = ctx.AS_SYSTEM.Where(s => s.SYSTEM_ID == query).First() as AS_SYSTEM;
if (system != null)
{
ASSystem sys = new ASSystem() { SID = system.SYSTEM_ID, Description = system.DESCRIPTION, SystemName = system.SYSTEM_NAME };
HttpContext.Current.Response.Write(serializer.Serialize(sys));
}
}
catch (Exception e)
{
HttpContext.Current.Response.Write(serializer.Serialize(new ErrorObj() { ErrorMessage = e.Message }));
}
}
public bool IsReusable
{
get
{
return false;
}
}
}
This works, but when i try with HttpContext.Current.Response.Write(serializer.Serialize(system));
i get the following error:
A circular reference was detected while serializing an object of type 'System.Data.Metadata.Edm.AssociationType
What i wanted was a json object representating the complete as_system object, so i dont have to map each property manually. Is there any way to solve this? Thanks!
If you want Serialize Entity Framework Objects into JSON, You can use JSON.NET from http://www.newtonsoft.com. to do this, install JSON.NET from nuget and use following code sample:
return Newtonsoft.Json.JsonConvert.SerializeObject(results, Formatting.Indented,
new JsonSerializerSettings {
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
});
ReferenceLoopHandling.Ignore can prevent circular reference error.
It sounds like EF is not giving you a ASSystem
, but rather some subtle dynamic subclass of that with some EF goo. If that is correct, I would argue the simplest thing to do here is to use something like AutoMapper to get a non-EF copy (into a new ASSystem()
instance, untouched by EF). However, a few alternatives:
- you could try marking
ASSystem
assealed
, taking away EF's ability to inject itself - you you write a custom converter and register it - this is probably more work than mapping, though
You can create a POCO object that can contains your data and can be serialized. For example define:
public class MySystem {
public int SID {get; set;}
public string Description {get; set;}
public string SystemName {get; set;}
}
in your code use this statement:
IQuerable<MySystem> sysList = from s in ctx.AS_SYSTEM where s.SYSTEM_ID == query
select new MySystem(){SID = s.SYSTEM_ID,
Description = s.Description, SystemName = s.SystemName };
MySystem sys = sysList.First();
Now you can serialize sys
as in your example.
Not sure if this will help, but try to use DataContractJsonSerializer instead of JavaScriptSerializer. As far as I know DataContractJsonSerializer is prefered over JavaScriptSerializer.
Try this; it works for me.
To return JSON data [in EF]:
- Add reference
System.Runtime.Serialization
to the project. - Write code like below:
using System.Web.Script.Serialization;
public string getValuesJson()
{
JavaScriptSerializer js = new JavaScriptSerializer();
MyDBEntities ctx = new MyDBEntities();
var myValues = (from m in ctx.TestEntity
where (m.id == 22)
select m).ToList();
return js.Serialize(myValues);
}
You can also check whether JSON string is valid at http://jsonlint.com/.
精彩评论