when should i use a datacontract and when a messagecontract in WCF - wcf

ON what basis should we decide whether we have to create a dataContract or a MessageContract for my WCF services.
What I know is that when we need to have more control over SOAP,We use MessageContract.
Secondly I have seen some code in which DataContract is exposed through MessageContract.Whats the use of it.
Please provide some real life scenerios.

It's not an "either-or" question - you'll always have data contracts if you're dealing with compound data (more than just the basic types of int, string etc.). That's a given.
You'll only ever need message contracts if you need to very closely and very specifically control the layout of your SOAP messages. In most case, over 90% of the time - you don't.
A message contract allows you to specifically say which elements (scalar types or compound types as DataContracts) will be in the SOAP header, and which will be in the SOAP body.
You might need this if you have a communication partner which requires a very specific format and you have to tweak your SOAP messages to match that given layout exactly. That's just about the only valid scenario when you'll need to and should use message contracts.
So, to make a long story short: always use data contracts, practically never use message contracts (unless you absolutely, positively have to).
Marc

If you need to take over the SOAP headers and body explicitly, you would use MessageContracts. For example, if you needed to make sure a credit card number was encrypted in your message separately from the rest of your type, you'd need to get that level of control over the message on the wire.
Here's more information on that with some examples (specifically the encryption example): http://msdn.microsoft.com/en-us/library/ms730255.aspx
If you just want pure DTOs and don't care about their shape on the wire, go with DataContracts.

Related

What if the best way to return Option types by WCF service

I have a WCF method which search the record in database and return Some(object) if the record exists and None if it doesn't.
As I see I can't call the method which returns Type option through WCF (I get exception).
What is the best way to design WCF services in F# in this way?
For example, I can return empty Type
Person
{
Name = ""
Age = 0
// ....
}
if the record doesn't exist in DB, but I am looking for the best ideas...
A WCF service, just like a RESTful service, exposes an API that can be accessed by remote clients. These clients need not even be written in .NET, but could be Java clients, or written in a completely different language, for all we know.
The entire point of SOAP and REST is to enable those interoperability scenarios, but that also means that services may share schema and contract, but not class (or any other type, for that matter).
A few years ago, I wrote an article called At the Boundaries, Applications are Not Object-Oriented, but you can take that article, and replace Object-Oriented with Functional: At the Boundaries, Applications are Not Functional (Programming).
Even if you could somehow serialize option types in WCF, you'd be advised not to do so, because clients may not understand what it means, or be able to handle that serialized format in any meaningful way.
In the end, an option can be viewed as a constrained collection with the constraint that it can hold either 0 or 1 element. You can't model that constraint when you return data over an interoperable service, but you can still return a collection/array.
That's what I sometimes do: return an array with either no element, or a single element. Most clients understand that.
When building RESTful services, you have the better option of returning 404 (Not found) when a resource doesn't exist, but I'm not sure there's a good way to do this with SOAP.
With SOAP, though, you can define data structures using XSD, so you might be able to use xsd.choice to model a data structure that can be either none or some.

Validation exceptions from a WCF service

I'd like some help with this one.
I want to return some kind of validation exception from my WCF service if the given entity data doesn't pass the business logic, but I'm not sure the best way to return muliple things from a WCF Service (for example a validation error and a list of entities).
This one might be really simple, but even so, I'd appreciate a little help.
I would suggest you take a look at the Enterprise Library Validation Block:
http://msdn.microsoft.com/en-us/library/ff648951.aspx
http://msdn.microsoft.com/en-us/library/ff648939.aspx (note this is for EntLib 3.1, which is a bit dated, but even in EntLib 5, WCF integration works similarly)
I've used this approach a number of times for WCF validation and it works out quite well. You'll end up decorating your data contracts with validation attributes that are part of EntLib. This defines what your validation rules are. Then you configure your service to use Enterprise Library's WCF extensibility. This is an endpoint behavior, so essentially this intercepts any incoming messages for your serivce, checks that all the defined validation attributes pass and then sends the message on to your service option. If the rules specified by your validation attributes don't pass then the endpoint behavior returns a fault message that contains the details about all validation failures. So, if one attribute didn't pass, there would be one message. If three attributes didn't pass, you'd have three messages and so on. Each validation failure message references what property didn't pass validation. The nice thing about the EntLib validation WCF integration is that the fault messages used for validation failures are strongly types and available in your service's WSDL. This means that your clients can easily consume these faults and act upon them appropriately.
If you feel like Enterprise Library is a little too heavy for your needs then you could certainly roll your own validation. You'd probably want the data contracts returned by your service operations to include something like a List that cotains validation messages.

WCF Contract restrict string values

We are defining some WCF contracts for a project.
In one case we want so send over a status field. We though of just sending this over as a text.
Can we specify in the WCF contract that only these x string valuses are allowed?
Would it be better to use enums?
We will be interoperating with java web services.
No you can't, but you could use enums which are then turned into the schema equivalent of a restricted list of strings. This is also helpful to non-WCF clients because they can easily see what the range of allowed string values are.
Unfortunately enums come with some unfortunate baggage in WCF when it comes to versioning. Specifically, you can't just add a new enum and not break existing WCF clients. So adding a new enum is considered a breaking change.
You will need to weigh these two options and decide which is best for you. If you choose "pure" string, then you will need to validate the values yourself. This can be done generically by writing an IParameterInspector which you can hook to all your services that might use the data contract that you're interested in constraining.

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.

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