WCF restores JSON with Entity Framework

I recently created WCF support with EF4. All this worked when returning an XML response. however, when it comes to JSON, I got a 504 Error. failed to return json data, WCF Resful Service.NET 4.0

Deeper work with Service Trace Viewer: I found this error:

'Type' xxx.DataEntity.AppView 'cannot be serialized for JSON, because its setting IsReference is "True". The JSON format does not support links because there is no standardized presentation format for Recommendations. To enable serialization, disable IsReference on the type or the corresponding parent class type.

"AppView" is a complex class of objects that is generated by EF4 from a storage procedure. I spend quite a lot of time on google, how to disable IsReference, very little result so far.

is anyone with any solutions?

early

the code:

[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;
                }
            }
+3
source share
4 answers

. , JSON- Entity. JSON (DTO), Entity. 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 , , , .

+1

, ADO Entity Models. , , , 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());

}}
+1

Entity Reflection. .

+1
source

Another way to do this is to use LINQ to create an anonymous type with a subset of the fields you need from your entity, and then use JSON.NET to serialize the collection of anon types created in the LINQ statement. then save this assembly as a string by serializing.

0
source

Source: https://habr.com/ru/post/1777835/


All Articles