Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / Distributed Applications / October 2004

Tip: Looking for answers? Try searching our database.

Problem with Component passing a class

Thread view: 
Enable EMail Alerts  Start New Thread
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 Magazines

Get 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 ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.