简体   繁体   中英

Automapper mapping Flags Enum from ViewModel to Domain model

While trying to translate between my ViewModel and my domain model using AutoMapper I noticed that it does not play well with Enums marked the the Flags attribute.

Here is a quick mockup of the classes:

ViewModel:

public class TestViewModel
{
    // array of individual Enum values
    public TestEnum[] TestEnum { get; set; } 
}

Domain Model:

public class TestModel
{
    // single Enum marked with flags attribute
    public TestEnum TestEnum { get; set; }
}

Enum:

[Flags]
public enum TestEnum
{
    Test1,
    Test2,
    Test3,
    Test4
}

This is what I am trying to do. I guess I need a Custom resolver of some sort in my Automapper config because it throws an exception when I do Mapper.Map().

My question: How would I accomplish this?

Bonus question: Is this best practice for handling Flags Enums / Bitmasks in Viewmodel -> Domain models (in a MVVM respect)? If not, what practice would you suggest (using AutoMapper or otherwise)?

When mapping to the view model, you can try to use Enum.GetValues() and LINQ to get a list of enum values. To map back to the model, try using Aggregate() ...

Mapper.CreateMap<TestModel, TestViewModel>()
    .ForMember(v => v.TestEnum, 
        x => x.MapFrom(m => Enum.GetValues(typeof(TestEnum))
                            .Cast<TestEnum>()
                            .Where(e => (e & m) > 0)
                            .ToList()))
    .ReverseMap()
    .ForMember(m => m.TestEnum,
        x => x.MapFrom(v => v.Aggregate((i, j) => i | j));

As for whether this is the best approach, it really depends on how the view model is being used. Currently, the view model doesn't contain flags that aren't set; do you need them for rendering the view?

I'd skip AutoMapper and go the model binding route. If you're using ASP.NET MVC, you can hook directly into model binding so that all values are combined into one.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM