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;
Related
I have created a SOAP service.
Now i want to consume it in a c# client application. I added the service using 'Add service reference' and service reference is added to client.
All my service entities are in service. And in current scenerio i can't move them to a common library.
Problem is, my service endpoint is accepting List<Foo> as parameter.
Foo has a method Boo.
In client, when i try to Foo.Boo() i get Cannot resolve symbol Boo error.
Unfortunately only methods on the service itself are exposed via a SOAP web service, methods on objects used as parameters or return values are not. If the method relates to a server-side operation then you could expose it at the service root level taking the instance object as parameter, or if it relates to a client-side operation you could consider adding it as a client-side extension method.
I am trying to consume a SOAP service in C#, so I added my WSDL as a Service Reference. So far, I have created an instance of the request I want to send, but I don't know how to send it, or process the response.
Can someone explain how to do this?
When you added the service reference, Visual Studio should generate some code for you, including a class for the service which is in its own namespace.
So, you need to create a new instance of this service:
var oService = new ServiceNamespace.ServiceClient();
Then you can call your methods on the service:
oService.SomeMethod();
here you can find the full documentation and sample:
http://msdn.microsoft.com/en-us/library/aa529276.aspx
Here is a full example of How you create a WebService and How to consume it. As I see you just need the part of how to consume it. But it is like a normal call function you send parameters and receieve a result parsed to an object. Sometimes Value Objects created by the Service Reference Tool. Hope it helps.
By the way it uses the Web reference, with a service reference is quite similar just the name of your Class is parsed with a SoapClient at the End, lets say that your service is named Foo, the Service reference will generate it for you like FooSoapClient
How to pass array from WinForm to WebService?
Can I get any C# sample?
In Visual Studio, simply add a Web Reference or a Service Reference to your WinForm project and it will create the service proxy for you. This assumes that your WebService is exposing a WSDL file that describes the methods and parameters used.
This is a pretty broad question, and it would depend entirely on the type of web service you are looking for. Here are some instructions on how to add a Web Service reference:
Add a link to a web service
Once added, you can call whatever method requires an array and pass in the array through the parameters. A sample instantiation and method call for a web service might look like this:
MyWebService myWebServiceInstance = new MyWebService(url);
string[] params = new string[2];
myWebServiceInstance.CallArrayMethod(params);
If the web service is SOAP based, it should have a WSDL. If so, simply import a service reference to the WSDL and it will set up the proxy for you. Then you create an array and pass it to the method in question.
If you are talking REST based services, I would look at the RestBucks implementation on CodePlex (http://restbucks.codeplex.com/). You will want to look at the client side code. It will show you how to add your "array" in the call body, while setting up header information, etc.
Worst case is going down to a lower level and creating your own Request object. Most likely that would be overkill.
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.
Suppose I have the following (rather common) model
Client invokes web service request -> request added to server queue -> server invokes 3rd party app via web service -> 3rd party app notifies server that event processing is finished -> server notifies client that request is completed
What I am wondering about is the 'server invokes 3rd party app via web service' stage. The 3rd party app exposes web service methods that are configured inside the application. For instance, I might create a method in this app called 'MultiplyByTwo'. Then I click 'GO' and it generates a web service with methods like BeginCalculateMultiplyByTwo and EndMultiplyByTwo (using the IAsync model). This is great.
Now I am creating a queue object so that multiple clients can request this service and have the server queue them up for sequential execution. So this queue object will have a method like runNext() that will invoke the web service on the 3rd party app. This is great so long as I know the name of the methods that are being called (BegingCaculateMultiplyByTwo in this case), but what if I want to dynamically change the name of the method?
So in the 3rd party app, I change my web service method and call it 'MultiplyByThree'. This will expose BeginMultiplyByThree and some other methods with a predictable naming scheme. How can I set my class up to dynamically call a method of which I dont yet know the name?
Ideally if I could set the name of the method to be called in an app.config file that would be great.
I suppose this is something I can achieve via reflection?
You can certainly do this via reflection:
MyClass o = new MyClass();
MethodInfo method = o.GetType().GetMethod("UnknownMethod",
BindingFlags.Instance | BindingFlags.Public);
MyRetValue retValue = (MyRetValue)
method.Invoke(o, new object[] { "Arg1", 2, "Arg3" });
To expand on Robert's answer you can do it with generics and stuff:
public TReturn DynamicInvoker<T, TReturn>(T obj, string methodName, param[] args){
MethodInfo method = obj.GetType.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public);
(TResult)method.Invoke(obj, args);
}
If you wanted to make it completely horrible you can do that as a static method of object. You also can pass the BindingFlags as a method parameter.
Maybe this will help - it's a dynamic web service method executor using reflection.
Reflection will only work if you already have a proxy (e.g. from wsdl.exe) that already knows all of the methods that need to be called. If you don't have the proxy, you're out of luck with reflection. For example if your middle layer needs to be able to call methods in the web service that it doesn't yet know about.
Note also reflection will also be harder to do if the web service methods take non-primitives.
WSDL - Web Service Description Language.
What it means is that Web Services are self-describing. All WSDL.exe is doing is creating and compiling proxy classes and methods so you don't have to work with the xml directly.
Not that you want to roll-your-own, but Web Services are essentially just an RPC mechanism that use xml for requests and results. So you don't need to use the fancy proxy objects, you just need to send xml to the web service and receive an xml response and interpret it.