.NET Forum / .NET Framework / Distributed Applications / October 2004
Problem with Component passing a class
|
|
Thread rating:  |
Gavin - 19 Feb 2004 18:41 GMT I have a problem with passing Classes between client and ServicedComponents in VB.net. An outline of my test situation is as follows …
ClassA – just contains integers a and b, and is marked as serializable
ClassB – a serviced component, inherits from ServicedComponent and is installed in Component Services. It exposes the following method :
Add(byref a as ClassA Dim sum as in Sum=a.a+a. …
ClassC – Test harness to call Class Dim a as new Class a.a=1 a.b= Dim doSum as new Class DoSum.Add(a
The above code is compiled with ClassA as a dll which is then installed on both client and servers in their GAC. Class B is installed in ServicedComponent with activation as a server and ‘Enforce access checks …’ disabled under Authorisation. A proxy is exported and installed on the client When the client program is run all is well, connection is made to the server until the marked (**) line is reached, at which point the client gives an error saying that the cast is invalid. I know the component has visibility of ClassA because I have put test code in there which is more than happy to manipulate them. Further I have put code in that extracts the type name of both a locally declared ClassA object and the one passed in – both are the same. I also tried removing the access to the passed in ClassA, at which point all is fine – no error is generated) So my question is what am I doing wrong,? I’m assuming that for some reason the object sent from the client is being detected as different from the class the server knows about – even though the dll’s present are the same (I’ve checked them in the GAC on both machines) I’ve also run both the client and server on the same box – in this configuration there is no problem I’ve also tried giving ClassA a strong name, this does not solve the problem
I hope there is just something simple I’m not doing…
Regard
Gavin
PS Platform is Windows 2000 Professional SP4, with VisualStudio .Net 2003
Gavin - 20 Feb 2004 07:41 GMT Just a clarification, I neglated to mark the line that causes the problem
Add(byref a as ClassA) Dim sum as int Sum=a.a+a.b <--- this one
Yan-Hong Huang[MSFT] - 20 Feb 2004 10:01 GMT Hello Gavin,
Thanks for posting in the group.
Based on my understanding, now the issue is: You created a service component and registered it in com+ in server A. Then you exported its proxy and installed it in server B. In the service component, you have one method which returns a user defined class instance. However, when you call this method in server B, you got error. Please correct me if I have any misunderstandings.
I setup almost the same environment and tested it. My classA is defined as: [Serializable] public class ClassA { public ClassA() { // // TODO: Add constructor logic here // a = 1; b = 1; }
public int a, b; }
However, I got error messag in server b: ( my application structure is same as yours) An unhandled exception of type 'System.Runtime.Serialization.SerializationException' occurred in system.enterpriseservices.dll
Could you please post here to let me know whether it is the same error message that you met? If so, I will go ahead to dig into it. It seems a serialization error in ClassA. I will reply here with more information as soon as possible.
If you have any more concerns on it, please feel free to post here.
Best regards, Yanhong Huang Microsoft Community Support
Get Secure! ?C www.microsoft.com/security This posting is provided "AS IS" with no warranties, and confers no rights.
Gavin - 20 Feb 2004 12:16 GMT Your interpretation was slightly different from my test, in that it was the client that passes the class to the component, and it's when the component tries to access it that I get the problem. The error I get is as follow
Unhandled Exception: System.InvalidCastException: Unable to cast object of type System.__ComObject to type ComClassLib.ClassA at Microsoft.VisualBasic.CompilerServices.LateBinding.LateGet(Object o, Type objType, String name, Object[] args, String[] paramnames, Boolean[] copyBack at ConsoleApplication1.TestComClass.Main(
When re-trying this just now I did have it working once, but as soon as I changed the contents of classA I get the above error - despite my best efforts to put the new classA dll on both machines, re-installing the Component, and re-exporting and installing on the client. I've also cleaned out the gac of previous versions of anything I could find relevant
Any thoughts, there must be something I missing about cleaning up one or other of the machines
Ga
PS Below is my current test cod
*** ClassA (in ComClassLib)... Imports System.EnterpriseService Imports System.Runtime.InteropService <GuidAttribute("B25D9733-A1B2-420D-8F6B-478E2B051C83"), Serializable()> Public Class Class Public s As Intege Public a As Intege Public b As Intege End Clas
***My component.(in CompMaths).. Imports System.EnterpriseService Imports System.Reflectio Imports ComClassLi Public Class CMath Inherits ServicedComponen Public Function DoCalc(ByVal cla As ClassA) As Intege Dim res As Intege MsgBox("About to access class" res = cla.a + cla. MsgBox("Accessed class OK" Dim z As New Class z = cl MsgBox("Coppied class OK" Return re End Functio End Clas
*** My test client.... Imports ComClassLi Imports CompMath Module TestComClas Sub Main( Dim x As New Class x.a = x.b = Dim o As New Objec o = CreateObject("CompMaths.CMaths" Console.WriteLine("Pre call" Dim res As Intege res = o.DoCalc(x Console.WriteLine(res Console.WriteLine("Post call" MsgBox("end" End Su End Modul
Yan-Hong Huang[MSFT] - 23 Feb 2004 07:28 GMT Hi Gav,
Thanks very much for your update. Sorry for the late response due to the weekend.
This seems strange since it works for once. What content did you change? Before going forward, I suggest you create a new client class and redo the steps. If it works fine this time, I think this problem may be related to DLL and component registering. If it has the same problem, we need to look into codes first.
One of the things that I could think of is the registry keys that ClassA may create. Try searching that in registry and delete corresponding registry keys if it is related to DLL and component registering. Also, use Windows explorer to make sure that it is removed from GAC too.
If the problem still can't be resolved, please feel free to post here.
Best regards, Yanhong Huang Microsoft Community Support
Get Secure! ?C www.microsoft.com/security This posting is provided "AS IS" with no warranties, and confers no rights.
Gavin - 23 Feb 2004 15:01 GMT I've managed to get passed it only working once. What appears to have been happening was the old dll was still in memory, when the new one was installed in the gac - is that possible? What I did to prove this was make each ClassA pop up a message box with an 'I'm a verison xx' and managed to get a version 4 message box on the server after I had uninstalled v4 and replaced it with v5. A while later I re-did the test after not changing anything and got a v5 message instead. So I am able to proceed, thanks for your help.... ....but this brings me to the problem that this little test program was working towards, I'll continue in this thread because it is based on the same code.. rather than passing a single class to the server I want to pass a Hashtable of that class, so the extra code at the server becomes ..
Public Function DoAllCalcs(ByVal all As Hashtable) As Intege Dim res As Intege Dim z As Class Dim o As Objec For Each o In al MsgBox("About to do cast" z = DirectCast(o, ClassA) << line 3 MsgBox("done cast" res += DoCalc(z Nex Return re End Functio
and the client is (where x is an instance of ClassA
Dim ht As New Hashtabl ht.Add(1, x ht.Add(2, x Dim cc As CompMaths.CMath o = CreateObject("CompMaths.CMaths" cc = CType(o, CompMaths.CMaths res = cc.DoAllCalcs(ht
With this configuration I get the following message
Unhandled Exception: System.InvalidCastException: Specified cast is not valid
Server stack trace at CompMaths.CMaths.DoAllCalcs(Hashtable all) in E:\c\testdotnet\TestComClasses\CompMaths\Maths.vb:line 3 at System.Runtime.Remoting.Messaging.StackBuilderSink.PrivateProcessMessage(MethodBase mb, Object[] args, Object server, Int32 m thodPtr, Boolean fExecuteInContext, Object[]& outArgs at System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage(IMessage msg, Int32 methodPtr, Boolean fExecuteInContex
Exception rethrown at [0] at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type at CompMaths.CMaths.DoAllCalcs(Hashtable all) in E:\c\testdotnet\TestComClasses\CompMaths\Maths.vb:line 2 at ConsoleApplication1.TestComClass.Main() in E:\c\testdotnet\TestComClasses\ConsoleApplication1\Main.vb:line 3
Any thoughts on this one
Thanks
Yan-Hong Huang[MSFT] - 24 Feb 2004 07:43 GMT Hello Gav,
Thanks for your update.
I thought this is a language issue instead of a remoting issue. :) When I create a console VB.NET application on it and it still throws InvalidCastException when runnning DirectCast line.
Please change the code to the following in the For Each loop: For Each o In all.Keys MsgBox("About to do cast") z = all(o) MsgBox(z.a.ToString) Next
It should work then. Please test it and let me know if it works for you.
Best regards, Yanhong Huang Microsoft Community Support
Get Secure! ?C www.microsoft.com/security This posting is provided "AS IS" with no warranties, and confers no rights.
gavin - 27 Feb 2004 12:41 GMT That certainly does the trick, nice easy one for you
thanks for your hel
Gav
Yan-Hong Huang[MSFT] - 01 Mar 2004 01:25 GMT Hi Gav,
I am glad to be of assistance. :)
Thanks for participating the community.
Best regards, Yanhong Huang Microsoft Community Support
Get Secure! ?C www.microsoft.com/security This posting is provided "AS IS" with no warranties, and confers no rights.
J?lio Carvalho - 04 Oct 2004 14:24 GMT ...
See the end of this message for details on invoking just-in-time (JIT) debugging instead of this dialog box.
************** Exception Text ************** System.InvalidCastException: Unable to cast object of type System.__ComObject to type LuxLibTeste.Servico01. at System.Runtime.InteropServices.Marshal.GetTypedObjectForIUnknown(IntPtr pUnk, Type t) at System.EnterpriseServices.ServicedComponentProxyAttribute.CreateInstance (Type serverType)
...
I solved this problem ... remove and reinstall .Net Framework ... if you use the .Net Framework version 1.0 ... and if you have a problem to reinstall ... you must install the version 1.1 ... I did it in several machines and it worked in all of them.
...
J?lio Carvalho Programmer C# .Net julio.carvalho@gmail.com
DotNetJunkies User - 14 Jun 2004 07:02 GMT Hi
When i am using similar kind of application i too got the same error but when i kept [Serializable] attribute for user defined class which you are passing as parameter for COM+ method that problem is solved,in my case this is happend,can yiou try it out
from prasanna_godugu@yahoo.com
---
J?lio Carvalho - 04 Oct 2004 14:24 GMT ...
See the end of this message for details on invoking just-in-time (JIT) debugging instead of this dialog box.
************** Exception Text ************** System.InvalidCastException: Unable to cast object of type System.__ComObject to type LuxLibTeste.Servico01. at System.Runtime.InteropServices.Marshal.GetTypedObjectForIUnknown(IntPtr pUnk, Type t) at System.EnterpriseServices.ServicedComponentProxyAttribute.CreateInstance (Type serverType)
...
I solved this problem ... remove and reinstall .Net Framework ... if you use the .Net Framework version 1.0 ... and if you have a problem to reinstall ... you must install the version 1.1 ... I did it in several machines and it worked in all of them.
...
J?lio Carvalho Programmer C# .Net
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|