Question

In VB.NET (using Visual Studio 2008) my WCF service has an interface something like:

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

    ' ...

End Interface

I recently changed two projects with similar code to use a basicHttpBinding rather than a wsHttpBinding. Everything compiles well on the service side. Now, in the a client app I choose "Update Service Reference". In one project, my resulting reference.vb seems correct--under 100 lines with simple wrappers for each method. However, in the other, the resulting reference.vb can't seem to understand what the service is. I get a reference.vb of over 1000 lines that looks like:

 '------------------------------------------------------------------------------
 ' <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...

It's as if the code generated knows nothing of my actual service interface. Any idea how to troubleshoot this? Thanks in advance.

EDIT: Looks like I need to make sure that the server can use the DataContractSerializer and not the XmlSerializer: see http://blogs.msdn.com/sonuarora/archive/2007/06/16/contract-generation-from-wsdl-xml-schema-datacontractserializer-vs-xmlserializer.aspx . Does anyone know how I can figure out what in my code (probably in Class Thing) is violating the restrictions on DataContractSerializer?

Was it helpful?

Solution

Honestly, I'm not sure what the answer is. Have you tried deleting the service reference and re-creating it from scratch? That would seem to be the most straightforward way to try to fix it, especially since you've made changes.

I know you didn't ask this, but as an aside, I have personally gotten away from using the service reference feature in visual studio altogether. Here is an excellent video that describes how easy it is to do, providing you are willing to refactor your code a little bit. Since it sounds like you are in charge of both WCF client and server, I think you'd benefit tremendously from the approach Miguel advocates.

EDIT:

In response to John Saunder's comment, if you are in charge of both the client and the server, you'd be better off, in my opinion, to re-factor the contracts (service and data contracts) into a single assembly that is shared between the client and server. When you add/update a service reference, all that does is make a code-generated copy of these contracts for the client and then adds the boilerplate code for the proxy. So in essence, you have two separate, but identical, definitions of these interfaces and classes, one on the server side and one on the client side.

The reason I migrated from doing this is because I have a WCF service hosted in a Windows service. This service was used by clients in four separate assemblies throughout my project. Every time I made a change to the service/data contract for the WCF service, I had to go update the service reference in the four assemblies that used the WCF service. By refactoring these contracts to a single, shared assembly, I update that assembly, re-compile (which I would have to do anyway), and I'm ready to go. I no longer have to remember which assemblies need to be updated.

I realize that many of the examples on the web talk about the simplicity of using the svcutil tool, but in my case, it's unnecessary overhead.

Take a look at the video and judge for yourself.

OTHER TIPS

Make sure all your datacontract contains only those properties which has return type as either primitive data type or any other dataContact. Datatype such as DataSet and DataType which requires XMLSerialization will convert your datacontract to MessegeContract and code generator simply displays the same messege as comment.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top