Consume more than one WCF service in same orchestration - wcf

I need to consume two WCF services in the same orchestration.
I use the "Consume WCF Service Wizard" that generates the xsd, xml, messages, pots and a orchrestation for each service
The thing is I can't use all the multipart messages generated just in one orchestration, I just can use the ones from the service it was generated from
I think it might have a simple solution.

I would recommend that you create a separate "Schemas" Project for the schemas and bindings generated by the Wizard.
Reference this Project from your "Orchestrations" project and re-create multi-part messages for the schemas.
You don't need to use the auto-generated multi-part messages as you can create your own;
Just create a request multi-part message with a Body and set the message type to the appropriate schema in your referenced Schema project.
This is the most flexible way I can think of to achieve your objective.
HTH

Related

single WCF endpoint for all commands in Nservicebus

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.

Deploying multiple similar schemas in BizTalk

I have two different servers on which two similar WCF services are running. Both services are exactly same (clone). I have to consume both services in a single orchestration because I have to communicate them with each other. (I am using "Add generated Items" to add service reference). I want to get data from one service method named "Get" and send it to others "Send" method. After deploying project I get error that "Cannot locate document specification because multiple schemas matched the message type #####".
I have read a solution of creating custom pipeline with a specific document schema but that didn't worked.
How I can handle this situation?
If the services really are identical, then you don't need to use the wizard to import the schema twice - just import the first service's WSDL to create the schemas and port types, and then create a new send port* and change the bindings accordingly to point to the second service (i.e. notably the service URL).
This situation also typically happens if your WCF Services use MessageContracts which accepts or returns the same message payload for more than one service call (as opposed to DataContract, where you should get typically 'uniquified' root element names of the form xmlns#MyMethod and xmlns#MyMethodResponse).
In this case (i.e. common MessageContracts), in addition to basvo's answer, you can also get around this issue as follows:
Import all artifacts for all consumed WCF services into your BTS project in Visual Studio.
Retain the first 'instance' of each request (or response schema), and then in Orchestration view in VS, go through each of the second and subsequent port types and delete the duplicated request or response messages ("operation message") on the Port type. (Under each Port Type, you should see the request, the response and also any fault message types)
You then need to 'edit' each of the message types that you've deleted, and then manually go and change it to the original instance of the schema that you've retained.
You may also need to delete or worse, hack, the duplicated message types out of the imported .xsd files.
This is a pain however if your web service changes and you need to 'refresh' your imported schemas again - it would be a nice feature if the Import Wizard detected duplicate schemas and offered to merge them in this way for you.
*
Update - just to clarify, reuse the same logical send port in your orch design, but create a new Send Port in the deployed BTS server / cluster, subscribing the send port to the required messages / link the second Orch to the send port (depending on whether you are using Direct binding or not), and obviously change the binding to the second URL.
The problem is that you now have more than one schema in your BizTalk application which has the same namespace and root element.
You need to set the DocumentSpecNames property on both the XMLReceivePipeline of your "get service" and the XMLTransmitPipeline of your "send service" to tell BizTalk which one to use.
The basic format of this value is ... Schemaname+Rootname,Assembly
Example:
Company.Schemas.Messages+GetReply,Company.Schemas,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
As these services are same so just adding service reference for any one of these will add the required schemas.Just create separate send ports for each service in BizTalk MMC and to connect the logical port created in orchestration to correct send port while configuring the orchestration.
This solution Worked.....

How to build a WCF service that consumes data given an XSD

I have been provided an XSD and a sample Xml file that contains the results I will be getting.
I am to build a Web Service that accepts this data and enter into a SQL 2005 table. Each time my service is invoked, I am expecting 1200+ rows of data.
I have also been provided two Xml files, success.xml and failure.xml, that are responses I am to provide back to the caller?
I would like to build a WCF service on the .Net 4.0 framework with one 'MethodToCall'. The other party would call this web service and pass in the data.
I used the SVCUTIL.exe file.xsd /dconly /importxmltypes to get an output.cs file.
Now what do I do?
How do I iterate through the rows to add to my table?
With so many rows, will I run into issues of having my service timeout or something?
Can I do the table insert/update in a batch after disconnecting from the wire?
Any sample or pseudo code would be appreciated.
How do I iterate through the rows to add to my table?
usually it generates classes using List for sequences in XSD, so you can iterate using foreach.
With so many rows, will I run into issues of having my service timeout
or something?
There are settings of binding like
<readerQuotas
maxDepth=""
maxStringContentLength=""
maxArrayLength=""
maxBytesPerRead=""
maxNameTableCharCount="" />
consider to increase its values.
Can I do the table insert/update in a batch after disconnecting from
the wire?
Think again, do you really need it? You should send response to sender that data is successfully processed. But you are going to send the response before data is written to the database. It could cause problems.
if the xml you got is not a soap envelope than you cannot build a wcf service that gets exactly it. you can build a service that gets that xml wrapped inside soap. that may or may not be what you want. to build a service that gets exaclty this xml use asp.net web api.
to build a wcf service given an xsd (and considering the limitation above) use wscf.blue.

Transfer XML between systems with Biztalk and WCF

I have system A which produces an xml-file and system B which takes the file. How can I implement this exchange using Biztalk with WCF?
You have two possible different solutions as I see it and it basically comes down to how typed you WCF service needs to be.
Do you need to transform you message into a new format? Or are you planning to use other features in BizTalk as content based routing etc? Are you at all interested in the content of the message while in BizTalk are you OK with just passing it thru?
If you are looking for a solution with the capabilities as described above you'll need to get the schema for the XML message you want to receive into WCF service and publish that service. Once the message is in BizTalk it's then typed and you can do what ever with it using BizTalk.
If you however just want to pass it thru you could just publish a service that received as message of type XML document and pass that thru. Here's a good post describing the a few different techniques to create a generic service accepting any XML as input.

How does WCF Decide which Operation to Dispatch To?

I'm building a WCF SOAP application. The WSDL file has numerous operations of which many have the same argument type. The WSDL file defines all soapAction attributes as "''". When I try to start such a service WCF throw an exception saying that soapActions have to be unique.
After some googling I'm even more puzzled than before. I used SOAPUI to create a mock service with two operations which take the same input type and without the soapActions defined it always chooses the same operation. When the actions are defined it works fine.
My questions are:
Can you make a WCF SOAP service without unique soapActions (actually leaving the soapActions "''" as defined in the original WSDL)?
How can a service choose the right operation without the soapAction defined?
Edited:
I'm not in control of the WSDL. I'm using the WSCF.Blue tool to create a service stub from the WSDL file. I might be able to modify the WSDL, but I want to see if there is some possibility to leave it as it is.
It is not very clear from your question but I suggest you are building service based on some defined WSDL, aren't you? WCF by default uses SOAP action because it is required part of WS-I Basic Profile 1.1 offered by WCF services with BasicHttpBinding. WSDLs with empty SOAP actions are used when the action is defined by root body element.
WCF samples provides example of custom DispatchOperationSelector which is able to route messages to operations by their root body element. This is probably what you need to add to your service so that clients based on provided WSDL can call it.