【问题标题】:How do I remove properties from related EF entities in Web API JSON response如何从 Web API JSON 响应中的相关 EF 实体中删除属性
【发布时间】:2014-10-24 16:53:26
【问题描述】:

我正在开发基于 Web API 2 的服务,使用 Entity Framework 6 进行持久性和 ASP.NET Identity 进行身份验证。我为实体框架使用默认的IdentityUser 实现。

假设我有一个这样的实体:

public class Example
{
    [Key]
    public string Id { get; set; }
    public string Foo { get; set; }
    public string Bar { get; set; }
    public virtual IdentityUser OwningUser { get; set; }
}

在我的 Web API 控制器中,HTTP GET 请求以这种方式返回记录:

public async Task<Example> Get( string id )
{
    var example = await _exampleRepository.FindByIdAsync( id );
    return example;
}

这很好用。但是,请求会返回如下 JSON:

{
    id: "some id",
    foo: "some foo",
    bar: "some bar",
    owningUser: {
        claims: [],
        logins: [],
        roles: [
            {
                userId: "some user id",
                roleId: "some role id"
            }
        ],
        securityStamp: "jadshgiuahsduigh",
        passwordHash: "adsghasdjgiasdg",
        email: "some@email.com",
        emailConfirmed: false,
        ... snip ...
        userName: "some user",
        id: "some user id"
    }
}

我不想返回所有用户数据!我想做的是以某种方式拦截正在生成的 JSON 和要包含的白名单属性,这样在这种情况下,从 API 返回的序列化 IdentityUser 对象将只包含以下内容:

owningUser: {
    userName: "some user",
    id: "some user id"
}

我怎样才能做到这一点?我不想全面截断IdentityUser 记录;这必须是我可以在控制器操作的基础上选择加入的东西。这是可以通过动作过滤器实现的吗?拦截需要在管道的哪个位置进行?理想情况下,我希望仅对从控制器操作返回的对象图中的 IdentityUser 实例进行自定义序列化,而不是直接操作完成的 JSON 响应。如果相关,我将 Web API 作为 OWIN 中间件运行。

【问题讨论】:

  • 常用方法:返回 DTO 而不是实体。

标签: c# entity-framework asp.net-web-api asp.net-identity owin


【解决方案1】:

一个好的解决方案是使用 Dtos,AutoMapper/Projection,这样您就可以设置您的 dtos 以包含您想要返回的内容,并通过使用 Automapper 和投影将您的原始实体映射到 Dtos,反之亦然。

p>

使用自动映射器: 所以你定义一个 UserDto 像这样:

public class UserDto
    {
        public int Id { get; set; }
        public string UserName { get; set; }
    }

然后在您的应用启动时,您可以像这样定义 IdentityUser 和 UserDto 之间的映射:

Mapper.CreateMap<IdentityUser, UserDto>();

然后当你有你的示例实体时,你可以像这样将 IdentityUser 映射到 UserDto

var dto = Mapper.Map<UserDto>(example.OwningUser);

然后你只返回 dto。

使用投影 您可以使用 Select Linq 方法仅选择要从数据库中返回的字段,如下所示:

var userDto = dbExamplesSet
                .Select(e => e.OwningUser)
                .Select(u => new UserDto
                {
                    Id = u.Id, 
                    UserName = u.UserName
                }).SingleOrDefault(u=> u.Id == someUserId);

希望有帮助。

【讨论】:

  • 我想我需要一些额外的管道来嵌套映射的 DTO,这就是这里的情况,但是像 AutoMapper 这样的东西似乎是要走的路。谢谢!
猜你喜欢
  • 2017-04-24
  • 1970-01-01
  • 2018-10-22
  • 1970-01-01
  • 2023-03-29
  • 2016-10-20
  • 1970-01-01
  • 2019-08-02
  • 2021-02-09
相关资源
最近更新 更多