简体   繁体   中英

Formatting Serialized JSON With Code-First Entity Framework

I'm using a Web-API GET to return JSON for a Report.

The GET method returns a simple db.Reports.ToList();

This is the dump of the data I retrieve

{
        "Project": {
            "Location": {
                "LocationId": 7,
                "Description": "New York"
            },
            "Department": {
                "DepartmentId": 7,
                "Description": "Engineering"
            },
            "ProjectId": 7,
            "Description": "Project_3",
            "LocationId": 7,
            "DepartmentId": 7
        },
        "Person": {
            "Email": "email@gmail.com",
            "FirstName": "John",
            "LastName": "Doe",
            "IsActive": true
        },
        "StatusCode": {
            "StatusId": 8,
            "Description": "Accepted"
        },
        "ReportId": "d4cddb3f-ea6a-4b0a-9820-19bd8ee43b3a",
        "Description": "Report 3",
        "RoundTrip": 45.88,
        "IsBillable": true,
        "StartDate": "2013-06-27T00:00:00",
        "EndDate": "2013-06-27T14:36:32.467",
        "TimeUpdated": "AAAAAAAAJxM="
    }, ... 
}

This is the related Report declaration:

public class Report
{
    public Guid ReportId { get; set; }
    public string Description { get; set; }
    public double RoundTrip { get; set; }
    public bool IsBillable { get; set; }

    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }

    public virtual Project Project { get; set; }

    public byte[] TimeUpdated { get; set; }

    public virtual Person Person { get; set; }

    public virtual StatusCode StatusCode { get; set; }
}

In this situation, I'd really like to just have the Ids of the various objects contained in the Report class. For example, I'd really just like to see:

    "Project": 7,
    "Location": 7,
    "Department": 7,
    "Person": "email@gmail.com",
    "StatusCode": 8,
    "ReportId": "d4cddb3f-ea6a-4b0a-9820-19bd8ee43b3a",
    "Description": "Report 3",
    "RoundTrip": 45.88,
    "IsBillable": true,
    "StartDate": "2013-06-27T00:00:00",
    "EndDate": "2013-06-27T14:36:32.467",
    "TimeUpdated": "AAAAAAAAJxM="
  1. Is there a relatively easy way to go about doing this, or would it be in my better interests to just further parse the result I'm seeing already?
  2. Why does EF by default create these objects within the JSON rather than just the foreign keys?

You can do without specifically creating a new class. In your ApiController , if you are using the typed return type (in favor of an HttpResponseMessage ), change the List type to IEnumerable<object> and return:

return db.Reports.Select(r => new {
    Project = r.ProjectId;
    Location = r.Location.LocationId;
    Department = r.Department.DepartmentId;
    Person = r.Person.Email;
    StatusCode = r.StatusCode.StatusId;
    Description: r.Description
    RoundTrip: r.RoundTrip
    IsBillable: r.IsBillable,
    StartDate: r.StartDate,
    EndDate: r.EndDate
    TimeUpdated: r.TimeUpdated
});

// Or if you're using HttpResponseMessage
return Request.CreateResponse(HttpStatusCode.Ok, 
    db.Reports.Select(r => new {
        Project = r.ProjectId;
        Location = r.Location.LocationId;
        Department = r.Department.DepartmentId;
        Person = r.Person.Email;
        StatusCode = r.StatusCode.StatusId;
        Description: r.Description
        RoundTrip: r.RoundTrip
        IsBillable: r.IsBillable,
        StartDate: r.StartDate,
        EndDate: r.EndDate
        TimeUpdated: r.TimeUpdated
    }));

The default Json serializer (Newtonsoft's Json.Net) is smart enough to serialize anonymous object. The only unknown in the code above is the behaviour of the TimeUpdated member as it's a byte array. You may have to adjust the assignment.

I would recommend making a model for displaying the JSON as you want it to be displayed. This would be the easiest option.

Something like this should work:

public class ReportSimple
{
    public Guid ReportId { get; set; }
    public int Project { get; set; }
    public int Location { get; set; } 
    public int Department { get; set; }
    public string Person { get; set; }
    public int StatusCode { get; set; }
    public string Description { get; set; }
    public double RoundTrip { get; set; }
    public bool IsBillable { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }
    public byte[] TimeUpdated { get; set; }

    public ReportSimple(Project project, Person person, StatusCode statusCode)
    {
        Project = project.ProjectId;
        Location = project.Location.LocationId;
        Department = project.Department.DepartmentId;
        Person = person.Email;
        StatusCode = statusCode.StatusId;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM