WCF Contract restrict string values - wcf

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.

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.

Request and Response objects and WCF versioning

I'm in the process of designing my first "proper" WCF service and I'm trying to get my head around how to best handle versioning of the service.
In older ASMX web services, I would create aMethodNameRequest and MethodNameResponse object for each web service method.
A request object would really just be a POCO wrapper around what would typically be in the method parameters. A response object might typically inherit from a base response object that has information about any errors.
Reading about WCF and how the IExtensibleDataObject, FaultContractAttribute and Namespacing works, it seems that I can revert back to using standard parameters (string, int etc) in my method names, and if the service is versioned, then ServiceContract inheritance can provide this versioning.
I've been looking into http://msdn.microsoft.com/en-us/library/ms731060.aspx and linked articles in that, but I was just looking for a bit of clarification.
Am I correct in thinking that dispensing with the Request/Response objects is more ideal for WCF versioning?
EDIT: I just found this article which suggests using explicit request/response object: http://www.dasblonde.net/2006/01/05/VersioningWCFServiceContracts.aspx
I don't agree that dispensing with Request/Response objects is that way to go.
There are obvious benefits of coding with messages:
you can reuse them, which avoids pass 5 ints and 3 strings to a number of different methods.
the properties are named and so can be reliably understood, whereas a parameter that is passed by value through multiple tiers could be confused, and so on.
they can be proper objects rather than just data containers, if you choose - containing private methods, etc
But you are really asking about versioning. Don't forget that you can version the messages within your service contracts. The classes in assembly can have the same name provided they are in different namespaces (e.g. v1.Request and v2.Request), and they can both implement a required interface or inherit from some base object.
They also need to be versioned for your service consumer, which can be done with xml namespaces; I've typically put the service contracts (the operations) in a namespace like http://myapp.mydomain/v1 and the messages (the request and response objects) in http://myapp.mydomain/v1/messages.
One gotcha with this approach is that if you have an operation, call it Submit, in the http://myapp.mydomain/v1 namespace then by convention / default the soap objects SubmitRequest and SubmitResponse will also exist in the same namespace (I don't remember what the run-time exception is but it confused me for a while). The resolution is to put message objects in another namespace as I've described above.
See "Versioning WCF Services: Part I" and "Versioning WCF Services: Part II".

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.

when should i use a datacontract and when a messagecontract in 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.

How do I reuse complex types accross different services?

I have 2 separate java services that use a complex type that is a exactly the same but takes an email object as a parameter like:
class Email{
Description{get;}
Address{get;}
}
The services look something like this:
emailBasketBallTeam(email);
emailTennisTeam(email);
Is there a way that I can specify a contract for the email object or somehow reuse the email object in different services despite them being in completely different namespaces?
Unlike wsdl /sharetypes, you need to consume one service at a time, but you can re-use types from existing assemblies.
With svcutil, you can use the /reference switch. I believe you can also do this in the IDE in the designer.