AutoMapper requires Get Accessor to Set. CS0154 The property or indexer 'Id' cannot be used in this context because it lacks the get accessor

The Id property in my ViewModel class can be set, but not gotten as the setter encrypts the value. To get the value I have to use a either GetEncryptedId() or GetDecryptedId().

The ViewModel

public ViewModel
{
    public int _id;
    public int Id { set { _id = Encrypt(value); }
    public Child ChildProperty {get; set; }
}

public Child
{
    public int Id {get; set;} 
    public string Name {get; set; }
}

The problem here is that for some reason Auto Mapper wants a get accessor so it can set a value.

public ViewModelProfile()
{
    CreateMap<Model, ViewModel>().ForMember(vm => vm.Id, opt => opt.MapFrom(m => m.ChildProperty.Id))
}

This throws and error stating:

CS0154 The property or indexer 'Id' cannot be used in this context because it lacks the get accessor.
  1. Why does Auto Mapper require a 'Get Accessor' to set a value.
  2. Is there a configuration option to force a set and no get?

As a work around I've added a Get { return -1; }, but that is far from ideal.

Upvotes: 2

Views: 817

Answers (2)

Pranav Mishra
Pranav Mishra

Reputation: 456

This is how i did it:

 //Mapper Class

 public partial class AutoMapperConfig
 {
  public static MapperConfiguration UserLoginTovmLogin = null;

  public static void Mappings()
    {
        UserLoginTovmLogin = new MapperConfiguration(cfg =>
        cfg.CreateMap<User_Login, VmLogin>()
        .ForMember(conf => conf.LoginId, dto => dto.MapFrom(src => src.Login_Id))
        .ForMember(conf => conf.Passsword, dto => dto.MapFrom(src => src.Passsword)));
    }
  }
   //In your Data login class
   VmLogin IAuthRepository.Login(string loginId)
    {
        VmLogin login = new VmLogin();
        var result = //Your Data Logic
        AutoMapperConfig.UserLoginTovmLogin.CreateMapper().Map(result, login);
        return login; 
    }

Upvotes: 0

Jeroen Mostert
Jeroen Mostert

Reputation: 28799

This isn't a limitation of AutoMapper as such, but of the way its API is structured. The expression tree vm => vm.Id can't be constructed because this is, you've guessed it, a reference to the property getter, which isn't possible because there is no getter. Passing an expression tree as a strongly typed way of referencing a member is a standard technique; AutoMapper is by far not the only thing that would have problems with this. The fact that AutoMapper would not ultimately call the getter is immaterial in this case.

Fortunately, ForMember has an override that accepts the member name as a string, and using that avoids the problem with the expression tree:

CreateMap<Model, ViewModel>()
    .ForMember(nameof(ViewModel.Id), opt => opt.MapFrom(m => m.ChildProperty.Id))

Upvotes: 2

Related Questions