【问题标题】:WCF restful returning JSON by using Entity Framework ComplexWCF 使用实体框架复杂返回 JSON
【发布时间】:2011-05-18 07:01:50
【问题描述】:

最近我用 EF4 设置了 WCF 宁静服务。 当返回 XML 格式响应时,一切都解决了。但是,当涉及到 JSON 时,我得到了 504 错误。 unable to return json data, WCF Resful Service .NET 4.0

通过使用服务跟踪查看器进行更深入的挖掘: 我发现了这个错误:

'类型'xxx.DataEntity.AppView' 无法序列化为 JSON,因为 其 IsReference 设置为“真”。这 JSON格式不支持 参考因为没有 表示的标准化格式 参考。要启用序列化, 禁用 IsReference 设置 类型或适当的父类 类型。'

“AppView”是由 EF4 从存储过程生成的复杂对象类。 我花了很多时间谷歌如何禁用 IsReference,到目前为止结果很少。

有人吗?有什么解决办法吗?

提前致谢

代码:

[OperationContract]
        [WebInvoke(Method = "GET",
            BodyStyle = WebMessageBodyStyle.Wrapped,
            UriTemplate = "App/{id}/{format}")]
        AppView FuncDetail(string id, string format);



public AppView FuncDetail(string id, string format)
        {
            SetResponseFormat(format);
            return AppSvcs.GetById(id);
        }


private void SetResponseFormat(string format)
            {
                if (format.ToLower() == "json")
                {
                    ResponseContext.Format = WebMessageFormat.Json;
                }
                else
                {
                    ResponseContext.Format = WebMessageFormat.Xml;
                }
            }

【问题讨论】:

    标签: json entity-framework serialization wcf-rest


    【解决方案1】:

    另一种方法是使用 LINQ 创建一个匿名类型,其中包含您从实体中需要的字段子集,然后使用 JSON.NET 序列化您在 LINQ 语句中创建的匿名类型的集合。然后通过序列化将该集合作为字符串持久化。

    【讨论】:

      【解决方案2】:

      我遇到了完全相同的问题。它只发生在我试图返回 JSON 序列化实体对象的一种服务方法上。对于我的所有其他方法,我返回的是 JSON 序列化数据传输对象 (DTO),它们是独立的,未连接到实体框架。我正在使用 DTO 将数据发布到方法中。通常,您发送的数据不需要您存储在模型或数据库中的所有数据,例如ID 值、更新日期等。映射在模型类中完成,如下所示:

      public partial class Location
      {
      
          public static LocationDto CreateLocationDto(Location location)
          {
              LocationDto dto = new LocationDto
              {
                  Accuracy = location.Accuracy,
                  Altitude = location.Altitude,
                  Bearing = location.Bearing                
              };
              return dto;
          }
      

      它可能看起来有点笨拙,但它有效,它确保您只发送您打算发回的数据字段。它对我有用,因为我只有 5 或 6 个实体,但我可以看到,如果你有很多类,它会变得有点乏味。

      【讨论】:

        【解决方案3】:

        使用实体元数据代替反射要清楚得多。 元数据非常广泛。

        【讨论】:

          【解决方案4】:

          我遇到了同样的问题,这是由使用自动生成的 ADO 实体模型引起的。我还没有找到直接解决此问题的方法,但作为一种变通方法,我将响应显式序列化为 json。

          因此,在您的示例中,AppView FuncDetail 如下所示:

          public object FuncDetail(string id, string format)
              {
                  SetResponseFormat(format);
          
                  // where AppSvc is the object type and the enumerable list of this type is returned by the GetById method, cast it to a json string
                  return JSONSerializer.ToJson<AppSvc>(AppSvcs.GetById(id));
              }
          

          这是我正在使用的序列化程序:

          public static class GenericSerializer 
          {
          public static DataTable ToDataTable<T>(IEnumerable<T> varlist)
          {
              DataTable dtReturn = new DataTable();
          
              // column names 
              PropertyInfo[] oProps = null;
          
              if (varlist == null) return dtReturn;
          
              foreach (T rec in varlist)
              {
                  // Use reflection to get property names, to create table, Only first time, others will follow 
                  if (oProps == null)
                  {
                      oProps = ((Type)rec.GetType()).GetProperties();
                      foreach (PropertyInfo pi in oProps)
                      {
                          Type colType = pi.PropertyType;
          
                          if ((colType.IsGenericType) && (colType.GetGenericTypeDefinition()
                          == typeof(Nullable<>)))
                          {
                              colType = colType.GetGenericArguments()[0];
                          }
          
                          dtReturn.Columns.Add(new DataColumn(pi.Name, colType));
                      }
                  }
          
                  DataRow dr = dtReturn.NewRow();
          
                  foreach (PropertyInfo pi in oProps)
                  {
                      dr[pi.Name] = pi.GetValue(rec, null) == null ? DBNull.Value : pi.GetValue
                      (rec, null);
                  }
          
                  dtReturn.Rows.Add(dr);
              }
              return dtReturn;
          }
          

          }

          public static class JSONSerializer 
          {
          public static string ToJson<T>(IEnumerable<T> varlist)
          {
              DataTable dtReturn = GenericSerializer.ToDataTable(varlist);
              return GetJSONString(dtReturn);
          }
          
              static object RowsToDictionary(this DataTable table)
          {
          
              var columns = table.Columns.Cast<DataColumn>().ToArray();
          
              return table.Rows.Cast<DataRow>().Select(r => columns.ToDictionary(c => c.ColumnName, c => r[c]));
          
          }
          
          static Dictionary<string, object> ToDictionary(this DataTable table)
          {
          
              return new Dictionary<string, object>
              {
                  { table.TableName, table.RowsToDictionary() }
              };
          
          }
          
          static Dictionary<string, object> ToDictionary(this DataSet data)
          {
          
              return data.Tables.Cast<DataTable>().ToDictionary(t => "Table", t => t.RowsToDictionary());
          
          }
          
          public static string GetJSONString(DataTable table)
          {
          
              JavaScriptSerializer serializer = new JavaScriptSerializer();
          
              return serializer.Serialize(table.ToDictionary());
          
          }
          
          public static string GetJSONString(DataSet data)
          {
          
              JavaScriptSerializer serializer = new JavaScriptSerializer();
          
              return serializer.Serialize(data.ToDictionary());
          
          }}
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-05-06
            • 2023-03-20
            • 1970-01-01
            • 2011-06-02
            • 1970-01-01
            相关资源
            最近更新 更多