Are there any specific complex types that can't be returned by a WCF Service? - wcf

I have a question on the types that can be returned by a WCF service.Are there any specific complex types that can't be returned by a WCF service? To put more clearly, can we have any kind of complicated datatypes to be defined as Data Contracts and have them returned by the Service operations? Is there any limitation to any type?

Yes - anything that cannot be serialized into a message constrained by a XML schema file.
This includes:
interfaces (only concrete types)
generics
any data structure that doesn't just contain data, but also behavior (like a SqlConnection or something like that)
the Windows API primitives, like a Brush or other drawing elements
The main point is: whatever you're trying to send from client to server must be able to be serialized into an XML message, expressed in a XML schema, and deserialized back into a new object

Related

WCF, Sending an unknown type to a WCF service

Consider this scenario that two WCF clients connect to one WCF service(server), this service will receive an object from one client and send it to the other one through some operation contract and client callbacks, both clients have the type for this object but we do not want the WCF service(server) to be dependent on this type.
The project is much bigger than this, but I wonder if you can send an object with an unknown type to a service and somehow receive it back on the other client. I saw this but it does not help me at all: Can WCF service transmit type (client doesn't know this type) information?
Thanks in advance.
You can do certain things with the "raw" Message data type - but it's really not pretty programming...
Read about it here:
How to pass arbitrary data in a Message object using WCF
WCF : Untyped messages on WCF operations.
Sending an "object" with unknown type is not possible in WCF because WCF requires a full compatibility with WSDL - and WSDL requires transparent type definition.
Having said that, if you use a type of object I believe there is a way for this to be loaded as a string and in WSDL it is defined as xs:anyType.
I personally would prefer defining the type as string and passing an XML which can be serialised using plain XML Serialization. I have used this in our company and it works really well, especially since we will be storing the XML as document in database.

Can WCF service transmit type (client doesn't know this type) information?

I'm working on a simple plug-in framework. WCF client need to create an instance of 'ISubject' and then send back to service side. The 'ISubject' can be extended by the user. The only thing client knows at runtime is ID of a subclass of 'ISubject'.
Firstly, client need to get type information of a specific subclass of 'ISubject'. Secondly, client using reflection to enumerate all members to create a custom property editor so that each member can be asigned with proper value. Lastly, client create an instance of that subclass and send back to service.
The problem is how does client get the type information through WCF communication?
I don't want client to load that assembly where the subclass (of 'ISubject') exists.
Thanks
First, you need to be aware that there is no magic way that WCF will provide any type information to your client in the scenario you have descibed. If you are going to do it, you will have to provide a mechanism yourself.
Next, understand that WCF does not really pass objects from server to client or vice versa. All it passes are XML infosets. Often, the XML infoset passed includes a serialized representation of some object which existed on the sender's side; in this case, if the client knows about that type (i.e. can load the type's metadata from its assembly), it can deserialize the XML to instantiate an identical object on the client side. If the client doesn't have the type metadata, it can't: this is the normal case with WCF unless data contract types are in assemblies shared by both server and client implementations (generally not a good idea).
The way WCF is normally used (for example if the client is implemented using a "Service Reference" in Visual Studio), what happens is that the service publishes WSDL metadata describing its operations and the XML schemas for the operation parameters and return values, and from these a set of types is generated for use in the client implementation. These are NOT the same .NET types as the data contract types used by the service implementation, but they are "equivalent" in the sense that they can be serialized to the same XML data passed over the network. Normally this type generation is done at design time in Visual Studio.
In order to do what you are trying to do, which is essentially to do this type generation at runtime, you will need some mechanism by which the client can get sufficient knowledge of the structure of the XML representing the various types of object implementing ISubject so that it can understand the XML received from the service and generate the appropriate XML the service is expecting back (either working with the XML directly, or deserializing/serializing it in some fashion). If you really, really want to do this, possible ways might be:
some out-of-band mechanism whereby the client is preconfigured with the relevant type information corresponding to each subclass of ISubject that it might see. The link provided in blindmeis's answer is one way to do that.
provide a separate service operation by which the client can translate the ID of the subclass to type metadata for the subclass (perhaps as an XSD schema from which the client could generate a suitable serializable .NET type to round trip the XML).
it would also be feasible in principle for the service to pass type metadata in some format within the headers of the response containing the serialized object. The client would need to read, interpret and act on the type infomation in an appropriate fashion.
Whichever way, it would be a lot of effort and is not the standard way of using WCF. You will have to decide if it's worth it.
I think you might be missing something :)
A major concept with web services and WCF is that we can pass our objects across the network, and the client can work with the same objects as the server. Additionally, when a client adds a service reference in Visual Studio, the server will send the client all the details it needs to know about any types which will be passed across the network.
There should be no need for reflection.
There's a lot to cover, but I suggest you start with this tutorial which covers WCF DataContracts - http://www.codeproject.com/KB/WCF/WCFHostingAndConsuming.aspx
To deserialize an object the receiving side will need to have the assembly the type is defined in.
Perhaps you should consider some type of remoting or proxying setup where the instance of ISubject lives on one side and the other side calls back to it. This may be problematic if you need to marshal large amounts of data across the wire.
wcf needs to know the real object(not an interface!) which should be sent across the wire. so you have to satisfy the server AND the clientproxy side from the WCF service that they know the types. if you dont know the object type while creating the WCF service, you have to find a way to do it in a dynamic way. i use the solution from here to get the knownTypes to my WCF service.
[ServiceContract(SessionMode = SessionMode.Required]
[ServiceKnownType("GetServiceKnownTypes", typeof(KnownTypeHelper))]//<--!!!
public interface IWCFService
{
[OperationContract(IsOneWay = false)]
object DoSomething(object obj);
}
if you have something "universal" like the code above, you have to be sure that whatever your object at runtime will be, your WCF service have to know this object.
you wrote your client create a subclass and sent it back to the service. if you want to do that, WCF(clientproxy and server!) needs to know the real type of your subclass.

In WCF, how do I convert a Datatable to a format that will output in JSON store format without classes

So here's the problem - I have a DataTable I want WCF (.NET 3.5) to send out in a JSON store format commonly used in ExtJS, etc - basically "Rows[{"Field1":value,"Field2":value},{...}]" but I cannot find the right structure to feed back to the Operation contract to send it out in this format.
So any ideas, or any further info needed.
Thanks, in advance!
AndyPC, unfortunately, you're out of luck.
If you're dealing with an object whose type is an IXmlSerializable, the WCF JSON serializer delegates to IXmlSerializable methods first, gets the serialized XML out of them, wraps the XML in a JSON string, and just passes that on. This is one of the major weaknesses of the WCF JSON model in .NET 3.5. I think the entity framework (WCF Data Services) technologies try to handle this more elegantly, but not sure. I'd recommend manually using the JSON serializer and crafting up a string or a manual serialization mechanism that does what you want...

Passing Object as a parameter to a WCF Service

I have a method AddEntity(object o). I am figuring out which entity type it is on the server side using reflection and such and adding it to the database. I am using Self Tracking entities. However this is the error I am getting.
"Element contains data from a type that maps to the name . The deserializer has no knowledge of any type that maps to this name."
This is a lie. I have the entity on the server side, and I have the entity on the client side as a proxy. I am just passing it as an object because I have generalized the AddEntity method.
I am using object because generics are not serializable. So I cannot do something like this:
[OperationContract]
AddObject(T entity)
Any suggestions are most welcome.
No. This is not how the WCF works. WCF serializes entity to wire format and deserializes the entity on the other side. Deserialization process needs to know what type have to be deserialized - such information is not part of serialized data. This type is resolved from operation parameter or return type. Object is not allowed.

MsmqIntegrationBinding Serialization with Unknown Message Body Types

I'm looking to use the MsmqIntegrationBinding to integrate with a legacy queue which has a serialized object as the message body. Has anyone come up with a way to obtain the "metadata" of the message body and create a service side class to use within the service?
For example, if I put in a serialized Product object from System A and my service needs to consume it, how do I provide MsmqMessage the type if I do not have the Product class on my side? I was thinking of reading off a message in a separate program, deserializing, and then emitting via the code dom. Ideas?
I wholeheartedly recommend against attempting to emit the deserialized type at runtime in the message destination. Either work with the XML at the destination to obtain the data you desire, or build data contracts that both the source and destination can adhere to.
Hmm... in WCF, you can define service methods which take (and optionally return) an untyped Message type. This seems to fit your bill quite nicely.
Other than with strongly typed messages, you'll have to do all the putting together of the message on the client and the taking apart on the server by means of reading the raw XML - but that seems to be what you're looking for, right?
Find more information and samples here:
WCF - Handling Generic Messages
How to pass a generic object through WCF
Untyped messages on WCF
Untyped messages have some restrictions, e.g. you can only read them once on the server, but you should be able to manage your scenario with this, I think.
Marc