Is there any metadata versioning support in OData protocol and its WCF Data Services implementation?
Let us suppose that we have OData service that exposes the single Goods collection, and the Goods entity type has three properties: Key (string), Name (string) and AvailableSince(string). The service is already running, and there are some consumers that rely on this metadata schema.
Next, we want to update Goods entity type - for example replace property AvailableSince(string) by something else, or change it type from string to datetime - so we will have two versions of metadata, and consumers thatdepends on the first version of metadata will not be able to send correct requests in terms of 2nd metadata schema.
Is there any way to provide both metadata versions within the single service? If yes, then how consumer can specify metadata version in request, and how it should be processed on WCF side?
Thank to all in advance.
Short answer: NO.
Most metadata changes require either a new service or breaking existing clients.
If the existing set of clients is important, our general recommendation is to create a new service...
i.e. something like:
/v1/myservice.svc
&
/v2/myservice.svc
Alex
OData Program Manager
This recent article describes on what data changes new service version is required, and what changes do not require service update.
http://msdn.microsoft.com/en-us/library/ee473427.aspx
Related
We are trying to build a Nservicebus service that can communicated with form and wpf based clients using WCF. I have read that you can inherit from WcfService.
like:
public class ThirdPartyWebSvc : WcfService<ThirdPartyCmd, ThirdPartyCmdResponse>
And then you simple create a endpoint in the app.config and you done like described here. but the problem is that i have to create a endpoint for every command.
I would like to have a single endpoint that excepts any command and returns its response.
public class ThirdPartyWebSvc : WcfService<ICommand, IMessage>
Can someone point me in the right direction? Using Nservicebus for client communication can't be done for us and i don't want to build a proxy like server unless thats the only way to do it.
Thanks
So from what I can gather, you want to expose a WCF service operation which consumers can call to polymorphically pass one of a number of possible commands to, and then have the service route that command to the correct NServiceBus endpoint which then handles the command.
Firstly, in order to achieve this you should forget about using the NserviceBus.WcfService base class, because to use this you must closely follow the guidance in the article you linked in your post.
Instead, you could:
design your service operation contract to accept polymorphic requests by using the ServiceKnownType attribute on your operation definition, adding all possible command types,
host the service using a regular System.ServiceModel.ServiceHost(), and then configure an NserviceBus.IBus in the startup of your hosted WCF service, and
define your UnicastBusConfig config section in your service config file by adding all the command types along with the recipient queue addresses
However, you now have the following drawbacks:
Because of the requirement to be able to pass in implementations of ICommand into the service, you will need to recompile your operation contract each time you need to add a new command type.
You will need to manage a large quantity of routing information in the config file, and if any of the recipient endpoints change, you will need to change your service config.
If your service has availability problems then no more messages to any of your NSB endpoints.
You will need to write code to handle what to do if you do not receive a response message from the NSB endpoints in a timely manner, and this logic may depend on the type of command sent.
I hope you are beginning to see how centralizing this functionality is not a great idea.
All the above problems would go away if you could get your clients to send commands to the bus in the standard way, but without msmq how can you do that?
Well, for a start you could look at using one of the other supported transports.
If none of these work for you and you have to use WCF hosted services, then you must follow the guidance in the linked article. This guidance is there to steer you in the correct direction - multiple WCF services sounds like a pain, until you try to centralize them into a single service - then the pain gets bigger, not less.
I have a WCF web-service with four different clients , one of our clients wants more functionality , so we are adding , new OperationContract , which will use new DataContracts and some existing one
Existing Operation Contracts or DataContracts are not being modified
We will just be adding new OperationContracts and few new DataContracts
Would all of our clients have to update their service reference ? ( or clients who don't want the additional functionality of new methods, can go on using the service as they were)
if all of the clients would have to update their service reference , is there a way around it ? ( I want that only the clients who want to use the new operationContract , should update the service reference )
We have netTcp and basichttp bindings
WCF is very flexible when in comes to versioning as shown in this good MSDN article. If you change a service contract exposed automatically through a MEX endpoint, then all clients will have access to the new changes.
If you want to tightly control the contract exposed by a service then you could turn off the MEX endpoint and distribute the edited WSDL (and appropriate XSDs if not using singlefile) files to specific clients. Do not consider this a security measure since all you're doing is "obscuring" the fact that the service supports more operations that you are revealing.
If you do need to secure the different contracts then you will need to create separate services to expose the appropriate contracts to authorized clients.
Existing clients do not need to change. Under the hood the contract between clients and the server are soap messages according to the schema of specific operations. Since these operations have not changed the soap is the same so clients will work.
Consider I have a DataContract with 6 properties. one client needs first 3 properties and second client needs last 3 properties of the Data Contract. How to write the Data Contract in a service So that the Service sends the message with only Required properties?
The correct way to do this is creating separate service for each client. Each service will expose operation using its own data contract with only required properties. Both services will be just wrapper around your core logic working with whole data object. If the reason for sending only subset of properties is data security then creating two services is the only valid option.
If we consider this more detaily the problem here is service description. If you expose metadata / WSDL on your service it will always contain the whole data contract because you can't change it dynamically. If a client creates proxy from these metadata it will also receive whole contract.
You can avoid sending some properties in SOAP message if you configure your contract to not include properties with default values and do not set them in your service but I don't think it is a good solution.
I have a universal service hosted on IIS7 that accepts a Message and returns Message ( with Action="*"). This service still publishes meta for the clients.
This metadata is explicitly specified using LocationUrl property in ServiceMetadataBehavior.
We have a requirement that the metadata can change during lifetime of the service, so in essence metadata has a lifetime.
I tried adding IWsdlExportExtension to the service endpoint behavior, but the ExportEndpoint method only gets called once (when the service is loaded first time). Is there a way for me to invalidate the loaded metadata so that anytime there is a call for wsdl using HttpGet, the behavior gets called ?
What you are asking for (changing the published service definition at runtime) is not possible - you need to remove the requirement which specifies that the metadata can change over time.
Once you've published a service, the only reason the service specification should change is because the service has been upgraded.
You should look closer at the business requirement which is making this technical requirement necessary, and try to find another way to satisfy it (perhaps post in programmers.stackexchange). Perhaps you can have multiple services available, and switch between the services over time - but this is a bit of a stab in the dark without knowing the business requirement.
No there is no way. Moreover if you needed you are up to your fully custom solution because this is out of scope of web services. Changing metadata means changing the service itself = its internal logic which always result in restarting the hosting process and publishing new metadata.
Desktop clients will be pushing data using WCF to a central server.
When the schema changes etc, say 100 computers have the old version of the desktop client while the rest are using the latest build.
What do I have to do on the server end to handle both versions?
Do I create 2 endpoints in WCF or a single smart endpoint that will figure out the version and act accordingly?
note: i will be passing the version info from the client (if required that is)
You have a choice:
Firstly you should be versioning your service contracts anyway, with their namespaces; eg. http://idunno.org/2008/10/numpty would change to http://idunno.org/2008/11/numpty if the service operations have breaking changes.
Ditto with data contracts; however if all you are doing to the data contract is additive then you can mark the new fields as optional;
[DataMember(IsRequired="false")]
And old clients will work. So this should indicate to you that the parameters into a service and parameters out should also be data contracts; it gives you that flexibility.
MSDN has more