views:

287

answers:

2

I've updated an existing WCF application to add protobuf-net support. Basically, I've :

  • added protobuf-net.dll (.net 3.0) as a reference in the assembly containing all my data objects. This assembly is referenced by both my server and my client

  • replaced [DataMember] by [DataMember(Order = x)] (using increasing ints as x)

  • Updated all my OperationContracts with the ProtoBehavior attribute

  • Updated my service reference

From the client, I call this method on the server :

[OperationContract(IsOneWay = false), ProtoBehavior]
ConnectionData Join(string userId, string Password);

with ConnectionData being defined like this :

[DataContract]
public class ConnectionData
{
    [DataMember(Order = 1)]
    public ConnectionStatusEnum ConnectionStatus; // this is a normal enum with five elements

    // .....

    [DataMember(Order = 5)]
    public bool MustChangePassword;
}

Now, here's what's going on :

  • If I debug the server, I see that a ConnectionData object is correctly initialized and returned in the Join method

  • If I debug the client, I see a null object being returned from my Join call

  • I've enabled WCF tracing to the maximum verbosity, nothing caught my eye in the Server's log, but in the Client log file I've seen this warning message :

System.Runtime.Serialization.ElementIgnored
An unrecognized element was encountered in the XML during deserialization which was ignored.
Element http://tempuri.org/%3Aproto

I've sniffed my network trafic, and I don't blame protobuf-net for not being able to deserialize this :

<s:Body><JoinResponse xmlns="http://tempuri.org/"&gt;&lt;proto/&gt;&lt;/JoinResponse&gt;&lt;/s:Body&gt;

How can I further troubleshoot the problem and get protobuf-net to serialize my messages correctly?


I'm using protobuf-net r275

A: 

Sorry for the delay - working hours, etc. Do both ends know about this change? Unfortunately, the WCF integration doesn't play very nicely with "mex"-generated proxies at the client, but works OK with assembly sharing.

Alternatively, there is some work in progress to use an endpoint behaviour that can be specified in the config; this isn't 100%, but should be very soon - and allows WCF to use protobuf-net transparently, with no midifications to the service contract (although the members still need to know about it, either through [ProtoMember(n)] etc, or [DataMember(Order=n)].

Marc Gravell
Hi Marc; thanks for your quick answer. The shared assembly (which was the only one modified so far), the client and the server are in a single .sln and both reference the shared assembly project. Does that answer your question?
Brann
re app.config support, if I understand correctly, that would definitely be a very nice addition as it would allow for providing client with a Soap AND a protobuf enabled service, with a single service definition.
Brann
It does... I'll try to put the above into something to try to reproduce it.
Marc Gravell
A: 

I've been doing some more work in this area, and I suspect the problem is that you have a service reference (either via the IDE or via svcutil), which even though it re-uses the shared data-contracts, causes the contract interface to get duplicated (and loses the behavior attribute, making it broken).

Options:

  • don't use a service-reference (use the channel directly, or subclass ClientBase<T>)
  • use the new endpoint configuration options
  • hack the generated interface to include the behavior (creates maintenance problems)

If you aren't familiar with them, I plan on writing a blog entry for the first option in the next couple of days.

Marc Gravell
@Marc: Thanks for your support and time. I'll try the .config thing and hopefully confirm you it solved the problem :)
Brann