2

I am trying to map a service model to a view model using Mapster.

My service model contains a list of strings.

My View Model contains a list of type RolesViewModel.

RolesViewModel has a string property named RoleName.

Below are my models

public class UserViewModel
{
    [Display(Name = "Email address")]
    [Required(ErrorMessage = "The email address is required")]
    [EmailAddress(ErrorMessage = "Invalid Email Address")]
    public string Email { get; set; }

    public List<RolesViewModel> Roles { get; set; } = new List<RolesViewModel>();
}

public class RolesViewModel
{
    public RolesViewModel(string roleName)
    {
        RoleName = roleName;
    }

    public string RoleName { get; set; }
}

//Service Model
public class User
{
    public string Email { get; set; }
    public List<string> Roles { get; set; } = new List<string>();
}

//Service Return Model
public class ServiceResponse<T>
{
    public bool Success { get; set; } = false;
    public Data.Enums.Exception Exception { get; set; }
    public T ResponseModel { get; set; }

    /// <summary>
    /// Allows Service Response <T> to be cast  to a boolean. 
    /// </summary>
    /// <param name="response"></param>
    public static implicit operator bool(ServiceResponse<T> response)
    {
        return response.Success;
    }
}

The line in my controller where I am applying the mapping is as follows:

List<UserViewModel> viewModel = serviceResponse.ResponseModel.Adapt<List<UserViewModel>>();

And finally my mapping config

public class Mapping : IRegister
{
    public void Register(TypeAdapterConfig config)
    {
        config.NewConfig<Tracer, TracerViewModel>();
        config.NewConfig<Asset, AssetViewModel>();
        config.NewConfig<Project, ProjectViewModel>();
        config.NewConfig<User, UserViewModel>();
        config.NewConfig<RolesViewModel, string>();
    }
}

To try and get the mapping to work I have tried to update the mapping config to:

public class Mapping : IRegister
{
    public void Register(TypeAdapterConfig config)
    {
        config.NewConfig<Tracer, TracerViewModel>();
        config.NewConfig<Asset, AssetViewModel>();
        config.NewConfig<Project, ProjectViewModel>();
        config.NewConfig<User, UserViewModel>().Map(dest => dest.Roles.Select(t => t.RoleName.ToString()).ToList(), src => src.Roles);
        config.NewConfig<UserViewModel, User>().Map(src => src.Roles, dest => dest.Roles.Select(t => t.RoleName.ToString()).ToList());
        config.NewConfig<RolesViewModel, string>();
    }
}

But I get the error message: "Invalid cast from 'System.String' to 'ViewModels.RolesViewModel'.

Could anyone please advise me what config I need in my mapping class.

j9070749
  • 815
  • 2
  • 11
  • 22

2 Answers2

0

It seems you are trying to force a directmap between a string and an object in the last line of your Register function.The concept of mapster and other object-to-object mappers is that they map objects to other objects. You can't map an object to a CLR reference type. To achieve what you are trying to do the best way is to create a function that receives a string and handles it properly.

Felipe Torres
  • 292
  • 2
  • 10
0

As Mapster says, when mapping to strings it will use ToString or Parse to perform the mapping:

var s = 123.Adapt<string>(); //equal to 123.ToString(); 
var i = "123".Adapt<int>();  //equal to int.Parse("123");

so you will need to implement a conversion routine that tells mapster how to parse from String to RolesViewModel.

gbjbaanb
  • 51,617
  • 12
  • 104
  • 148