Web API:返回包含 EF 成员字段计数但不返回成员对象数据的 JSON



场景:投诉对象可以有很多投票。在 GET 请求中,我想返回投票计数,而不是在 API 响应中返回每个带有投诉的单独投票对象。

以下是主要类:

//Model: Complaint.cs
public class Complaint
{
    public int Id { get; set; }
    public string Summary { get; set; }
    public List<Vote> Votes { get; set; }
    public int UpVoteCount=> Votes.Count(v => v.IsUpvote);
    public ApplicationUser Creator { get; set; }
}

//Model: Vote.cs
public class Vote
{
    public int Id { get; set; }
    public bool IsUpVote{ get; set; }
    public Complaint Complaint { get; set; }
    public ApplicationUser Creator { get; set; }
}

//DbContext: AppDbContext.cs
....
public IQueryable<Complaint> ComplaintsWithData =>
        Complaint
            .Include(complaint => complaint.Votes)
            .AsNoTracking();
//ApiController: ComplaintsController.cs
[HttpGet]
public IEnumerable<Complaint> GetComplaints()
{
      return _context.ComplaintsWithData.ToList();
}

在当前的 JSON 响应中,我获得了投票计数,但是我也获得了每个单独的投票对象的详细信息(在此调用中我不需要)。

当前响应:

{
        "id": 2,
        "summary": "House was Stolen",
        "votes": [
            {
                "id": 146,
                "isUpvote": false,
                "creator": null
            },
                        {
                "id": 147,
                "isUpvote": false,
                "creator": null
            },
            ....
            ....
            ....
        ],
        "upVoteCount": 211,
    }

期望响应:

{
        "id": 2,
        "summary": "House was Stolen",
        "upVoteCount": 211,
    }

我需要有 .包括(投诉=>投诉。投票).cs 文件中,以便我可以实际加载投票以确定投票计数。

我不想将投票计数存储为实际的数据库列。

任何建议将不胜感激!

我正在使用带有实体框架核心的.NET Core 2.0 Web API。

提前谢谢。

您可以在类上使用 OptIn 进行成员序列化:

//..
using Newtonsoft.Json;
//..
[JsonObject(MemberSerialization.OptIn)]
public class Complaint
{
    [JsonProperty("id")]
    public int Id { get; set; }
    [JsonProperty("summary")]
    public string Summary { get; set; }
    public List<Vote> Votes { get; set; }
    [JsonProperty("upVoteCount")]
    public int UpVoteCount=> Votes.Count(v => v.IsUpvote);
    public ApplicationUser Creator { get; set; }
}

也许是这样的:

public List<Complaint> ComplaintsWithData()
{
    return this.DbContext.Complaints
        .Include(complaint => complaint.Votes)
        .Select(p => new Complaint
        {
            Id = p.Id,
            IsUpVote = p.IsUpVote,
            UpVoteCount = p.Votes.Count
        }).ToList();
}

有几个选项。以下是其中的两个:

您可以考虑添加视图模型 - 具有要返回到 UI 的确切属性集的类。您只需要将实体记录映射到它们

或者,只需使用"非序列化"属性标记隐藏的属性,使其不被序列化到JSONXML终结点响应。

public class Complaint
{
    public int Id { get; set; }
    public string Summary { get; set; }
    [NonSerialized]
    public List<Vote> Votes { get; set; }
    public int UpVoteCount=> Votes.Count(v => v.IsUpvote);
    public ApplicationUser Creator { get; set; }
}

最新更新