2010-09-14 142 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