【问题标题】:Serializing Entity Framework Objects into JSON将实体框架对象序列化为 JSON
【发布时间】:2011-12-09 02:32:27
【问题描述】:
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

我想要的是一个代表完整 as_system 对象的 json 对象,所以我不必手动映射每个属性。有没有办法解决这个问题?谢谢!

【问题讨论】:

    标签: c# javascript json entity-framework


    【解决方案1】:

    如果您想将实体框架对象序列化为 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】:

    听起来 EF 并没有给你一个ASSystem,而是它的一些微妙的动态子类和一些 EF goo。如果这是正确的,我认为在这里做的最简单的事情 使用类似 AutoMapper 的东西来获取非 EF 副本(到 new ASSystem() 实例中,不受 EF 影响)。但是,有一些替代方案:

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

    【讨论】:

      【解决方案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

      【讨论】:

      • 有什么办法可以让 EF 生成一个类,其中包含所有具有正确数据类型的列作为属性?
      • @Johan 是的,EF 4.0 支持 POCO 对象,EF 4.1 默认使用 POCO。
      【解决方案4】:

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

      【讨论】:

      • 我忘了提到我正在使用 .net 3.5 和 VS2008。我没有找到它,我想这是问题所在? :)
      • 我通常发现DataContractJsonSerializer 在许多情况下提供了一些... 非典型 JSON。我通常对JavaScriptSerializerJson.NET 有更多的运气
      【解决方案5】:

      试试这个;它对我有用。

      返回 JSON 数据 [在 EF 中]:

      1. 将引用System.Runtime.Serialization 添加到项目中。
      2. 编写如下代码:

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

      您还可以在http://jsonlint.com/处检查JSON字符串是否有效。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-02-27
        • 2012-12-16
        • 1970-01-01
        • 1970-01-01
        • 2016-12-21
        • 2012-10-25
        • 2015-08-28
        相关资源
        最近更新 更多