【问题标题】:ASP.NET Web API returns empty collection in json responseASP.NET Web API 在 json 响应中返回空集合
【发布时间】:2013-10-25 16:05:10
【问题描述】:

好的,我的 ASP.NET Web API 有问题。我按照this 教程学习了如何创建它。为了我的目的,我修改了教程。

我有一个包含下载 URL 集合的补丁类。 API 可以很好地返回所有信息,只有 DownloadURLs 的集合返回为 null。 但是,当我逐步调试代码时,它正确返回了集合。 我做错什么了。我找不到我的错误。 这是模型:

public class Patch
{
    [Key]
    [Required]
    [JsonProperty("PatchVersion")]
    public string PatchVersion { get; set; }

    [Required]
    [JsonProperty("Length")]
    public long Length { get; set; }

    [JsonProperty("VersionToUpdateFrom")]
    public string VersionToUpdateFrom { get; set; }

    [JsonProperty("DownloadUris")]
    public ICollection<DownloadUri> DownloadUris { get; set; }
}

public class DownloadUri
{
    [Key]
    [Required]
    [JsonProperty("AbsolutePath")]
    public string AbsolutePath { get; set; }

    [Required]
    [JsonProperty("IndirectDownload")]
    public bool IndirectDownload { get; set; }
}

这是我的 DataContext 类:

public class PatchesContext : DbContext
{
    public PatchesContext()
        : base("name=PatchesContext")
    {
    }

    public DbSet<Patch> Patches { get; set; }

    public DbSet<DownloadUri> DownloadUris { get; set; }
}

这是 ContextInitializer

public class PatchesContextInitializer : DropCreateDatabaseIfModelChanges<PatchesContext>
{
    protected override void Seed(PatchesContext context)
    {

        var downloadUri = new List<DownloadUri>
        {
            new DownloadUri
            {
                AbsolutePath = "http://downloadUri1.test", IndirectDownload = false
            },
            new DownloadUri
            {
                AbsolutePath = "http://downloadUri2.test", IndirectDownload = false
            }
        };

        var patches = new List<Patch>
        {
            new Patch
            {
                Length = 100000, PatchVersion = "1.0.0.0", VersionToUpdateFrom = string.Empty, DownloadUris = downloadUri
            },
            new Patch
            {
                DownloadUris = null, Length = 10000, PatchVersion = "1.1.0.0", VersionToUpdateFrom = "1.0.0.0"
            }
        };
        patches.ForEach(p => context.Patches.Add(p));
        context.SaveChanges();
    }
}

最后是我的控制器类。我省略了 Post、Put 和 Delete 方法,因为我还没有测试它们(如果 get 不起作用,那就没有意义了):

public class AdminController : ApiController
{
    private PatchesContext db = new PatchesContext();

    // GET api/Admin
    public IEnumerable<Patch> GetPatches()
    {
        return db.Patches.AsEnumerable();
    }

    // GET api/Admin/5
    public Patch GetPatch(string version)
    {
        Patch patch = db.Patches.Find(version);
        if (patch == null)
        {
            throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
        }

        return patch;
    }
}

希望大家能帮帮我,谢谢。

/编辑: 标头如下所示:

Status Code: 200 OK
Cache-Control: no-cache
Content-Length: 291
Content-Type: application/json; charset=utf-8
Date: Fri, 25 Oct 2013 17:25:48 GMT
Expires: -1
Pragma: no-cache
Server: Microsoft-IIS/8.0
X-SourceFiles: =?UTF-8?B?RTpcVXNlcnNcUm9iZXJ0XERvY3VtZW50c1xWaXN1YWwgU3R1ZGlvIDIwMTJcUHJvamVjdHNcTjQ0V2Vic2l0ZVxONDRXZWJzaXRlXGFwaVxhZG 1pbg==?=

响应正文如下所示:

[

  {
    "$id": "1",
    "PatchVersion": "1.0.0.0",
    "Length": 100000,
    "VersionToUpdateFrom": "",
    "DownloadUris": null
  },
  {
    "$id": "2",
    "PatchVersion": "1.1.0.0",
    "Length": 10000,
    "VersionToUpdateFrom": "1.0.0.0",
    "DownloadUris": null
  }
]

【问题讨论】:

  • 所以你得到一个 200 成功代码但没有数据?当您在 Web API 操作上设置断点时,您是否返回了非空值?
  • 我们能看到json的例子吗?
  • 我将响应头和正文添加到我的初始帖子中

标签: c# asp.net json asp.net-web-api linq-to-entities


【解决方案1】:

您没有显式加载 Patch.DownloadUris 属性,该属性也不是虚拟的,因此它也不会延迟加载它。

要么通过此行的包含 DownloadUris 显式加载它:

Patch patch = db.Patches.Find(version);

到(未经测试)

Patch patch = db.Patches.Find(version).Include("DownloadUris");

或者将该属性设为虚拟并确保在您的上下文中启用延迟加载。

编辑说明: 在您的代码示例中给出的 Seed 方法,只有 Patch (1.0.0.0) 将具有 DownloadUris 的值,因为在 Patch (1.1.0.0) 中您将该属性设置为 null

【讨论】:

  • 所以如果我理解正确,我必须将DownloadUri 类的属性设为虚拟?会试试的。
  • 不,将 Patch 类中的 DownloadUris 属性设为虚拟
  • 添加了显式加载示例,因为我离开了我的 IDE,所以没有测试。
  • 是的,将集合属性设为虚拟就可以了。所以我会接受这个作为我的答案。通过将其虚拟化,我应该知道的任何事情。我知道这与继承有关,但我从来没有与它有太多关系。有什么需要注意的吗?
  • 是的,你应该注意一些事情! ;) (如果其他人没有更快,我会回到这个并发表后续评论)你真的应该开始显式和隐式加载。它比许多人最初想象的要复杂一些,但是当您习惯了如何使用它时会非常酷。
猜你喜欢
  • 2018-07-09
  • 2019-02-13
  • 2017-05-05
  • 2017-09-23
  • 1970-01-01
  • 1970-01-01
  • 2014-06-08
  • 2014-07-01
  • 2021-06-24
相关资源
最近更新 更多