猿问

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

我在 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");

        });

我没有收到任何错误,我只是没有收到任何数据。


有人知道为什么当我点击这个控制器时没有得到任何数据吗?


互换的青春
浏览 86回答 1
1回答

杨魅力

对象图中循环的存在很可能导致序列化出现故障。如果是这种情况,我很惊讶您在运行时没有遇到异常。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等库。
随时随地看视频慕课网APP
我要回答