1 votes

Obtention d'un mauvais code généré par "Update Service Reference" (mise à jour de la référence du service)

En VB.NET (à l'aide de Visual Studio 2008), mon service WCF possède une interface semblable à celle-ci :

<ServiceContract()> _
Public Interface IThingService
    <OperationContract()> _
    Function GetThingByNumber(ByVal thingNumber As MyKeyClass) As Thing
    <OperationContract()> _
    Function GetThing(ByVal thingId As Guid) As Thing

    ' ...

End Interface

J'ai récemment modifié deux projets avec un code similaire pour utiliser un basicHttpBinding plutôt qu'un wsHttpBinding. Tout se compile bien du côté du service. Maintenant, dans l'application cliente, je choisis "Update Service Reference". Dans l'un des projets, le fichier reference.vb résultant semble correct - moins de 100 lignes avec des enveloppes simples pour chaque méthode. Cependant, dans l'autre, le reference.vb résultant ne semble pas comprendre ce qu'est le service. J'obtiens un reference.vb de plus de 1000 lignes qui ressemble à ceci :

 '------------------------------------------------------------------------------
 ' <auto-generated>
 '     This code was generated by a tool.
 '     Runtime Version:2.0.50727.3053
 '
 '     Changes to this file may cause incorrect behavior and will be lost if
 '     the code is regenerated.
 ' </auto-generated>
 '------------------------------------------------------------------------------
 Option Strict On
 Option Explicit On
 Imports System.Data
 Namespace ThingService

 <System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0"),  _
 System.ServiceModel.ServiceContractAttribute(ConfigurationName:="GetThingByVersion.IGetThingByVersion")>  _
 Public Interface IThingService

    'CODEGEN: Parameter 'GetThingByNumberResult' requires additional schema information that cannot be captured using the parameter mode. The specific attribute is 'System.Xml.Serialization.XmlElementAttribute'.
    <System.ServiceModel.OperationContractAttribute(Action:="http://tempuri.org/ThingService/GetThingByVersion", ReplyAction:="http://tempuri.org/ hingService/GetThingByVersionResponse"),  _
     System.ServiceModel.XmlSerializerFormatAttribute()>  _
    Function GetThingByNumber(ByVal request As ThingService.GetThingByVersionRequest) As ThingService.GetThingByVersionResponse

    'CODEGEN: Parameter 'GetThingResult' requires additional schema information that cannot be captured using the parameter mode. The specific attribute is 'System.Xml.Serialization.XmlElementAttribute'.
    <System.ServiceModel.OperationContractAttribute(Action:="http://tempuri.org/ThingService/GetThing", ReplyAction:="http://tempuri.org/ThingService/GetThingResponse"),  _
     System.ServiceModel.XmlSerializerFormatAttribute()>  _
    Function GetThing(ByVal request As ThingService.GetThingRequest) As ThingService.GetThingResponse
'...
End Interface

 '''<remarks/>
 <System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "2.0.50727.3082"),  _
 System.SerializableAttribute(),  _
 System.Diagnostics.DebuggerStepThroughAttribute(),  _
 System.ComponentModel.DesignerCategoryAttribute("code"),  _
 System.Xml.Serialization.XmlTypeAttribute([Namespace]:="http://schemas.datacontract.org/2004/07/ThingLibraryCore")>  _
 Partial Public Class MyKeyClass
    Inherits Object
    Implements System.ComponentModel.INotifyPropertyChanged

    Private concatenatedThingNumberField As String
    Private ThingNumberField As Integer
    Private ThingNumberFieldSpecified As Boolean

 '... goes on and on...

C'est comme si le code généré ne connaissait rien de mon interface de service réelle. Avez-vous une idée de la façon de résoudre ce problème ? Merci d'avance.

EDIT : Il semble que je doive m'assurer que le serveur peut utiliser le DataContractSerializer et non le XmlSerializer : voir http://blogs.msdn.com/sonuarora/archive/2007/06/16/contract-generation-from-wsdl-xml-schema-datacontractserializer-vs-xmlserializer.aspx . Quelqu'un sait-il comment je peux déterminer ce qui, dans mon code (probablement dans la classe Thing), viole les restrictions relatives à DataContractSerializer ?

3voto

Matt Davis Points 22019

Honnêtement, je ne suis pas sûr de la réponse. Avez-vous essayé de supprimer la référence du service et de la recréer à partir de zéro ? Cela semble être le moyen le plus direct d'essayer de le réparer, surtout que vous avez fait des changements.

Je sais que vous n'avez pas demandé cela, mais en passant, j'ai personnellement renoncé à utiliser la fonction de référence de service dans Visual Studio. Voici un excellent vidéo qui décrit à quel point c'est facile à faire, à condition que vous soyez prêt à remanier un peu votre code. Comme il semble que vous soyez en charge à la fois du client et du serveur WCF, je pense que l'approche préconisée par Miguel vous serait extrêmement utile.

EDIT :

En réponse au commentaire de John Saunder, si vous êtes en charge à la fois du client et du serveur, vous feriez mieux, à mon avis, de refactoriser les contrats (contrats de service et de données) en un seul assemblage qui est partagé entre le client et le serveur. Lorsque vous ajoutez/mettez à jour une référence de service, tout ce que cela fait est de générer un code copie de ces contrats pour le client et ajoute ensuite le code passe-partout pour le proxy. Ainsi, en substance, vous avez deux définitions distinctes, mais identiques, de ces interfaces et classes, l'une du côté du serveur et l'autre du côté du client.

La raison pour laquelle j'ai abandonné cette méthode est que j'ai un service WCF hébergé dans un service Windows. Ce service était utilisé par des clients dans quatre assemblages distincts tout au long de mon projet. Chaque fois que j'apportais une modification au contrat de service/données pour le service WCF, je devais mettre à jour la référence du service dans les quatre assemblages qui utilisaient le service WCF. En refactorisant ces contrats en un seul assemblage partagé, je mets à jour cet assemblage, je recompile (ce que je devrais faire de toute façon), et je suis prêt à partir. Je n'ai plus besoin de me rappeler quels assemblages doivent être mis à jour.

Je réalise que de nombreux exemples sur le web parlent de la simplicité d'utilisation de l'outil svcutil, mais dans mon cas, c'est une surcharge inutile.

Jetez un coup d'œil à la vidéo et jugez par vous-même.

0voto

Prafull Maru Points 1

Assurez-vous que votre contrat de données contient uniquement les propriétés dont le type de retour est un type de données primitif ou tout autre type de données DataContact. Les types de données tels que DataSet et DataType qui nécessitent XMLSerialization convertiront votre contrat de données en MessegeContract et le générateur de code affichera simplement le même message que le commentaire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X