When should I use OperationContextScope inside of a WCF service? - c#

I'm currently working on a WCF service that reaches out to another service to submit information in a few of its operations. The proxy for the second service is generated through the strongly typed ProxyFactory<T> class. I haven't experienced any issues but have heard I should do something like the following when making the call:
using (new OperationContextScope((IContextChannel)_service))
_service.Send(message);
So my question is: when is creating this new OperationContextScope appropriate, and why?
Thanks!

If you are using callbacks or if you want to modify the message or headers then you need to use OperationContextScope. Your service might need to modify outgoing headers while calling that another service.
When you establish OperationContextScope then you can:
Access and modify incoming and outgoing message headers and other properties.
Access the runtime, including dispatchers, the host, channel, and extensions.
Access other types of contexts, such as security, instance, and request contexts.
Access the channel associated with the OperationContext object or (if the channel implements System.ServiceModel.Channels.ISession) the associated channel's session identifier.
The other service which you call, is it a session-based service? Probably you need to look at its sample client code or documentation if available.

Related

Call a soap client's method using a string and an object

I'm using an external open source project that provides me computation services that I create using a UI that it provides.
The project creates web-service endpoints automatically that I'm suppose to consume via my application.
My problem is that I can't interfere in the process. It's a black box that creates a service for me when I choose to deploy the project.
Each service has a bunch of different logical "private methods" that are exposed in the wsdl that's automatically created.
If I could create the service myself, I would create one an interface with an exposed method called Process that will have one general input request param and one general Response, something like:
public GeneralResponse Process(GeneralRequest request);
I want to create a generic out-point in my application which passes two parameters:
1.Endpoint Url to shoot the request to.
2.Generic request as an input param.
I'm using C# and the easiest way to consume a service is simply adding a service-reference, creating a client and calling the wanted method.
Since I don't want to add a client per service reference, I'll add a random one, change the client's endpoint address and shoot the request.
The problem with this approach is that the client generated will expose it's "private methods" and I don't want other programmers on my team to accidentally invoke them.
Bottom line:
Is there any elegant way to create a Generic soap client and invoke a method using a string? Similar to the way you call the Invoke method when you use reflection?
Something like this:
GenericRequest req = GetRequest();
SoapClient client = new SoapClient(endpointUrl);
GenericResponse res = client.Invoke("Process", req) as GenericResponse;

Is it possible to use persistent connections with System.Net.Http.HttpClient?

I have created REST resource using Web API running as a self-hosted process. For performance reasons I would like to be able to call it using persistent HTTP connections. I using OWIN self-hosting.
I really like the asnyc methods for GET, POST, PUT, DELETE in System.Net.Http.HttpClient. They are easy to call and deal with--they return a System.Threading.Tasks.Task which is convenient for what I'm trying to do. I prefer using HttpClient to System.Net.HttpWebRequest.
I'm probably missing something, but it isn't readily apparent to me how to create persistent connections with HttpClient. I'm digging through the System.Net.Http.HttpClientHandler and System.Net.Http.WebRequestHandler classes, but so far I haven't found an option for persistent connections. Google finds all sorts of examples of creating persistent connections using HttpWebRequest. It has a KeepAlive property that can be set to true. Is there a way to set this with HttpClient?
MSDN documentation for HttpClient:
By default, HttpWebRequest will be used to send requests to the server. This behavior can be modified by specifying a different channel in one of the constructor overloads taking a HttpMessageHandler instance as parameter. If features like authentication or caching are required, WebRequestHandler can be used to configure settings and the instance can be passed to the constructor. The returned handler can be passed to one of the constructor overloads taking a HttpMessageHandler parameter.
Is there a way to set the KeepAlive feature on the underlying HttpWebRequest?
The MSDN documentation also says:
The HttpClient class instance acts as a session to send HTTP requests. An HttpClient instance is a collection of settings applied to all requests executed by that instance. In addition, every HttpClient instance uses its own connection pool, isolating its requests from requests executed by other HttpClient instances.
Am I to understand from this that the connection pool will optimize for me using persistent connections when a performance benefit can be gained? What if I want there to only ever be a single connection from my client?
You will need to set the MaxIdle time on the ServicePoint for the client. The easiest way is to set the timeout for all service points:
ServicePointManager.MaxServicePointIdleTime = Timeout.Infinite;
You can also set it on the connection to the specific endpoint
var sp = ServicePointManager.FindServicePoint(targetUri);
sp.MasIdleTime = Timeout.Infinite;
I'm not sure what exactly you are trying to solve but have you looked at SignalR ? They have pretty fancy websocket api's that might do the job you are looking for.
If you are not using .NET 4.5 then they do have alternate mechanisms. One I'v seen being used is something like a server/event-stream.

Global variables in WCF REST services

My applciation works as follows
[user]----username/password/domain----->[WCF service]
then i access the domain server to see to which actual DB the user is associated,
after getting that, i validate the user in his actual DB(DB is per domain)
the problem is that i need a place to store the domain name for the following requests against the db.
for example,if the users calls a WCF service operation:
Test()
first the validation procedure is called, (WCF UserNamePasswordValidator) which validates the user password(which is sent as part of the header for REST or as part of the SOAP), and the next function to be called is the Test, but by then i cant tell the domain of the user(to actually serve the request agains that domain..)
I dont want to change the signature of each domain to
Test(string domain)
I cant simply access the headers since i expose the same methods both as REST and as SOAP and the authentication is different for each of them..(one is with headers as with Amazon S3 and the later is using the SOAP standard)
so basically i'm looking for a global, per call storage.(i want to avoid the Per-Call initiation method)
thanks.
EDIT:
Maybe i should use the ThreadStaticAttribute? will that work?
This will not work. You can't store anything in UserNamePasswordValidator. It even doesn't have access to OperationContext because it runs on different thread.
The way to do this is create custom message inspector and extract the information from custom message header to custom operation context extension as Frank mentioned.
WCF knows a Current OperationContext. You can write your own extensions for it. Unrelated to this issue, I used the same mechanics in this NHibernate Session management here, which may work in its concept for you as well. It accesses the InstanceContext, but the concepts are similar.

Multiple Operations with soapAction="" in a WCF Service Contract?

I need to create a service that will be "called back" by a third party. As a result, I need to conform to their WSDL.
Their WSDL has all of the operations defined with soapAction="", so my service needs to do the same. Unfortunately, I'm getting the error:
The operations A and
B have
the same action (). Every operation
must have a unique action value.
In ASMX web services, there was a mode where the soapAction would not be used, but the name of the request element would be used instead. Is there some way using WCF not only to dispatch on the request element, but also to emit a WSDL with no soapAction?
This is possible in asmx, but out of the box you will find no clean way to do this in WCF because it uses the action to dispatch messages to operations.
I think the hack you need is to set your soapAction to "*", and then write a custom dispatcher.
A potential side effect of this is a bad WSDL, if you need to expose a WSDL you will have to generate/steal it and then use the externalMetadataLocation attribute

See the SOAP request from Proxy class method calls

I'm using .NET 2.0 web services. If I add a reference to a WSDL and make a proxy class method call, what's the easiest way in VS to see the SOAP being sent?
Example, I added the PayPal WSDL Web Service Reference and made a call as so:
PayPalAPIAASoapBinding _client = new PayPalAPIAASoapBinding();
...rest of code and then
SetExpressCheckoutResponseType checkoutResponse = new SetExpressCheckoutResponseType();
checkoutResponse = _client.SetExpressCheckout(request); // makes the call here
I tried setting a debug point on line 2 but not sure how to dive in to see the SOAP. Obviously I could use something like Fiddler but want to just use Intellisense during debugging to drill down to the object that has the request. I would assume client would have it, my instance above but could not find it. Client is an instance of the PayPal Service.
I do see when I drill down into the base class PayPalAPIAASoapBinding that there is a version property but I can't get the value for this:
System.Web.Services.Protocols.SoapProtocolVersion.Default
when I try to paste that into my watch window, the value just shows the word Default not the true value that's sent. So this is why I need to look at the SOAP and so far in that binding object I don't see a property holding it. But it's gotta be somewhere in any requests you make in a web service in .NET, just don't know where to look during debug?
My end goal here is to be able to read the SOAP envelop before it's being sent really using any WSDL reference in VS.
There's no very easy way. See the example in the SoapExtension documentation on MSDN for a way to log the information.
If you were using WCF, you could just turn on logging in the configuration.
The easiest way to see the SOAP messages (regardless of the programming language) is to use a tool like SoapUI or TCPmon which lets you intercept send and received messages.
This is very easy (if the SOAP is not encrypted). Although it is not in VS.
The easiest way is to use the Fiddler. You can let your VS make Soap calls and see the traffic in raw view on the Fiddler. If the Soap calls are made over SSL, there are some extra steps that needs to be taken for Fiddler to trace them.

Categories

Resources