将实体框架对象序列化为JSON

时间:2011-10-17 08:01:10

标签: c# javascript json entity-framework

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 = HttpContext.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;
        }
    }
}

这有效,但当我尝试使用HttpContext.Current.Response.Write(serializer.Serialize(system));时,我收到以下错误:

  

在序列化类型的对象时检测到循环引用   “System.Data.Metadata.Edm.AssociationType

我想要的是一个json对象来表示完整的as_system对象,所以我不必手动映射每个属性。有什么方法可以解决这个问题吗?谢谢!

5 个答案:

答案 0 :(得分:4)

听起来EF并没有给你一个ASSystem,而是一些微妙的动态子类,带有一些EF goo。如果这是正确的,我认为这里最简单的事情使用类似AutoMapper之类的东西来获取非EF副本(进入new ASSystem()实例,不受影响EF)。但是,有一些选择:

  • 您可以尝试将ASSystem标记为sealed,从而消除EF注入自身的能力
  • 你编写了一个自定义转换器和register it - 这可能比映射更多,但

答案 1 :(得分:4)

如果要将序列化实体框架对象转换为JSON,可以使用http://www.newtonsoft.com中的JSON.NET。为此,请从nuget安装JSON.NET并使用以下代码示例:

return Newtonsoft.Json.JsonConvert.SerializeObject(results, Formatting.Indented, 
new JsonSerializerSettings { 
    ReferenceLoopHandling = ReferenceLoopHandling.Ignore 
});

ReferenceLoopHandling.Ignore可以防止循环引用错误。

答案 2 :(得分:3)

您可以创建一个POCO对象,该对象可以包含您的数据并且可以序列化。例如,定义:

public class MySystem {
  public int SID {get; set;}
  public string Description {get; set;}
  public string SystemName {get; set;}
}
代码中的

使用此语句:

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();

现在您可以像示例中那样序列化sys

答案 3 :(得分:0)

不确定这是否有帮助,但尝试使用DataContractJsonSerializer而不是JavaScriptSerializer。据我所知,DataContractJsonSerializer优先于JavaScriptSerializer。

答案 4 :(得分:0)

试试这个;它对我有用:

返回[在EF中]的Json数据:

  1. 添加参考&#39; System.Runtime.Serialization&#39;到项目
  2. 编写如下代码:
  3. 使用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);
    }
    

    您还可以在http://jsonlint.com/

    检查Json字符串是否有效