Автоматическое преобразование Mapper из строки в Int
Я создаю простое приложение MVC4
у меня есть automapper
Mapper.CreateMap<SourceClass, DestinationClass>()
.ForMember(dest => dest.IntphoneNo,
opt => opt.MapFrom(src => src.Stringphoneno));
IntphoneNo имеет тип данных int (IntphoneNo-переменная моего класса Person
)
Атрибут источника Stringphoneno имеет тип данных строка.
когда я сопоставляю, я получаю следующую ошибку.
исключение типа ' AutoMapper.AutoMapperMappingException произошел в AutoMapper.DLL но не был обработан в пользовательском коде
но когда я меняю Dataype IntphoneNo С int to строка тогда моя программа работает успешно.
к сожалению, я не могу изменить тип данных в моей модели
это любой способ изменить Datatupe в сопоставлении .. Что-то вроде ниже
.ForMember(dest => dest.IntphoneNo,
opt => opt.MapFrom(src => src.Int32(Stringphoneno));
после некоторых исследований я пришел на один шаг дальше ..
Если мой StringPhoneNo is = 123456
затем работает следующий код. Мне не нужно разбирать его на string
Mapper.CreateMap<SourceClass, DestinationClass>()
.ForMember(dest => dest.IntphoneNo,
opt => opt.MapFrom(src => src.Stringphoneno));
но когда мой StringPhoneNo = 12 3456 (есть пробел после 12), то мой код не работает. Есть ли способ обрезать пробелы в Stringphoneno (Stringphoneno Я получаю от webservice) в automapper.
что-то вроде ниже..
Mapper.CreateMap<SourceClass, DestinationClass>()
.ForMember(dest => dest.IntphoneNo,
opt => opt.MapFrom(src => src.Trim(Stringphoneno)));
4 ответов
Mapper.CreateMap<SourceClass, DestinationClass>()
.ForMember(dest => dest.IntphoneNo,
opt => opt.MapFrom(src => int.Parse(src.Stringphoneno)));
вот пример рабочего кода с использованием описанной карты
class SourceClass
{
public string Stringphoneno { get; set; }
}
class DestinationClass
{
public int IntphoneNo { get; set; }
}
var source = new SourceClass {Stringphoneno = "8675309"};
var destination = Mapper.Map<SourceClass, DestinationClass>(source);
Console.WriteLine(destination.IntphoneNo); //8675309
проблема, с которой вы можете столкнуться, когда он не может разобрать строку, одним из вариантов было бы использовать ResolveUsing:
Mapper.CreateMap<SourceClass, DestinationClass>()
.ForMember(dest => dest.intphoneno, opts => opts.ResolveUsing(src =>
{
double strphoneno;
double.TryParse(src.strphoneno, out strphoneno);
return strphoneno;
}));
Yuriy Faktorovich
решение может быть обобщено для всех string
s, которые должны быть преобразованы в int
s, определив метод расширения для IMappingExpression
и использование некоторых пользовательских атрибутов:
[AttributeUsage(AttributeTargets.Property)]
public class StringToIntConvertAttribute : Attribute
{
}
// tries to convert string property value to integer
private static int GetIntFromString<TSource>(TSource src, string propertyName)
{
var propInfo = typeof(TSource).GetProperty(propertyName);
var reference = (propInfo.GetValue(src) as string);
if (reference == null)
throw new MappingException($"Failed to map type {typeof(TSource).Name} because {propertyName} is not a string);
// TryParse would be better
var intVal = int.Parse(reference);
return intVal;
}
public static IMappingExpression<TSource, TDestination> StringToIntMapping<TSource, TDestination>(this IMappingExpression<TSource, TDestination> expression)
{
var srcType = typeof(TSource);
foreach (var property in srcType.GetProperties().Where(p => p.GetCustomAttributes(typeof(StringToIntConvertAttribute), inherit: false).Length > 0))
{
expression.ForMember(property.Name, opt => opt.MapFrom(src => GetIntFromString(src, property.Name)));
}
return expression;
}
для выполнения этой работы необходимо выполнить следующие шаги:
-
сопоставление между источником и назначением должно добавить расширение сопоставления. Е. Г.:
var config = new MapperConfiguration(cfg => { // other mappings cfg.CreateMap<SrcType, DestType>().StringToIntMapping(); });
применить атрибут ко всем свойствам исходной строки это должно быть автоматически преобразовано в целочисленные значения
здесь более простой, но менее эффективный подход. Всякий раз, когда вы звоните картографу.Инициализируйте, не забудьте позвонить .ToInt (), или вы получите ошибку времени выполнения.
public class NumberTest
{
public static void Main(string[] args)
{
Console.WriteLine("".ToInt());
// 0
Console.WriteLine("99".ToInt());
// 99
}
}
public static class StringExtensions
{
public static int ToInt(this string text)
{
int num = 0;
int.TryParse(text, out num);
return num;
}
}
// Use like so with Automapper
.ForMember(dest => dest.WidgetID, opts => opts.MapFrom(src => src.WidgetID.ToInt()));