如何在 Web API 2.2 中序列化 IdentityUser 引用?

How do I serialize an IdentityUser reference in Web API 2.2?

Visual Studio "Web API" 项目模板包括用于处理用户注册、身份验证和授权的端点。然而,在生产应用程序中,用户通常也会与其他实体相关联,例如:

public class Post {
  public Post() {};
  public int Id { get; set; }
  public ApplicationUser User { get; set; }
}

在这些情况下,无法序列化 ApplicationUser class(派生自 IdentityUser)。尝试这样做会产生类似于以下的错误:

The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; charset=utf-8'.

我在其他地方看到过类似的问题,建议传递 DTO 而不是 ApplicationUser 对象。然而,这似乎是很多开发人员的开销。有没有办法直接序列化ApplicationUser

显然,IdentityUser 上有一些属性不应该向其他用户公开,例如 PasswordHash。其他人,例如 EmailPhoneNumber 可能违反用户隐私预期,具体取决于您的 API 的身份验证设置。因此,应仔细评估哪些属性公开,哪些不公开。使用 DTO 可以解决这些问题。

就是说,您没有理由不能通过将 DataContractAttribute 添加到继承的 class 来配置 IdentityUser class 进行序列化:

[DataContract] 
public class ApplicationUser : IdentityUser {
  //...
}

然后您可以使用 DataMemberAttribute:

显式包含您希望公开的任何自定义属性
[DataMember]
public string TwitterHandle { get; set; }

如果您希望公开 UserIdentity 的成员,您需要覆盖它们:

[DataMember]
public override string UserName {
  get {
    return base.UserName;
  }
  set {
    base.UserName = value;
  }
}

最后,值得注意的是,这些属性将与有权访问端点的任何人共享。如果您想要更详细地控制谁看到什么,那么将对象包装在 DTO 中将提供这一点。