2010-09-14 137 views
1

我已经更新了我的问题,因为我意识到我的代码是原始问题的原因。但是,在进一步调查问题时,我现在遇到了在映射过程中发生在我的代码中的异常,但我无法捕获映射表达式扩展。AutoMapper:为什么这个异常没有被捕获

基本上,当“dictionaryKey”包含字典中找不到的值时,下面的代码将抛出keynotfoundexception。至于Automapper而言,字典中被映射的源对象保持并请dictionaryKeys是从目标对象上的性质(被映射到):

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

的automapper扩展类如下所示完整地,我已经添加了对该行的注释,导致对上述代码的调用,抛出异常。问题是它没有被周围的代码所捕获,而是被抛出到Mapper.Map < ...>(...)调用。是什么原因导致这个问题,为什么是例外而不是try/catch块内的try catch块捕获(我已经添加了破发点,以确认例外的GetValue(被抛出...)的代码。

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是automapper内部工作的静态包装类,这就是在IMappingExpression的实现中没有捕获到异常的原因,而是冒泡到触发地图调用本身的代码?

+0

什么是你想实现呢? – Omu 2010-09-24 19:29:23

+0

我正在学习automapper,并遇到一些问题 - 在这种情况下,我试图映射(通过名称)基本上相当于字典中的名称/值对的目标类中的属性。如果目标类包含不在字典中的属性,则会引发异常(如您所期望的)。但是我无法捕获异常,exp.ForMember调用包含抛出异常的代码,但围绕它的try/catch不捕获异常。我试图理解为什么和我能做些什么来解决它。 – 2010-09-26 10:32:31

回答

0

这可能是一个愚蠢的问题,但为什么你不允许在你允许数据访问字典之前进行containsKey?

+0

这里提出的实际问题是,为什么try/catch块没有处理异常 - 而是由其他东西处理,重新升起并被捕获到更高的堆栈 - 这不是我们想要发生的事情。 但这是一个很好的观点,这里的代码只是在更大,更完整的代码中复制问题。如果我们可以避开它,我们不想添加一个检查到ContainsKey,因为它改变了代码库来解决automapper问题。理想情况下,我们的映射表达式最终将能够处理它(通过在那里进行正确的检查没有例外)。 – 2010-09-26 16:05:22

0

这是黑暗中的镜头,但有可能抛出的“Exception”实际上并不是从Exception中派生出来的?请注意对“Why is UnhandledExceptionEventArgs.ExceptionObject an object and not an Exception?”问题的回答:

这不能被键入到Exception,因为可以在.Net中引发不会从System.Exception派生的对象。这在C#或VB.Net中是不可能的,但在其他基于CLR的语言中是可能的。因此API必须支持这种可能性并使用类型对象。

所以虽然它不应该是null,它实际上可能不是一个System.Exception。

见CLI规范第10.5(特别是CLS规则40)了解更多详情

+0

我的代码抛出的异常是KeyNotFoundException(这是预期的)。在调试模式下,我可以看到这被抛出,然后它成为Automapper.AutoMapperMappingException的内部异常(这又是另一个Automapper.AutoMapperMappingException的内部异常) – 2010-09-28 08:20:47