即使使用 IgnoreDataMember 和 JsonIgnore 也尝试序列化 ICollection

Attempted Serialization Of ICollection even with IgnoreDataMember and JsonIgnore

我在避免 Web Api 中某些 ICollection 属性的序列化时遇到了一些问题。避免序列化的常见建议似乎是添加 IgnoreDataMemberJsonIgnore。我不想序列化一对多和一对一的属性。

我有以下型号:

public class Player
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Key, Column(Order=0)]
    public Guid PlayerId { get; set; }

    [IgnoreDataMember]
    public virtual ICollection<Player> Friends { get; set; }

    [IgnoreDataMember]
    [Required]
    public string Password { get; set; }

    [MaxLength(100)]
    [Index(IsUnique = true)]
    public string Username { get; set; }

    [IgnoreDataMember]
    public virtual ICollection<WordChallenge> IssuedChallenges { get; set; }

    [IgnoreDataMember]
    public virtual ICollection<WordChallenge> ReceivedChallenges { get; set; }
}

然而,当我对端点执行 POST 时,出现以下异常:

The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.

在这种情况下,它应该只尝试序列化 PlayerIdUsername

由于被请求,以下管理 dbContext:

public async Task<IEnumerable<Player>> GetFriends(Guid playerId)
{
    //Handles common exceptions and manages the dbcontext. In this case context is disposed off after the interaction is done.
    return await DbInteraction(
        async dbModel =>
        {
            var player = await GetPlayerById(playerId, dbModel);
            return player.Friends.ToList();
        });
}

控制器:

// GET: api/Friend/5
public async Task<ReturnObject<IEnumerable<Player>>> Get(Guid token, Guid id)
{
    var playerService = new PlayerService(base._wordModelFactory);
    var fields = await playerService.GetFriends(id);

    return ReturnData(fields);
}

在你的情况下(通常),与其标记你不想用 IgnoreDataMember 序列化的成员,不如用 DataContact 标记 class 并标记成员您想要DataMember.

连载

您仍然可能想知道为什么使用 IgnoreDataMember 和导航属性会观察到这种行为。我的猜测是 - 为了在您访问导航 属性 时支持延迟加载,EF 可能会为您的 POCO class 创建动态代理 class。请注意,您的导航属性标有 "virtual"。这是为了让 EF 能够在该动态代理 class 中覆盖它们并添加延迟加载行为。 IgnoreDataMember 属性不被继承,因此在继承的代理中 class 导航属性不再用它标记,因此序列化程序将尝试包含它们。