views:

568

answers:

3

Per my other post about WCF service return values, I'm consuming a web service from another company, and when I add the service reference inside Visual Studio, the return value of the method is an object of type object.

The author of the web service showed me the code, and it actually returns a typed object.

Am I missing something, or is the proxy class supposed to return a typed value?

Is there a setting for generating the proxy class, or the actual service?

UPDATE:

I looked at the actual classes behind the WCF service and realized that the return value of the service method is actually returning an interface, that the concrete type implements. The concrete type is marked with the [DataContract] attribute ( and appropriate [DataMember] attributes), but the interface has no such attributes. Could this be causing the service to set the return type as object?

+1  A: 

The proxy class is a generated file and as such it can contain mistakes. If you have a copy of the data contract you are free to change the proxy class to use the correct type rather than System.Object and things ought to work properly.

The Visual Studio "Add Service Reference" tool and svcutil.exe are very good at generating proxy classes but they are not perfect. The files that they generate are yours to modify and I would encourage you to simply modify the operation to return the proper data contract.

Andrew Hare
But if I manually change the auto-generated proxy class, and then update the service it will overwrite my changes right?
SkippyFire
It looks like the proxy class is a partial class. So I can make changes that way.
SkippyFire
You won't be able to change this with a partial class - you will need to change the proxy itself. Without testing I cannot say for sure if a service update will overwrite your changes but even so it will be trivial to fix that and it will be a compilation error that will be easily spotted.
Andrew Hare
What about the update I just made to the question, could the interface be the culprit?
SkippyFire
+3  A: 

Hypothetically, if you were the service developer, you could use a KnownTypeAttribute:

[DataContract]
[KnownType(typeof(MyConcreteClass))]
public interface IMyInterface {
}

[DataContract]
public class MyConcreteClass : IMyInterface {
}

I haven't personally tried this with an interface, but I have tried it with an abstract base class and it works fine. When the client receives the return value, it can successfully downcast to the derived class.

It might be that the service code actually does this, and the problem lies with svcutil.exe not generating the proxy classes accurately enough.

Although you don't control the service code, you do control the client proxy code. You could try manually editing the proxy classes that svcutil.exe gave you to add the KnownTypeAttribute yourself. By doing this, you are taking control of the behaviour of the DataContractSerializer at your end, and as long as you take care not to change the wire format of the data by mistake, it should all still work.

Christian Hayter
A: 

We had a similar problem when consuming a java web service from WCF.

In our case the type that it said that it was returning was a limited version of what was actually being returned.

What worked for us was to cast the object to the type that was expected. After that the data was available.

Therefore, to fix your problem you could try to cast the object to the type expected.

Shiraz Bhaiji