如何在 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
。其他人,例如 Email
和 PhoneNumber
可能违反用户隐私预期,具体取决于您的 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 中将提供这一点。
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
。其他人,例如 Email
和 PhoneNumber
可能违反用户隐私预期,具体取决于您的 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 中将提供这一点。