Duplex WCF service - wcf

I created a simple WCF service that worked just fine. I tried later to make it a duplex service.
I created the duplex contract, changed the binding to wsDualHttpBinding and pulish the WSDL. However when I try to do the last step on the client side I face some trouble. Here is what I did on the client side:
static void Main(string[] args)
{
InstanceContext context = new InstanceContext(new CalcCallbackHandler());
CalcClient proxy = new CalcClient(context);
}
The problem is that CalcClient ctor can't receive InstanceContext.
I can't understand how It's possible beacuse all the example I've seen on the web use this method to create duplex server. Any suggestions?

On the client side you will need to setup/host the call back object and expose the callback endpoint.

Related

How to pass parameter and get data from wcf service

I got this error:
There was no endpoint listening at http://vkalra.in/WCF_SERVICE/RestServiceImpl.svc that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details
InnerException-The remote server returned an error: (404) Not Found.
This is my code:
Binding binding = new BasicHttpBinding();
// Create endpointAddress of the Service
EndpointAddress endpointAddress = new EndpointAddress("http://vkalra.in/WCF_SERVICE/RestServiceImpl.svc");
ServiceReference1.Leave_Details emp = new ServiceReference1.Leave_Details();
emp.empid = items.empid;
emp.fromdate = "01-04-2019";
emp.todate = "04-06-2019";
emp.tabt = "1";
emp.jdis = "0";
try
{
ServiceReference1.RestServiceImplClient service = new ServiceReference1.RestServiceImplClient(binding, endpointAddress);
string levbal = service.Leave_Calculation(emp);
}
catch(Exception ex)
{
}
If we want to consume the WCF service created by WebHttpBinding(this type of the WCF service is also called Restful service) by adding service reference, we need to do something special. Generally speaking, if we want to call Restful service (such as the service created by Asp.net WebAPI), we could construct a http request, Get or Post with a request body, then send to the specified service address.
https://code-maze.com/different-ways-consume-restful-api-csharp/
https://learn.microsoft.com/en-us/aspnet/web-api/overview/advanced/calling-a-web-api-from-a-net-client
This also applies to WCF service created by WebHttpBinding.
consuming a WCF service using simple HttpClient class
But if we want to consume the WCF restful service by adding the service reference, we are supposed to maintain the consistency of binding between the client and server. we should add [WebGet]/[WebInvoke] to the auto-generated method of the service interface, which comes in the form of adding service reference, located in Reference.cs file.
One more thing we need do is add Webhttpbehavior (endpoint behavior) to the client service endpoint. This client configuration comes in the form with adding service reference, located in the System.ServiceModel section of the app.config/web.config.
The remote server returned an unexpected response: (400) Bad Request. wcf
Feel free to let me know if there is anything I can help with.

Does IErrorHandler Interface work for a caller or only a called WCF service?

Referring to this interface: https://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.ierrorhandler(v=vs.110).aspx
I have coded class that implements IErrorHandler, and it's not firing (although using debugger I see methods like Validate, AddBindingParameters, ApplyClientBehavior, but didn't see ApplyDispatchBehavior run.
The example I used to write it was a BizTalk orchestration published as a webservice (https://blog.tallan.com/2014/09/29/wcf-webhttp-and-custom-json-error-messages/comment-page-1/#comment-232591); but in my case, I'm a BizTalk orchestration calling an external webservice (I am the client, not the server). I want to trap and change the 400 status.
So in his code sample, he adds the ErrorHandler to endpointDispatcher.ChannelDispatcher in the ApplyDispatcherBehavior. After doing some reading, looks like ApplyDispatchBehavior is only when you are the server. Can I add the error behavior "to dispatch" in the ApplyClientBehavior?
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
clientRuntime.MessageInspectors.Add(new BizTalkRESTTransmitHandler());
#can IErrorHandler be added to client?
}
// Apparently ApplyDispatchBehavior only applies if you are the server, not the client
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
BizTalkRESTTransmitErrorHandler handler = new BizTalkRESTTransmitErrorHandler();
endpointDispatcher.ChannelDispatcher.ErrorHandlers.Add(handler);
}
I'm hoping that someone WCF pro vs a BizTalk person can actually answer. BizTalk has a WCF adapter (acting as the WCF client in this case), and we have ways to implement custom behaviors within that structure. I was also using the AfterReceiveReply method; but I think BizTalk stopped the adapter before it could run that method. I was hoping IErrorHandler might allow me to do the intercept.
I have logic for AfterReceiveReply; but it's not running (although BeforeSendRequest is). I think the BizTalk Adapter is calling the message because of the bad HTTP status and not letting me inspect it.
My related post written in BizTalk terminology: How to prevent BizTalk 2013/R2 WCF-WebHttp Rest SendPort from Suspending on Http Status=400

How to prevent WCF proxy from following redirect?

I'm using basicHttpBinding for my WCF service and have a message inspector that sets response code to Redirect under certain circumstances. I find that the WCF proxy (generated by svcutil) automatically tries to follow the redirect. How do I prevent this from happening?
Thanks,
Priya
Can you reference the service contract assembly from your client application? If so you can get rid of the generated service reference and just spin up a proxy at runtime using ChannelFactory.
For example:
// Create service proxy on the fly
var factory = new ChannelFactory<IMyServiceContract>("NameOfMyClientEndpointInConfigFile");
var proxy = factory.CreateChannel();
// Create data contract
var requestDataContract = new MyRequestType();
// Call service operation.
MyResponseType responseDataContract = proxy.MyServiceOperation(requestDataContract);
In the above example, IMyServiceContract is your service contract, and MyRequestType and MyResponseType are your data contracts, which you can use by referencing the assembly which the service also references (which defines these types).
what have you tried to achieve with redirect ? you will an handle this cases with some message interceptors on client side:
http://msdn.microsoft.com/en-us/library/ms733786(v=vs.90).aspx

Is it possible to have WCF services using MSMQ and WCF services not using MSMQ in the same host?

Maybe I am mixing things, if this is the case, please let me know.
I want to provide a set of services through WCF regarding messages (this is an example). In this set I am going to have a "sendMessage" service and a "receiveMessage" service.
For the sendMessage, I want to use MSMQ, so the user can send the message to 100.000 other users and this will be processed in background.
For the receiveMessage I do not want to use MSMQ because I want the user to be served when he makes the request and get the response (MSMQ, in this case, is oneway).
I am using this code to start my host in an example application
static void Main(string[] args)
{
using (ServiceHost host =
new ServiceHost(typeof(Service), new Uri[] {
new Uri("net.msmq://localhost/private/loadqueue"),
new Uri("http://localhost:8383/") }))
{
host.Description.Behaviors.Add(new ServiceMetadataBehavior() { HttpGetEnabled = true });
NetMsmqBinding binding = new NetMsmqBinding();
binding.Security.Transport.MsmqAuthenticationMode = MsmqAuthenticationMode.None;
binding.Security.Transport.MsmqProtectionLevel = System.Net.Security.ProtectionLevel.None;
binding.ExactlyOnce = false;
host.AddServiceEndpoint(
typeof(IContract),
binding,
string.Empty);
host.AddServiceEndpoint(
typeof(IMetadataExchange),
MetadataExchangeBindings.CreateMexHttpBinding(),
"mex");
host.Open();
Console.WriteLine("service running");
Console.ReadLine();
}
}
The Contract looks like this
[ServiceContract(SessionMode=SessionMode.Allowed)]
[DeliveryRequirements(QueuedDeliveryRequirements = QueuedDeliveryRequirementsMode.Allowed)]
public interface IContract
{
[OperationContract(IsOneWay = true)]
void SendData(string msg);
}
When the client invokes the SendData service, the message is sent to the queue and after that it is consumed by the service.
I would like to create a second service which receives directly the message from the client (no queue in the middle).
The client would have only one web reference and if he calls service.SendData() the message is sent to the queue and if the client calls service.NetMethod() the service receives the message directly. This way it would be transparent for the client side developer if the service is using a queue or not and I would be able to group the services regarding their functions and not mechanisms. Would that be possible to make?
Thanks,
Oscar
WCF allows you to expose the same service contract across mixed transport bindings. For example, your service class has two operations, one one-way, and one request-response. You can expose this service across net.tcp:// and http:// on two endpoints (with different URIs).
However, what you want to do is have the different operations on your service contract exposed over different transports, and as far as I know WCF does not allow this.
The problem you have is that, as you say, the bi-directional operation cannot be supported under the msmq binding. So you would not be able to expose your entire contract across http and msmq simultaneously.
Is there any reason you cannot define two service contracts and host them in the same servicehost, as described here?

accessing WCF service through URL

I have a WCF service ( Let's say WCFService1 ) is deployed on two remote machines. Since the same service is deployed on two different machines they have common interface and common methods exposed.
WCFService1 is deployed on Machine1 and Machine2.
To consume WCF service from client machine, I have created a client app:
I have added a design time reference of WCF service (WCFService1 )( with the help of URL http://11.12.25.23/WCFService/Service1.svc).
Now I can invoke the methods exposed in the service. Up until now its fine...
Now my question is If I have to update client at run time with same service hosted in different machine with different URL ( Let's say http://12.12.24.24/WCFService/Service1.svc), How can I do that?
At present I am doing this:
BasicHttpBinding binding = new BasicHttpBinding();
EndpointAddress address = new EndpointAddress("http://12.12.24.24/WCFService/Service1.svc");
MyServiceClient serviceClient = new MyServiceClient(binding, address);
but whenever I use to invoke the method exposed in the service I got binding mis match error.
Have you tried invoking your client first?
eg:
MyWCFClient client = new MyWCFClient();
client.EndPoint.Address = new EndpointAddress("http://somewhere:888/here.svc");
I'd suspect, that if you look in your web.config file on Machine1, you'll see that the binding there is WSHttpBinding (or something different than BasicHttpBinding). If you change it to BasicHttpBinding (assuming that is what you really want), you'll remove this error.
How is your service configured? Show us your server-side and client-side config!
Binding mismatch means you're either not using the same binding, or some vital parameter on the binding is different - there must be something configured wrong - so show us the config!
Marc