0

I'm working on a Web API 2 based service, using Entity Framework 6 for persistence and ASP.NET Identity for authentication. I use the default IdentityUser implementation for Entity Framework.

Say I have an entity like this:

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; }
}

And in my Web API controller, a HTTP GET request returns a record this way:

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

This works just fine. However, a request would return JSON such as this:

{
    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: "[email protected]",
        emailConfirmed: false,
        ... snip ...
        userName: "some user",
        id: "some user id"
    }
}

I don't want to return all that user data! What I'd like to do is to somehow intercept the JSON that's being generated and whitelist properties to include, so that in this case, the serialized IdentityUser object returned from the API would only include this:

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

How can I achieve this? I don't want to truncate IdentityUser records across the board; this would have to be something I can opt in to on a controller action basis. Is this something that could be achieved with an action filter? And where in the pipeline would the interception need to take place? Ideally I'd want to have custom serialization for just the instances of IdentityUser in the object graph I'm returning from my controller action, rather than directly manipulating the finished JSON response. I'm running Web API as OWIN middleware if that's relevant.

1
  • 2
    Usual approach: return DTOs in stead of entities. Commented Oct 24, 2014 at 8:17

1 Answer 1

4

A good solution is by using Dtos, AutoMapper/Projection, so you setup your dtos to include what you want to return, and by using Automapper and projection you map your original entities to Dtos, and vice versa.

Using Automapper : So you define a UserDto like this:

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

then at the startup of your app you define the mapping between the IdentityUser and the UserDto like this:

Mapper.CreateMap<IdentityUser, UserDto>();

and then when you have your example entity, you can map the IdentityUser to UserDto like this

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

and you return just the dto.

Using Projection you can use Select Linq method to select only the field you want to return from the database, so something like this:

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

hope that helps.

Sign up to request clarification or add additional context in comments.

1 Comment

I guess I'll need some additional plumbing for nesting mapped DTO's which would be the case here, but something like AutoMapper seems like the way to go. Thanks!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.