I am currently using AutoMapper in my c# MVC project and have come across an issue converting from a integer to a string.
I have two classes:
public class Job
{
public string Prefix { get; set; }
public int JobNumber { get; set; }
public int Year { get; set }
public int JobPriority { get; set; }
public virtual EntityPriority EntityPriority { get; set; }
}
public class JobViewModel
{
public string JobNumberFull { get; set; }
{
Using Automapper I would like to join all three properties in the Job class to form a string which will then be mapped to JobNumberFull in the JobViewModel class.:
Prefix-JobNumber-Year
To start I have kept things simple and not concatenated the fields into a string, I have just tried to take JobNumber (int) and map it to JobNumberFull (string) as follows:
Mapper.CreateMap<int, string>().ConvertUsing(Convert.ToString);
Mapper.CreateMap<Job, JobViewModel>()
.ForMember(d => d.JobPriorityId, opt => opt.MapFrom(s => s.EntityPriority.EntityPriorityID))
.ForMember(d => d.JobPriorityLevel, opt => opt.MapFrom(s => s.EntityPriority.PriorityLevel))
.ForMember(d => d.JobNumberFull, opt => opt.MapFrom(s => s.JobNumberYear));
Mapper.AssertConfigurationIsValid();
var jobsList = db.Jobs.Where(j => j.OperationID == operationId).Project().To<JobViewModel>().ToList();
When I run this I get the following error
Type 'System.String' does not have a default constructor
I know this is to do with
Convert.ToString
but I'm not sure what to do about it! I can do Convert.ToInt32 when going from a string to an int and it works like a treat. Do I need to create a custom type converter?
How would I go about getting the string prefix-jobnumber-year?
All help much appreciated.
UPDATE
Thanks to the help of Jeremy and the AutoMapper website I have managed to get this working here is my solution, please feel free to comment if you think there is a more elegant solution:
public class Job
{
public string Prefix { get; set; }
public int JobNumber { get; set; }
public int Year { get; set; }
public int JobPriority { get; set; }
public virtual EntityPriority EntityPriority { get; set; }
}
public class JobViewModel
{
public int JobNumber { get; set; }
public int Year { get; set; }
public string JobNumberFull { get; set; }
}
public enum EntityPriority
{
Normal = 0,
High
}
public interface IValueResolver
{
ResolutionResult Resolve(ResolutionResult source);
}
public class JobNumberConverter : ValueResolver<Job, string>
{
protected override string ResolveCore(Job source)
{
return string.Format("{0}-{1}-{2}", source.Prefix, source.JobNumber, source.Year);
}
}
public ActionResult Index()
{
Mapper.CreateMap<Job, JobViewModel>()
.ForMember(jvm => jvm.JobNumberFull, opt => opt.ResolveUsing<JobNumberConverter>());
Mapper.AssertConfigurationIsValid();
List<Job> jobs = new List<Job>();
Job j = new Job()
{
JobNumber = 1,
Prefix = "prefix",
Year = 2013,
EntityPriority = EntityPriority.High,
JobPriority = 2
};
Job j2 = new Job()
{
JobNumber = 2,
Prefix = "prefix",
Year = 2013,
EntityPriority = EntityPriority.High,
JobPriority = 2
};
Job j3 = new Job()
{
JobNumber = 3,
Prefix = "prefix",
Year = 2013,
EntityPriority = EntityPriority.High,
JobPriority = 2
};
jobs.Add(j);
jobs.Add(j2);
jobs.Add(j3);
var jobViewModels = jobs.Select(job => Mapper.Map<JobViewModel>(job));
return View();
}
I think you can use the ResolveUsing
method to solve it.
Mapper.CreateMap<Job, JobViewModel>()
.ForMember(d => d.JobNumberFull,
exp =>
exp.ResolveUsing(j => string.Format("{0}-{1}-{2}", j.Prefix, j.JobNumber, j.Year)));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With