为了账号安全,请及时绑定邮箱和手机立即绑定

API端点没有返回数据,也没有错误

API端点没有返回数据,也没有错误

C#
互换的青春 2023-09-09 16:25:49
我在 NetCore 2 Entity Framework API 应用程序中有一个简单的控制器,它应该根据 stateID 获取国家公园列表:[HttpGet("ListNationalParksByState/{stateId}")]public async Task<ActionResult<IEnumerable<NationalParkList>>> GetNationalParksForState(Guid stateID){    var nationalparkList = await _context.NationalParkList.Where(n => n.StateId == stateID).ToListAsync();    return nationalparkList;}但我返回的 JSON 只显示了这一点:  [{"state":{"nationalparkList":[然而,当我在该控制器中设置断点时,它显示它找到了 3 个国家公园(我不确定 Castle.Proxies 是不是):  [0] {Castle.Proxies.NationalParkListProxy}  [1] {Castle.Proxies.NationalParkListProxy}  [2] {Castle.Proxies.NationalParkListProxy}扩展显示 3 个国家公园及其所有财产。这是我的 NationalParkList 模型:public partial class NationalParkList{    public NationalParkList()    {        NationalParkLinks = new HashSet<NationalParkLinks>();    }    public string NationalParkId { get; set; }    public Guid StateId { get; set; }    public string NationalParkTitle { get; set; }    public string NationalParkText { get; set; }    public virtual StateList State { get; set; }    public virtual ICollection<NationalParkLinks> NationalParkLinks { get; set; }}这是它在我的 dbcontext 中的定义方式:modelBuilder.Entity<NationalParkList>(entity =>        {            entity.HasKey(e => e.NationalParkId)                .HasName("PK_NationalParkList");            entity.ToTable("nationalparkList");            entity.Property(e => e.NationalParkId)                .HasColumnName("nationalparkID")                .HasMaxLength(50)                .ValueGeneratedNever();            entity.Property(e => e.StateId).HasColumnName("stateID");        });我没有收到任何错误,我只是没有收到任何数据。有人知道为什么当我点击这个控制器时没有得到任何数据吗?
查看完整描述

1 回答

?
杨魅力

TA贡献1811条经验 获得超6个赞

对象图中循环的存在很可能导致序列化出现故障。如果是这种情况,我很惊讶您在运行时没有遇到异常。


AFAIK 你有两个选择:


装饰类中您不想序列化的 props[JsonIgnore]或类似的 props,以避免对象图中出现循环。


我认为这种方法的最大问题是它的不灵活性:考虑 2 个端点A、BFoo和一个具有多个属性(包括x、y)的实体类;AFoo需要除x之外的所有道具,B需要除y之外的所有道具。如果类只有一种可能的序列化配置,您将如何处理这个问题Foo?


此外,从纯粹主义者的角度来看,添加此类装饰器会增加实体类的责任/知识,其中包含与业务逻辑无关的内容。


将实体映射到较低级别的对象(又称 DTO)


另一种方法是将实体映射到(大部分)无行为类的实例中,这些类可以被视为数据传输对象。在大多数 Web/控制器层中,您将看到数据对象进出。例如,在您的情况下,您可以重构为以下内容:


public class NationalParkListData

{

    public string Id { get; set; }

    public Guid StateId { get; set; }

    public string Title { get; set; }

    public string Text { get; set; }


    // Depending on how rest-compliant your approach is, you 

    // might include non-collection nested objects or not

    public StateListData State { get; set; }

    public int NationalParkLinksCount { get; set; }

}


[HttpGet("/states/{stateId:guid}/national-parks")]

public async Task<IActionResult> GetNationalParksForState(Guid stateId, CancellationToken cancellationToken)

{

    var stateNationalParks = await _context.NationalParkList

                                   .Where(n => n.StateId == stateId)

                                   .ToListAsync(cancellationToken);

    IEnumerable<NationalParkListData> result = // your mapper logic

    return this.Ok(result);

}

在这种情况下,您可以很容易地注意到,之前方法中提到的问题并不存在,因为它是由映射层处理的。为了实现映射层,最常见的方法是使用AutoMapper等库。


查看完整回答
反对 回复 2023-09-09
  • 1 回答
  • 0 关注
  • 85 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信