2010-09-14 2 views
1

Я обновил свой вопрос, поскольку понял, что мой код является причиной первоначальной проблемы. Однако при дальнейшем изучении проблемы я столкнулся с исключением, которое возникает в моем коде во время процесса сопоставления, но я не могу зафиксировать в своем расширении выражения отображения.AutoMapper: Почему это исключение не попало

В основном код ниже будет вызывать keynotfoundexception, когда «dictionaryKey» содержит значение, не найденное в словаре. Что касается Automapper касается, словарь удерживается в исходном объекте привязывается и dictionaryKeys запрашиваемые из свойств на целевом объекте (для отображения на):

класс
public dynamic GetValue(string dictionaryKey) 
{ 
    return _dictionary[dictionaryKey].Value; 
} 

Расширение automapper показано ниже в полном объеме, я добавил комментарии к строке, которая вызывает вызов кода выше, бросая исключение. Проблема в том, что она не попадает в окружающий код, а бросается полностью на вызов Mapper.Map < ...> (...). Что вызывает этот вопрос, почему исключение не поймало в блоке попытки поймать (я добавил точки разрыва, чтобы подтвердить исключение в GetValue (...) с помощью кода в блоке Try/поймать.

public static IMappingExpression<ActiveRecord, TDestination> ConvertFromDictionary<TDestination>(this IMappingExpression<ActiveRecord, TDestination> exp, Func<string, string> propertyNameMapper) 
{ 
    foreach (
     PropertyInfo pi in typeof (TDestination).GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) 
    { 
     if (!pi.CanWrite) 
     continue; 

     string propertyName = pi.Name; 
     propertyName = propertyNameMapper(propertyName); 

     try 
     { 
     // The following code will fail when the target read/write property does not exist in the 
     // source dictionary. This is thrown in GetValue as a KeyNotFoundException. But it is not 
     // caught in this try/catch. It makes it's way all the way up to the calling code 
     // i.e. var entity = Mapper.Map<ActiveRecord, EntityDetail>(activeRecord); 
     exp.ForMember(propertyName, cfg => cfg.MapFrom(r => r.ActiveFields.GetValue(propertyName))); 
     } 
     catch (Exception ex) 
     { 
     // This is never reached by the exception above 
     throw ex; 
     } 
    } 
    return exp; 
} 

UPDATE Хотя «ключ не найден исключение» брошен в вызове GetValue, она завернута в AutoMapper.AutoMappingException, который пузырилась на линии ниже:

клиента клиента = Mapper.Map (запись)

Конечно, вызов Mapper.Map для этих объектов w плохой запуск моей реализации IMappingExpression, чтобы сделать отображение, поскольку оно было настроено как:

Mapper.CreateMap(). ConvertFromDictionary (propName => propName);

Поскольку Automapper является статическим классом-оболочкой во внутренней обработке автоматов, это причина, по которой исключение не попадает в реализацию IMappingExpression, но барботируется до кода, который вызвал сам вызов карты?

+0

что вы пытаетесь достичь в любом случае? – Omu

+0

Я участвую в процессе обучения automapper и столкнулся с несколькими проблемами. В этой ситуации я пытаюсь сопоставить (по имени), что в основном составляет пару имя/значение в словаре для свойств в целевом классе. Если целевой класс содержит свойство, которое не находится в словаре, оно генерирует исключение (как и следовало ожидать).Однако я не могу зафиксировать исключение, вызов exp.ForMember содержит код, который генерирует исключение, но try/catch, который его окружает, не фиксирует исключение. Я пытаюсь понять, почему и что я могу сделать, чтобы решить эту проблему. –

ответ

0

чувак, это может быть глупый вопрос, но почему бы вам не сделатьKey, прежде чем разрешить доступ к данным в ваш словарь?

+0

Здесь возникает вопрос, почему исключение не обрабатывается блоком try/catch - вместо этого он обрабатывается чем-то другим, повторно поднимается и попадает выше стека - не то, что мы хотим. Но это хороший момент, и код здесь просто для того, чтобы реплицировать проблему в более крупном и дополненном коде. Мы не хотим добавлять чек в ContainsKey, если мы можем уйти от него, так как это изменяет базу кода только для работы с automapper. В идеале наше отображающее выражение сможет справиться с этим в конечном итоге (без исключений, возникающих при выполнении правильных проверок). –

0

Это выстрел в темноте, но возможно ли, что исключение «Исключение» на самом деле не происходит из-за исключения? Обратите внимание, ответ на вопрос «Why is UnhandledExceptionEventArgs.ExceptionObject an object and not an Exception?»:

Это не может быть введен в Exception, потому что это можно бросать предметы в .Net, которые не вытекают из System.Exception. Это невозможно в C# или VB.Net, но это возможно на других языках CLR. Следовательно, API должен поддерживать эту возможность и использует объект типа.

Так что, хотя он никогда не должен быть нулевым, на самом деле это не может быть исключение System.Exception.

См CLI раздел спецификации 10,5 (в частности CLS правило 40) для получения более подробной информации

+0

Исключение, созданное моим кодом, - KeyNotFoundException (что и следовало ожидать). В режиме отладки я вижу, что это выбрасывается, а затем становится внутренним исключением из Automapper.AutoMapperMappingException (которое, в свою очередь, является внутренним исключением другого Automapper.AutoMapperMappingException) –