BO working locally but failing when using remoting

BO working locally but failing when using remoting

Old forum URL: forums.lhotka.net/forums/t/2343.aspx


CrispinH posted on Wednesday, February 14, 2007

I’ve created a BO inheriting from ReadOnlyListBase which works fine locally but is throwing an error when using remoting.  I suspect it might have something to do with me using a List(Of T) as an argument in the Criteria constructor. All the other BOs in the project are loading correctly, but none of them has a List(Of T) as a Criteria argument.

At the moment I'm testing on a single box, so the 'remote' computer also has the client on it.

The calling function looks like:

    Public Shared Function objWebPagesLookupReadOnlyFetch(ByVal intWebsiteD As Int32) As WebPagesLookupReadOnly
   
    Dim objSqlParameterList As New List(Of SqlParameter)

        Dim objSqlParameter As New SqlParameter("@intWebsiteID", SqlDbType.Int)
        objSqlParameter.Value = intWebsiteD
        objSqlParameterList.Add(objSqlParameter)

        Dim objCriteria As New Criteria("StoredProcedureName", objSqlParameterList)
        Return DataPortal.objFetch(Of WebPagesLookupReadOnly)(objCriteria)
    End Function

In the data access section of the BO, the error (according to line number in the stack trace) is on the Add line below, though it might be in the first line:

    For Each objSqlParameter In objCriteria.objSqlParameterList
 
        objSqlCommand.Parameters.Add(objSqlParameter)

    Next

Not being expert in remote debugging, I'm having difficulty in finding out what actual values have been transferred to the 'remote' computer.

I had a look at this thread: http://forums.lhotka.net/forums/thread/8929.aspx.  Whilst similar, it doesn't seem to be quite the same.

Can anyone shed any light on this? 

Many thanks.

Crispin

xal replied on Wednesday, February 14, 2007

Did you look at the exception & inner exception to see what the error actually was?
You shouldn't have any issues serializing List(Of T). If in doubt, List(Of T) has a ToArray() method that will return an array with all the values in the list. You could pass an array instead of the list.

I'm not possitive, but I think SqlParameter is not serializable. I think that could be the problem....


Andrés

CrispinH replied on Wednesday, February 14, 2007

Andrés

The inner exception is not giving anything away - it just says the DataPortal Fetch method failed. 

I did some checking around the web as to whether SqlParameter was serializable or not and found nothing definitive.  So I wrote a small console app to see if it worked or not:

Sub Main()

Dim objListOfSqlParameter As New List(Of SqlParameter)

Dim objSqlParameter As New SqlParameter("@storedproc", SqlDbType.Int)

objListOfSqlParameter.Add(objSqlParameter)

Console.WriteLine("Serializing...")

Dim objSerializer As New Serialization.XmlSerializer(GetType(List(Of SqlParameter)))

Dim objStreamWriter As New StreamWriter("D:\SqlParameterList.xml")

objSerializer.Serialize(objStreamWriter, objListOfSqlParameter)

objStreamWriter.Close()

Console.WriteLine("Deserializing...")

Dim objSerializer2 As New Serialization.XmlSerializer(GetType(List(Of SqlParameter)))

Dim objListOfSqlParameter2 As New List(Of SqlParameter)

Dim objFileStream As New FileStream("D:\SqlParameterList.xml", FileMode.Open)

objListOfSqlParameter2 = DirectCast(objSerializer2.Deserialize(objFileStream), List(Of SqlParameter))

Console.WriteLine("Done")

Console.ReadLine()

End Sub

This works, so it looks like a List(Of SqlParameter) can be serialized.

Thanks anyway.

Crispin

 

CrispinH replied on Wednesday, February 14, 2007

I did find this message at the top of the trace:

System.Runtime.Remoting.RemotingException: This remoting proxy has no channel sink which means either the server has no registered server channels that are listening, or this application has no suitable client channel to talk to the server.

Initially I ignored this because all the other BOs (before and after this was was invoked) worked perfectly.  I took it to mean that there was an error, but the error message wasn't relevant - but someone else may think differently.

Crispin

RockfordLhotka replied on Wednesday, February 14, 2007

The data portal doesn't use the XmlSerializer. As I discuss in the book, it doesn't provide the capabilities required to serialize object graphs completely. The BinaryFormatter is what is used, and that's what you'd need to use for testing.

Look at the DoClone() implementation discussed in Chapter 3 for some sample code along this line.

That will be your simplest test scheme too - directly run the BinaryFormatter on your Criteria class and see if it can be serialized/deserialized successfully.

xal replied on Wednesday, February 14, 2007

As Rocky explained, Csla uses the binary formatter.
I modified your sample to use a binaryformatter:

        Dim objListOfSqlParameter As New List(Of SqlParameter)
        Dim objSqlParameter As New SqlParameter("@storedproc", SqlDbType.Int)
        objListOfSqlParameter.Add(objSqlParameter)
        Dim objSerializer As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
        Dim objStream As New System.IO.MemoryStream
        objSerializer.Serialize(objStream, objListOfSqlParameter)
        Dim objListOfSqlParameter2 As New List(Of SqlParameter)
        objListOfSqlParameter2 = DirectCast(objSerializer.Deserialize(objStream), List(Of SqlParameter))


It crashes on serialization with a:

Type 'System.Data.SqlClient.SqlParameter' in Assembly 'System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' is not marked as serializable.

So, try to change your code to pass a list that contains serializable objects and create the parameters in the DataPortal_Fetch() method.

I hope that solves it!

Andrés

CrispinH replied on Thursday, February 15, 2007

So much for using the XML serializer so as to be able to look at the output half-way. 

I find it odd that the XML serializer works and the binary one doesn't; odder still that SqlParameter is 'not marked marked as serializable' according to the error message on the binary formatter when it clearly works for the XML serializer.  Oh, well.

Thanks for your help guys.

Crispin

xal replied on Thursday, February 15, 2007

The XmlSerializer works quite differently from the Binary one...
All that the XmlSerializer cares for are public read-write properties. It will not serialize the private fields or readonly properties.

The binary formatter doesn't care about the properties and goes deep and gathers all the fields in the object.

Search for deep and shallow serialization and you'll see the difference. There used to be a good article from Rocky in msdn, but it doesn't seem to be there anymore...


Andrés

Copyright (c) Marimer LLC