Immer schlecht generierten Code von „Update Service Reference“
-
18-09-2019 - |
Frage
In VB.NET (unter Verwendung von Visual Studio 2008) mein WCF-Dienst verfügt über eine Schnittstelle so etwas wie:
<ServiceContract()> _
Public Interface IThingService
<OperationContract()> _
Function GetThingByNumber(ByVal thingNumber As MyKeyClass) As Thing
<OperationContract()> _
Function GetThing(ByVal thingId As Guid) As Thing
' ...
End Interface
Ich änderte vor kurzem zwei Projekte mit ähnlichem Code einen Basichttpbinding eher als ein wsHttpBinding zu verwenden. Alles kompiliert gut auf der Serviceseite. Jetzt, in der ein Client-Anwendung I "Update Service Reference" wählen. In einem Projekt, scheint meine resultierende Reference.vb richtig - unter 100 Zeilen mit einfachen Wrapper für jede Methode. Doch in der anderen kann die resultierende Reference.vb nicht scheinen zu verstehen, was der Service ist. Ich erhalte eine Reference.vb von über 1000 Zeilen, die wie folgt aussieht:
'------------------------------------------------------------------------------
' <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...
Es ist, als ob der Code generiert weiß nichts von meiner eigentlichen Service-Schnittstelle. Jede Idee, wie diese zu beheben? Vielen Dank im Voraus.
EDIT: Sieht aus wie sie müssen dafür sorgen, dass der Server die DataContractSerializer verwenden kann und nicht die XmlSerializer: siehe http://blogs.msdn.com/sonuarora/archive/2007/06/16/contract-generation -von-wsdl-xml-schema-DataContractSerializer-vs-xmlserializer.aspx . Wer weiß, wie ich herausfinden kann, was in meinem Code (wahrscheinlich in der Klasse Thing) ist, die Beschränkungen für DataContractSerializer verletzen?
Lösung
Ehrlich gesagt, ich bin nicht sicher, was die Antwort ist. Haben Sie versucht, den Dienstverweis zu löschen und es von Grund auf neu erstellt? Das scheint die einfachste Weg, um zu versuchen, es zu beheben, vor allem, da Sie Änderungen vorgenommen haben.
Ich weiß, Sie haben das nicht fragen, sondern als beiseite, ich habe persönlich weg in Visual Studio ganz von der Nutzung des Service Referenzmerkmal bekommen. Hier ist ein ausgezeichnetes Video , die beschreibt, wie einfach es zu tun ist, können Sie die Bereitstellung bereit sind, Ihren Code ein wenig Refactoring. Da es klingt wie Sie für beide WCF-Client und Server sind, ich glaube, Sie enorm von dem Ansatz profitieren würden Miguel befürwortet.
EDIT:
Als Antwort auf John Saunder Kommentar, wenn Sie für beide dem Client und dem Server, dann würden Sie besser dran, meiner Meinung nach, erneut Faktor die Verträge (Service und Datenverträge) in einer einzigen Baugruppe dass zwischen dem Client und dem Server geteilt. Wenn Sie hinzufügen / einen Dienstverweis aktualisieren, alles, was tut, ist eine Code-generierte machen Kopie diese Verträge für den Client und fügt dann den Standardcode für den Proxy. Also im Grunde haben Sie zwei getrennte, aber identische, Definitionen dieser Schnittstellen und Klassen, einen auf der Server-Seite und eine auf der Client-Seite.
Der Grund, warum ich zu tun, das migriert ist, weil ich einen WCF-Dienst in einem Windows-Dienst gehostet habe. Dieser Service wurde von den Kunden in vier getrennten Baugruppen in meinem Projekt verwendet. Jedes Mal, wenn ich eine Änderung des Service / Datenvertrag für den WCF-Dienst gemacht, ich hatte den Dienstverweis in den vier Baugruppen gehen zu aktualisieren, die den WCF-Dienst verwendet. Durch Refactoring diese Verträge zu einer einzigen, gemeinsamen Versammlung, aktualisiere ich, dass die Baugruppe, Re-Kompilierung (was ich hätte ohnehin tun), und ich bin bereit zu gehen. Ich muss nicht mehr erinnern, welche Baugruppen aktualisiert werden müssen.
Ich weiß, dass viele der Beispiele auf der Web-Diskussion über die Einfachheit des svcutil Werkzeug zu verwenden, aber in meinem Fall ist es nicht notwendig, Overhead.
Werfen Sie einen Blick auf das Video und für sich selbst beurteilen.
Andere Tipps
Stellen Sie sicher, dass alle Datacontract enthalten diese Eigenschaften nur die Art entweder als primitiven Datentyp oder einen anderen Datacontact zurückgeben muß. Datentyp wie DataSet und Datatype, die XmlSerialization konvertiert Ihre Datacontract erfordert zu MessegeContract und Code-Generator zeigt einfach die gleiche messege als Kommentar.