Автоматическое преобразование 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решение может быть обобщено для всех strings, которые должны быть преобразованы в ints, определив метод расширения для 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;
}

для выполнения этой работы необходимо выполнить следующие шаги:

  1. сопоставление между источником и назначением должно добавить расширение сопоставления. Е. Г.:

    var config = new MapperConfiguration(cfg =>
    {
       // other mappings
    
       cfg.CreateMap<SrcType, DestType>().StringToIntMapping();
    });
    
  2. применить атрибут ко всем свойствам исходной строки это должно быть автоматически преобразовано в целочисленные значения


здесь более простой, но менее эффективный подход. Всякий раз, когда вы звоните картографу.Инициализируйте, не забудьте позвонить .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()));