|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Remoting Server Object not passing propertiesPrivate _name As String Public Property Name() As String Get Return _name End Get Set(ByVal value As String) _name = value End Set End Property Public Sub New() End Sub Protected Sub New(ByVal info As System.Runtime.Serialization.SerializationInfo, ByVal context As System.Runtime.Serialization.StreamingContext) MyBase.New(info, context) End Sub The server object creates, sets the name property and returns it From the server: Inherits MarshalByRefObject Implements IEmployee.IEmployee Public Function GetEmployee() As Employee.Employee Implements IEmployee.IEmployee.GetEmployee Dim TestEmployee As New Employee.Employee TestEmployee.Name = "Harry" Return TestEmployee End Function From the client: ServerEmployee = DirectCast(Activator.GetObject(GetType(IEmployee.IEmployee), URL.ToString), IEmployee.IEmployee) Dim Employee As New Employee.Employee Employee = ServerEmployee.GetEmployee The problem is when the client recieves the object, its name property = "". I have double checked this and when the object is created on the server, the property is set. I have tried it with other collections and it works as expected, the problem seems to be any classes that derive from Collections.Specialized namespace. All of the base properties retain settings. Only properties in the inherited class seem not to retain their settings. Does anyone see something I am missing? Thanks. -- DENNY BROWNE Hi Denny,
Welcome to the MSDN newsgroup. From your description, I understand you have developed a custom class which derives from "NameObjectCollectionBase" class. The class also has a custom string property named "Name". In your .net remoting application, you use a server object to return an instance of this custom class to client-side. However, you found that the returned custom class instance always have empty "Name" value, correct? Based on the code snippet you provided, I've also done some tests by creating a simple custom class inheriting from NameObjectCollectionBase and I did encounter the problem you mentioned. After doing some further research, I found that the problem is caused by the base class "NameObjectCollectionBase". Since "NameObjectCollectionBase" class has implemented the "ISerializable" interface, when the .net runtime serializing the custom class instance, it will call the "GetObjectData" method of the "NameObjectCollectionBase" class. However, "NameObjectCollectionBase" class's "GetObjectData" method only save its own properties, so our sub class's property values are lost. To resolve this problem, we need to explicitly override the "ISerializable.GetObjectData" method to store our own class's property(if you want to persist it). In addition, we also need to retrieve the data back from the SerializationInfo collection in the deserialization constructor, Below is a simple test class I made, you can refer to it on the two methods: ========================== <Serializable()> Public Class EmployeeBase Inherits NameObjectCollectionBase Private _de As New DictionaryEntry Private _name As String Public Sub New() End Sub Public Sub New(ByVal d As IDictionary, ByVal bReadOnly As [Boolean]) Dim de As DictionaryEntry For Each de In d Me.BaseAdd(CType(de.Key, [String]), de.Value) Next de Me.IsReadOnly = bReadOnly End Sub 'New Protected Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext) MyBase.New(info, context) Dim name As String name = info.GetValue("EmployeeBase.Name", GetType(String)) _name = name End Sub Public Property Name() As String Get Return _name End Get Set(ByVal value As String) _name = value End Set End Property Default Public ReadOnly Property Item(ByVal index As Integer) As DictionaryEntry Get _de.Key = Me.BaseGetKey(index) _de.Value = Me.BaseGet(index) Return _de End Get End Property Default Public Property Item(ByVal key As [String]) As [Object] Get Return Me.BaseGet(key) End Get Set(ByVal Value As [Object]) Me.BaseSet(key, Value) End Set End Property Public ReadOnly Property AllKeys() As [String]() Get Return Me.BaseGetAllKeys() End Get End Property Public ReadOnly Property AllValues() As Array Get Return Me.BaseGetAllValues() End Get End Property Public ReadOnly Property AllStringValues() As [String]() Get Return CType(Me.BaseGetAllValues(Type.GetType("System.String")), [String]()) End Get End Property Public ReadOnly Property HasKeys() As [Boolean] Get Return Me.BaseHasKeys() End Get End Property Public Sub Add(ByVal key As [String], ByVal value As [Object]) Me.BaseAdd(key, value) End Sub 'Add Public Overloads Sub Remove(ByVal key As [String]) Me.BaseRemove(key) End Sub 'Remove Public Overloads Sub Remove(ByVal index As Integer) Me.BaseRemoveAt(index) End Sub 'Remove Public Sub Clear() Me.BaseClear() End Sub 'Clear Public Overrides Sub GetObjectData(ByVal info As System.Runtime.Serialization.SerializationInfo, ByVal context As System.Runtime.Serialization.StreamingContext) MyBase.GetObjectData(info, context) info.AddValue("EmployeeBase.Name", _name, GetType(String)) End Sub End Class ============================== Hope this helps. Regards, Steven Cheng Microsoft Online Support Get Secure! www.microsoft.com/security (This posting is provided "AS IS", with no warranties, and confers no rights.) Yes, that solution worked! Thank you for your quick response.
-- Show quoteDENNY BROWNE "Steven Cheng[MSFT]" <stch***@online.microsoft.com> wrote in message news:D1qS4rtMGHA.768@TK2MSFTNGXA01.phx.gbl... > Hi Denny, > > Welcome to the MSDN newsgroup. > > From your description, I understand you have developed a custom class > which > derives from "NameObjectCollectionBase" class. The class also has a custom > string property named "Name". In your .net remoting application, you use a > server object to return an instance of this custom class to client-side. > However, you found that the returned custom class instance always have > empty "Name" value, correct? > > Based on the code snippet you provided, I've also done some tests by > creating a simple custom class inheriting from NameObjectCollectionBase > and > I did encounter the problem you mentioned. After doing some further > research, I found that the problem is caused by the base class > "NameObjectCollectionBase". Since "NameObjectCollectionBase" class has > implemented the "ISerializable" interface, when the .net runtime > serializing the custom class instance, it will call the "GetObjectData" > method of the "NameObjectCollectionBase" class. However, > "NameObjectCollectionBase" class's "GetObjectData" method only save its > own properties, so our sub class's property values are lost. To resolve > this problem, we need to explicitly override the > "ISerializable.GetObjectData" method to store our own class's property(if > you want to persist it). In addition, we also need to retrieve the data > back from the SerializationInfo collection in the deserialization > constructor, Below is a simple test class I made, you can refer to it on > the two methods: > > ========================== > <Serializable()> Public Class EmployeeBase > Inherits NameObjectCollectionBase > > Private _de As New DictionaryEntry > > Private _name As String > > > Public Sub New() > End Sub > > Public Sub New(ByVal d As IDictionary, ByVal bReadOnly As [Boolean]) > Dim de As DictionaryEntry > For Each de In d > Me.BaseAdd(CType(de.Key, [String]), de.Value) > Next de > Me.IsReadOnly = bReadOnly > End Sub 'New > > > Protected Sub New(ByVal info As SerializationInfo, ByVal context As > StreamingContext) > MyBase.New(info, context) > > Dim name As String > > name = info.GetValue("EmployeeBase.Name", GetType(String)) > > _name = name > End Sub > > > Public Property Name() As String > Get > Return _name > End Get > Set(ByVal value As String) > _name = value > End Set > End Property > > > Default Public ReadOnly Property Item(ByVal index As Integer) As > DictionaryEntry > Get > _de.Key = Me.BaseGetKey(index) > _de.Value = Me.BaseGet(index) > Return _de > End Get > End Property > > > Default Public Property Item(ByVal key As [String]) As [Object] > Get > Return Me.BaseGet(key) > End Get > Set(ByVal Value As [Object]) > Me.BaseSet(key, Value) > End Set > End Property > > Public ReadOnly Property AllKeys() As [String]() > Get > Return Me.BaseGetAllKeys() > End Get > End Property > > > Public ReadOnly Property AllValues() As Array > Get > Return Me.BaseGetAllValues() > End Get > End Property > > > Public ReadOnly Property AllStringValues() As [String]() > Get > Return > CType(Me.BaseGetAllValues(Type.GetType("System.String")), [String]()) > End Get > End Property > > > Public ReadOnly Property HasKeys() As [Boolean] > Get > Return Me.BaseHasKeys() > End Get > End Property > > > Public Sub Add(ByVal key As [String], ByVal value As [Object]) > Me.BaseAdd(key, value) > End Sub 'Add > > Public Overloads Sub Remove(ByVal key As [String]) > Me.BaseRemove(key) > End Sub 'Remove > > Public Overloads Sub Remove(ByVal index As Integer) > Me.BaseRemoveAt(index) > End Sub 'Remove > > > Public Sub Clear() > Me.BaseClear() > End Sub 'Clear > > Public Overrides Sub GetObjectData(ByVal info As > System.Runtime.Serialization.SerializationInfo, ByVal context As > System.Runtime.Serialization.StreamingContext) > > MyBase.GetObjectData(info, context) > > info.AddValue("EmployeeBase.Name", _name, GetType(String)) > End Sub > End Class > ============================== > > Hope this helps. > > Regards, > > Steven Cheng > Microsoft Online Support > > Get Secure! www.microsoft.com/security > (This posting is provided "AS IS", with no warranties, and confers no > rights.) > > You're welcome Denny,
Have a good day! Regards, Steven Cheng Microsoft Online Support Get Secure! www.microsoft.com/security (This posting is provided "AS IS", with no warranties, and confers no rights.) |
|||||||||||||||||||||||