6
votes

Impossible de lancer l'objet de type MyObject pour taper MyObject

J'ai ce scénario dans lequel une méthode WebService que je prends en C # renvoie un objet métier, lors de l'appel de la méthode WebService avec le code suivant, je reçois l'exception "Impossible de lancer l'objet de type Contactinfo pour taper contactInfo" dans la référence CLASSE .CS DE LA RÉFÉRENCE WEB

CODE: STRAND> P>

ContactInfo contactInfo = new ContactInfo();
Contact contact = new Contact();

contactInfo = contact.Load(this.ContactID.Value);


1 commentaires

Avez-vous mis à jour votre référence Web récemment?


7 Réponses :


10
votes

Ceci est parce que l'un des objets code> contactInfo code> est un proxy de service Web, et se trouve dans un espace de noms différent.

C'est un problème connu avec les services Web de style ASMX. Dans le passé, j'ai mis en place une copie automatique peu profonde pour travailler autour d'elle ( Voici comment , bien que si je le faisais à nouveau, je regarderais probablement Automapper à la place) . P>

Par exemple, si vous avez un assemblage avec la classe suivante: p> xxx pré>

et vous renvoyez une instance d'une méthode Web: p> xxx pré>

puis lorsque vous ajoutez la référence Web à votre projet client, vous obtenez réellement ceci: p> xxx pré>

Cela signifie que si, Dans votre demande client, vous appelez le service Web pour obtenir un contactInfo code>, vous avez cette situation: p>

namespace MyClientProject
{
    public class MyClientClass
    {
        public void AskWebServiceForContactInfo()
        {
            using (var service = new DoSomethingService())
            {
                MyClientProject.DoSomethingService.ContactInfo contactInfo = service.GetContactInfo(1);

                // We actually get a new object here, of the correct namespace
                MyProject.ContactInfo localContactInfo = ShallowCopy.Copy<MyClientProject.DoSomethingService.ContactInfo, MyProject.ContactInfo>(contactInfo);
            }
        }
    }
}


0 commentaires

0
votes

Comment référencez-vous la classe dans votre projet de service Web ainsi que le projet de consommateur? Si vous avez simplement utilisé un lien de fichier, cela pourrait bien expliquer la cause de l'erreur. La façon dont la sérialiasation fonctionne pour .NET (services Web ou autrement je crois) consiste à utiliser la réflexion pour charger / vider les données d'un objet. Si les fichiers sont simplement liés, ils sont réellement compilés à différents types dans différents assemblages, ce qui expliquerait pourquoi vous avez le même nom mais que vous ne pouvez pas lancer entre eux. Je recommande de créer une bibliothèque «Core» que le service Web et le projet de consommateur se réfère, et contient la classe contactInfo que vous utilisez partout.


0 commentaires

0
votes

Ce n'est pas un problème - c'est une fonctionnalité.

Ce sont deux classes indépendantes. Comparez les deux et remarquez que la classe de proxy n'a aucun des constructeurs, méthodes, indexeurs ou autres comportements de la classe d'origine. C'est exactement la même chose qui se produirait si vous consommez le service ASMX avec un programme Java.


3 commentaires

@Downvoter: Vous voulez que quelqu'un se soucie de ce que vous pensez? Ensuite, vous devrez dire ce que vous pensez. "-2" ne dit pas grand chose. Au lieu de cela, dites pourquoi vous avez bownd.


Cela ne devrait pas se comporter de cette façon. Nous avons cette question lors de l'utilisation d'un proxy généré uniquement, pas lors de l'utilisation de la méthode Createcharnel, mais notre problème est identique à ce poste. Je ne pense pas que cela soit censé être une fonctionnalité.


@schmoopy: Il utilise des services Web ASMX, pas WCF. Il n'y a pas de méthode Createchannel .



1
votes

Comme plusieurs des autres réponses ont suggéré, c'est parce que .net les voit deux classes différentes. Personnellement, je recommanderais d'utiliser quelque chose comme Automapper . Je l'utilise et cela semble assez génial. Vous pouvez copier vos objets dans 1-2 lignes de code.

Mapper.CreateMap<SourceClass, DestinationClass>();
destinationInstance = Mapper.Map<SourceClass, DestinationClass>(sourceInstance);


0 commentaires

0
votes

On dirait que vous avez deux classes différentes aux deux extrémités. Votre application a la classe ContactInfo et votre site WebService dispose également de la classe ContactInfo. Les deux sont deux classes complètement différentes. Une façon est d'utiliser la classe WebService de votre côté. Si vous utilisez ContacterInfo dans votre service Web, il sera sérialisé et sera disponible du côté client à utiliser.


0 commentaires

1
votes

En réalité, ce n'est pas un bug. C'est un problème avec les changements de version de votre propre projet! Parce que votre exécution finale n'utilise pas les références importées d'origine sur la compilée!

Par exemple, je faisais un serveur de discussion, client. J'ai utilisé une structure de paquets pour transmettre des données sur le projet client. Puis importé la même référence au projet de serveur.

Lors de la coulée paquet de paquets = (paquet) binarinformatter.deserialize (flux); j'ai la même erreur. Étant donné que la référence d'exécution réelle sur le projet Server n'est pas la référence maintenant au projet client! Parce que j'ai un projet client reconstruit plusieurs fois après!

en casting = () Le nouvel objet doit toujours être une version plus récente ou la même version que l'ancien objet!

Alors, ce que j'ai fait, j'ai construit un projet distinct pour créer une DLL pour la classe de paquets et importé le fichier DLL aux deux projets.

Si j'ai fait une modification de la classe de paquets, je dois importer la référence à la fois au client et au serveur.

Puis le casting ne donnera pas à l'exception ci-dessus!


0 commentaires

0
votes

Vous pouvez également modifier votre fichier de références.cs généré par Visual Studio lorsque la référence Web est ajoutée. Si vous supprimez les classes générées par procuration et ajoutez une référence (à l'aide de déclarations) à vos cours personnelles, vous pourrez les utiliser immédiatement, sans copie / réflexion peu profonde ou mappage lourde. (Mais vous devrez ré-appliquer votre modification si vous régénérez la couche proxy).

J'ai également essayé de sérialiser l'objet proxy et de les désérialiser dans mes classes DTO, mais c'était des ressources assez lourdes sage, donc j'ai fini par modifier les références CS Couche générée.

J'espère que cela aidera les autres personnes à venir ici :)

gentiment.


0 commentaires