Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AutoMapper: Mapping Tuple to Tuple

I'm using AutoMapper in my ASP.NET MVC4 project. I have a problem when mapping 2 class Question and QuestionViewModel. Here my two model classes:

   public class Question
    {
      public int Id { get; set; }
      public string Content { get; set; }
      public Tuple<int, int> GetVoteTuple()
       {
         "some code here"
       }
    }

   public class QuestionViewModel
    {
      public int Id { get; set; }
      public string Content { get; set; }
      public Tuple<int, int> VoteTuple { get; set; }
    }

Here is my controller code :

   public class QuestionController: Controller 
    {
       public ActionResult Index(int id)
         {

            Question question = Dal.getQuestion(id);
            Mapper.CreateMap<Question, QuestionViewModel>()
                .ForMember(p => p.VoteTuple,
                m => m.MapFrom(
                s => s.GetVoteTuple()
            ));

            QuestionViewModel questionViewModel =
                        Mapper.Map<Question, QuestionViewModel>(question);

            return View(questionViewModel);

          }
     }

When I run this code the VoteTuple property in QuestionViewModel has null value. How can I map 2 class with Tuple property ?

Thanks.

like image 962
Hai Nguyen Avatar asked Jan 22 '26 14:01

Hai Nguyen


2 Answers

Mapping from Tuple to Tuple is not possible by default through Automapper, because Tuple doesn't have setter properties (they can only be initialized through the constructor).

You have 2 options:

1) Create a custom resolver for Automapper and then use the .ResolveUsing method in the mapping config: .ForMember(p => p.VoteTuple, m => m.ResolveUsing<CustomTupleResolver>())

2) Map to a properties / a class instead, like this:

public class QuestionViewModel
{
  public int Id { get; set; }
  public string Content { get; set; }
  public int VoteItem1 { get; set; }
  public int VoteItem2 { get; set; }
}

And then:

.ForMember(p => p.VoteItem1, m => m.MapFrom(g => g.Item1))
.ForMember(p => p.VoteItem2, m => m.MapFrom(g => g.Item2))

You don't really need to use Tuple in your view model, so I'd recommend the 2nd option.

Edit:

I see that you've updated your code so that GetVoteTuple() is a function, not a property. In that case, you could easily adapt the code like this:

.ForMember(p => p.VoteItem1, m => m.MapFrom(g => g.GetVoteTuple().Item1))
.ForMember(p => p.VoteItem2, m => m.MapFrom(g => g.GetVoteTuple().Item2))
like image 152
valentin Avatar answered Jan 25 '26 05:01

valentin


Your CreateMap call is incorrect:

Mapper.CreateMap<Question, QuestionViewModel>()
    .ForMember(p => p.VoteTuple,
        m => m.MapFrom(
        s => s.GetVoteTuple()
//-----------^
     ));
like image 36
Andrew Whitaker Avatar answered Jan 25 '26 05:01

Andrew Whitaker



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!