.net Remoting - Execute Getter on Host - c#

i'm writing an application that uses .net Remoting via MarshalByRefObject.
I can connect and everything works fine for simple things like method calls.
now the problem is, when i try to access properties on an object i received from an earlier call, the property-getters are execute "client"-side, and not inside the host process.
inside these getters i'm using Marshalling on the local process, so they are required to be running on the host process instead of the client.
My question now: is there any specific way to achieve what i'm trying to do, or will i have to go the route and on the host-side write additional methods in the exposed interface and implementing class, that will return the value of the getters?
My code looks like this:
MyApi api = new MyApi();
var channel = new IpcChannel(processId.ToString());
ChannelServices.RegisterChannel(channel, false);
RemotingConfiguration.CustomErrorsMode = CustomErrorsModes.On;
RemotingConfiguration.ApplicationName = "MyApi-Server" + processId;
RemotingServices.Marshal(api, "service");
for the host process.
And this is the Client-Side
api = (IMyApi)Activator.GetObject(typeof(IMyApi), "ipc://MyApi-" + process.Id + "/service");
MessageBox.Show(api.GetSomething().Someproperty);
thanks for your help

outch, i'm stupid.
not only the implementation of the interface class should derive from MarshalByRefObject, all the other objects that i'm passing around should too.

Related

MarshalByRefObject instead of __TransparentProxy

I have C# dll that is working good with .NET Framework application.
That Dll provides WCF client.
Problem is that mentioned client does not work as a part of Unity application.
I spent some time trying to understand the problem and here is what I found:
factory's CreateChannel() method returns MarshalByRefObject instead of __TransparentProxy.
I am using System.Reflection to get remote object's properties and invoke them. That approach works perfect for __TransparentProxy. And it does not work at all for MarshalByRefObject instance. __TransparentProxy has all the same properties as the remote object. On the other hand MarshalByRefObject instance does not have any of these properties.
Is there anything I can do in this situation?
UPDATE:
Here is the code sample
NetTcpBinding binding = new NetTcpBinding(SecurityMode.None);
object[] parameters = new object[]
{
binding,
new EndpointAddress("net.tcp://127.0.0.1:1234/ICP01")
};
Type factoryType = typeof(ChannelFactory<>).MakeGenericType(typeof(IICP01Remote));
ChannelFactory<IICP01Remote> factory = (ChannelFactory<IICP01Remote>)Activator.CreateInstance(factoryType, parameters);
IICP01Remote remote = factory.CreateChannel();
//remote is MarshalByRefObject not a __TransparentProxy
float result = remote.GetValue(1);
factory.Close();

C# - WCF Message Inspector Doesn't Run

I'm working on refactoring a project that has about 5 different web services, and each web service had a ton of identical code, including adding a message inspector onto the client endpoint behaviors so we could see the request and response data.
Part of the refactoring was to come up with a cleaner model for the web services (e.g. one abstract base service model that did all the common setup, including the addition of the message inspector).
Now, when I make the service calls (invoked via reflection), the service call works perfectly fine, and if I add a breakpoint right after the response comes back, I can see that there are 3 behaviors added to the client's endpoint:
[0] Microsoft.VisualStudio.Diagnostics.ServiceModelSink.Behavior
[1] System.ServiceModel.Description.ClientCredentials
[2] MyProject.MyMessageInspector
...but the message inspector code doesn't seem to get called at all anymore. The inspector code is currently identical to the MSDN example here (except for the class name):
https://msdn.microsoft.com/en-us/library/ms733786(v=vs.110).aspx
The primary difference is that I'm now using generic methods for setting up the client, which looks like this:
...sanity checks, etc...
TClient client = Activator.CreateInstance(typeof(TClient), binding, new EndpointAddress(url)) as TClient;
ClientBase<TInterface> _clientBase = client as ClientBase<TInterface>;
...credentials, timeout, etc...
MyEndpointBehavior _inspector = new MyEndpointBehavior()
_clientBase.Endpoint.Behaviors.Add(_inspector);
Then, when I make a call, I use this code that is located in the new abstract base class (the original code did it this way, and so far the only difference is the use of generics):
ClientBase<TInterface> _clientBase = _client as ClientBase<TInterface>;
using (new OperationContextScope(_clientBase.InnerChannel))
{
// Get the method
MethodInfo mi = _client.GetType().GetMethod(APICall);
// Make the call and return the result if successful
object response = mi.Invoke(_client, APICallParameters);
return response;
}
Any ideas why this worked prior to the switchover to generic methods and not now?
I'm not sure why this made a difference, but I re-ordered the code to move the inspector addition to happen immediately after the client creation, so the code now looks like this:
...sanity checks, etc...
TClient client = Activator.CreateInstance(typeof(TClient), binding, new
EndpointAddress(url)) as TClient;
ClientBase<TInterface> _clientBase = client as ClientBase<TInterface>;
MyEndpointBehavior _inspector = new MyEndpointBehavior()
_clientBase.Endpoint.Behaviors.Add(_inspector);
...credentials, timeout, etc...
The inspector now seems to work as expected. Strange.

How to handle a WCF call per method with lots of methods

I have a DLL that handles making hundreds of method calls either via WCF or directly to QuickBooks. In each method I have code similar to this:
public Response GetSomethingFromQuickBooks()
{
Response response = new Response();
if (useWCF == true)
{
System.ServiceModel.BasicHttpBinding binding = new System.ServiceModel.BasicHttpBinding();
System.ServiceModel.EndpointAddress endpoint = new System.ServiceModel.EndpointAddress(new Uri(wcfEndpoint));
WCFClient = new ServiceReference.OperationsClient(binding, endpoint);
WCFClient.CreateConnection(opsConnectionDTO);
response = WCFClient.GetSomethingFromQuickBooks();
try
{
WCFClient.Close();
}
catch (Exception)
{
WCFClient.Abort();
}
}
else
{
response = qbManager.GetSomethingFromQuickBooks();
}
return response;
}
I have a couple of questions:
1) Is this the proper way to handle WCF calls on a per method basis?
2) Is there a way I can instantiate the WCF client on a per method basis without having to put duplicate code in each method?
Is this the proper way to handle WCF calls on a per method basis?
Well, if we can conveniently ignore fact that you're talking to a service with hundreds of operations defined on it, there are still some things you could be doing differently.
Spinning up a client channel for each call is excessive. Although low, the cost is still significant. It would be better to have some wrapper or factory which could be depended on to manage the lifecycle of the client channel in a sensible way.
Also, it looks like you're using a service reference to call the service. This is sub-optimal for many reasons and should be done only as a last resort, for example when you don't have access to the service interface definition other than via the service metadata. You should be using a WCF Channel otherwise.
Is there a way I can instantiate the WCF client on a per method basis
without having to put duplicate code in each method?
Setting aside the fact that client channels are generally reusable as long as they are not faulted, you could utilise an IoC container to inject a runtime dependency containing a freshly-initialised client channel implementation. Either that or reimplement WCFClient as a reusable wrapper around the client channel as mentioned before.

Writing a generic WCF service client config/endpoint checker?

I have a client application that consumes a number of services. It's not always immediately obvious when a service is down or incorrectly configured. I own the service side code and hosting for most of the services, but not all of them. It's a real mixed bag of client proxies - different bindings (basichttp/wshttp/nettcp), some have been generated using svcutil.exe, while others are made programatically with ChannelFactory where the contract is in a common assembly. However, I always have access to the address, binding and contract.
I would like to have a single component in my client application that could perform a basic check of the binding/endpoint config and the service availability (to show in some diagnostic panel in the client). As a minimum I just want to know that there is an endpoint at the configured address, even better would be to find out if the endpoint is responsive and supports the binding the client is trying to use.
I tried googling and was surprised that I didn't find an example (already a bad sign perhaps) but I figured that it couldn't be that hard, all I had to do was to create a clientchannel and try to open() and close() catch any exceptions that occur and abort() if necessary.
I was wrong - in particular, with clients using BasicHttpBinding where I can specify any endpoint address and am able to open and close without any exceptions.
Here's a trimmed down version of my implementation, in reality I'm returning slightly more detailed info about the type of exception and the endpoint address but this is the basic structure.
public class GenericClientStatusChecker<TChannel> : ICanCheckServiceStatus where TChannel : class
{
public GenericClientStatusChecker(Binding binding, EndpointAddress endpoint)
{
_endpoint = endpoint;
_binding = binding;
}
public bool CheckServiceStatus()
{
bool isOk = false;
ChannelFactory<TChannel> clientChannelFactory = null;
IClientChannel clientChannel = null;
try
{
clientChannelFactory = new ChannelFactory<TChannel>(_binding, _endpoint);
}
catch
{
return isOk;
}
try
{
clientChannel = clientChannelFactory.CreateChannel() as IClientChannel;
clientChannel.Open();
clientChannel.Close();
isOk = true;
}
catch
{
if (clientChannel != null)
clientChannel.Abort();
}
return isOk;
}
}
[Test]
public void CheckServiceAtNonexistentEndpoint_ExpectFalse()
{
var checker = new GenericClientStatusChecker<IDateTimeService>(new BasicHttpBinding(), new Endpointaddress("http://nonexistenturl"));
// This assert fails, because according to my implementation, everything's ok
Assert.IsFalse(checker.CheckServiceStatus());
}
I also tried a similar technique with a dummy testclient class that implemented ClientBase with the same result. I suppose it might be possible if I knew that all my service contracts implemented a common CheckHealth() method, but because some of the services are outside my control, I can't even do that.
So, is it even possible to write such a simple general purpose generic service checker as this? And if so how? (And if not, why not?)
Thanks!
Have you looked at WCF Discovery?
WCF Discovery allows a client to search for a service based on
different criteria including contract types, binding elements,
namespace, scope, and keywords or version numbers. WCF Discovery
enables runtime and design time discovery. Adding discovery to your
application can be used to enable other scenarios such as fault
tolerance and auto configuration.
For a first attempt, you could query the endpoint to see if it supports the expected contract.
The big benefit is that you can have the client “discover” which service it wants to talk to at runtime. Which removes a lot of the client side configuration errors that you are likely used to seeing.
You need to check out SO-AWARE. It is a web service management tool that can manage SOAP or REST WCF-based service across your organization. Further it has a Test Workbench!
Here are a couple of videos that show it off too:
Part 1
Part 2
To put it in perspective, this is so complex that these people make a living doing it, I don't think it's something you want to realistically build on your own.

Using multiple wcf services, factory class to return proxyclient

I have multiple services in my application. WebService1, WebService2,WebService3 and so on..
All the services have same methods, but they are hosted on different IPs.
Now when a client calls a methodA(1) then
WebService1Client.Method() should be called;
client calls a methodA(2) then WebService2Client.Method() should be called.
I do not want to do a switch case for each and every function on the client.
I would rather prefer to create some class/methods which would return the appropriate proxyClient.
How can I create a class to return the object and further how to use that object.
Please point me to some sample codes or references.
Thanks
If all your services implement the same contract (I mean exactly the same, not a contract with the same methods), you can simply create proxies using the ChannelFactory class and cast the returned object into the contract interface.
This should give you the expected generic behavior.
One way to ensure the same interface is used all over is to put it into a separate class library and share it between all projects. Make sure you configure your service references to reuse types in referenced assemblies.
EDIT: This is how you would use the ChannelFactory, you can get rid of the service reference:
BasicHttpBinding myBinding = new BasicHttpBinding();
EndpointAddress myEndpoint = new EndpointAddress("http://localhost/MathService/Ep1");
ChannelFactory<IMath> myChannelFactory = new ChannelFactory<IMath>(myBinding, myEndpoint);
I am not quite sure why you want to wrap the creation of the proxies into a factory. The easiest usage pattern is to new the proxy where you need it and each time when you need. When you are not running reliable sessions or something other heavy stuff it does not have much overhead to new a proxy instance. On the other hand it makes sure that you have a connection that is working and that the channel is not in a faulted state.
When using the proxy you should make sure to close it when done and abort it when it throws an exception.
var proxy = new Proxy();
try { proxy.SomeMethod(); }
catch { proxy.Abort(); }
finally { proxy.Close(); }

Categories