2010-09-14 6 views
1

J'ai mis à jour ma question en constatant que mon code était la cause du problème d'origine. Cependant, en étudiant le problème plus loin, j'ai maintenant rencontré une exception qui se produit dans mon code pendant le processus de mappage, mais je suis incapable de capturer dans mon extension d'expression de mappage. Fondamentalement, le code ci-dessous va lancer une exception keynotfound lorsque "dictionaryKey" contient une valeur introuvable dans le dictionnaire. En ce qui Automapper concerne, le dictionnaire est tenu dans l'objet source étant cartographiés et les dictionaryKeys demandées ne sont pas des propriétés de l'objet cible (à être mis en correspondance):AutoMapper: Pourquoi cette exception n'est-elle pas interceptée?

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

La classe d'extension automapper est illustré ci-dessous en entier, j'ai ajouté des commentaires à la ligne qui provoque l'appel au code ci-dessus, lançant l'exception. Le problème est qu'il n'est pas intercepté par le code qui l'entoure, mais est renvoyé à l'appel Mapper.Map < ...> (...). Quelles sont les causes de cette question, pourquoi est l'exception et non pris dans le bloc catch try (j'ai ajouté des points d'arrêt pour confirmer exception est levée dans GetValue (...) par le code dans le bloc try/catch.

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; 
} 

MISE à JOUR Alors que le est jeté « clé introuvable exception » dans l'appel GetValue, il est enveloppé dans un AutoMapper.AutoMappingException qui bouillonnait sur la ligne ci-dessous:

client client = Mapper.Map (record

Bien sûr, en appelant Mapper.Map pour ces objets w mal déclencher mon implémentation de IMappingExpression pour effectuer le mappage tel qu'il a été configuré comme suit:

Mapper.CreateMap(). ConvertFromDictionary (propName => propName); Comme Automapper est une classe d'encapsulation statique autour des rouages ​​internes d'automapper, est-ce la raison pour laquelle l'exception n'est pas interceptée dans l'implémentation de IMappingExpression, mais est passée au code qui a déclenché l'appel cartographique lui-même?

+0

ce que vous essayez d'atteindre de toute façon? – Omu

+0

Je suis en train d'apprendre automapper et j'ai rencontré quelques problèmes - Dans cette situation, j'essaie de mapper (par nom) ce qui équivaut essentiellement à une paire nom/valeur dans un dictionnaire à des propriétés dans la classe cible. Si la classe cible contient une propriété qui ne figure pas dans le dictionnaire, elle déclenche une exception (comme vous pouvez vous y attendre).Toutefois, je ne parviens pas à capturer l'exception, l'appel exp.ForMember contient le code qui déclenche l'exception, mais le try/catch qui l'entoure ne capture pas l'exception. J'essaie de comprendre pourquoi et ce que je peux faire pour le résoudre. –

Répondre

0

dude cela peut être une question idiote, mais pourquoi ne faites-vous pas containKey avant d'autoriser l'accès aux données de votre dictionnaire?

+0

La vraie question posée ici est pourquoi l'exception n'est pas gérée par le bloc try/catch - à la place, elle est gérée par autre chose, re-raise et est attrapée plus haut dans la pile - pas quelque chose que nous voulons faire. Mais c'est un bon point et le code ici est juste pour répliquer le problème dans un code plus grand et plus complexe. Nous ne voulons pas ajouter une vérification à ContainsKey si nous pouvons nous en sortir car cela change la base de code juste pour contourner automapper. Idéalement, notre expression de mappage sera capable de gérer cela (sans exception, en faisant les vérifications correctes ici). –

0

Ceci est un tir dans l'obscurité, mais est-il possible que l'exception émise ne provienne pas d'Exception? Notez la réponse à la question « Why is UnhandledExceptionEventArgs.ExceptionObject an object and not an Exception? »:

Ce ne peut pas être dactylographiées à l'exception car il est possible de lancer des objets dans .Net qui ne dérivent pas de System.Exception. Ceci n'est pas possible en C# ou VB.Net mais c'est possible dans d'autres langages basés sur CLR. L'API doit donc prendre en charge cette possibilité et utiliser l'objet type.

Ainsi, même s'il ne doit jamais être nul, il se peut qu'il ne soit pas une exception System.Exception.

section spec Voir CLI 10.5 (CLS spécifiquement règle 40) pour plus de détails

+0

L'exception levée par mon code est KeyNotFoundException (ce qui est attendu). En mode débogage, je peux voir que cela est jeté, il finit par être une exception interne d'une Automapper.AutoMapperMappingException (qui est à son tour une exception interne d'une autre Automapper.AutoMapperMappingException) –

Questions connexes