Link to home
Start Free TrialLog in
Avatar of sutorius
sutoriusFlag for United States of America

asked on

How to convert 'Structure' to serializable result for web service use

I inherited a class library in vb.net. I'm a c# guy.
There is a structure called TestServiceResponse (in the snippet) and there is a method called TestSQLConnect in the class library called EOCQuery.
I have an .asmx page with a web method which calls the method.
However even with the XmlInclude attribute I still get the

Public Structure TestServiceResponse
    Public Version As String
    Public ReturnCode As Integer
    Public ReturnMessage As String
End Structure
 
Public Function TestSQLConnect() As TestServiceResponse
            Dim oRet As New TestServiceResponse
            Dim oDBInfo As CustomerDBInfo
 
            Try
                oDBInfo = GetCustomerInfo()
 
                oRet.Version = ConfigurationManager.AppSettings("HTA_Version").ToString
 
                'Attempt to connect to SQL server.
                If OpenPCON(oDBInfo) Then
                    oRet.ReturnCode = 0
                Else
                    oRet.ReturnCode = 1
                End If
 
                oRet.ReturnMessage = m_oErrors.GetErrorMessage(oRet.ReturnCode)
 
            Catch ex As Exception
                m_oErrors.WriteToEventLog(ex, EventLogEntryType.Error)
 
                oRet.Version = ConfigurationManager.AppSettings("HTA_Version").ToString
                oRet.ReturnCode = 99
                oRet.ReturnMessage = m_oErrors.GetErrorMessage(oRet.ReturnCode)
            End Try
 
            'Cleanup SQL
            Cleanup()
 
            Return oRet
 
        End Function
 
 
<WebMethod()> _
    <XmlInclude(GetType(WebService1))> _
    Public Function TestWebService() As String
 
        Dim result As String
 
        result = PeaWebService.TestWebService.ToString()
 
        Return result
 
    End Function

Open in new window

SP32-20080303-171419.gif
SOLUTION
Avatar of Joel Coehoorn
Joel Coehoorn
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
You cannot serialize structure as easy as putting [serializable] attribute!!
Bcoz you cannot derive a structure from a class since SerializableAttribute is a class..

Do check for the following function in MSDN or in google !
you will get fair idea!

iSizeMemory = Marshal.SizeOf(IN_obTemp.GetType());
ArrayByte = new Byte[iSizeMemory];
ptrSt = Marshal.AllocCoTaskMem(iSizeMemory);
Marshal.StructureToPtr(IN_obTemp, ptrSt, false);
Marshal.Copy(ptrSt, ArrayByte, 0, iSizeMemory);
Marshal.FreeCoTaskMem(ptrSt);

where IN_obTemp is struct object !

Regards
Renju
Instead of these naughty code u can make it class rather than structure? Do you have any restriction for that?

Regards
Renju
Avatar of sutorius

ASKER

I don't think so but I have a question:
The structure is already in a class with a few of other structures. How can I keep code modification to a minimum and 'put a class in a class'?

Another Question:
Instead of assigning the values in the functions to the members of the structure/class would a better design be to declare locals in the function and return those to the web method?
Sub Question:
Using the above scenario...the local return values are of mixed types what is the best function return type for the web method? Sorted List, Array List, Name Value Collection?

Thanks!
Ok, this is good.
One last obstacle I hope, the web method is not showing the values of the key value pair on the webpage.
However during debug it is showing them in the kvp variable prior to displaying the web page.
1) I did away with the Structure and stayed in the function and got dirty with Generics
2) I have stepped through the code in the function and the web method and the values are there however
3) The values do not show up on the web page while debugging...what am I missing?
Public Function TestSQLConnect() As Dictionary(Of String, String)
            Dim instance As New Dictionary(Of String, String)
            Dim oDBInfo As CustomerDBInfo
            Dim Version As String
            Dim ReturnCode As Integer
            Dim ReturnMessage As String
 
            Try
                oDBInfo = GetCustomerInfo()
 
                Version = ConfigurationManager.AppSettings("HTA_Version").ToString
 
                instance.Add("Version", Version)
 
                'Attempt to connect to SQL server.
                If OpenPCON(oDBInfo) Then
                    ReturnCode = 0
                Else
                    ReturnCode = 1
                End If
 
                instance.Add("Return Code", ReturnCode)
 
                ReturnMessage = m_oErrors.GetErrorMessage(ReturnCode)
 
                instance.Add("Return Message", ReturnMessage)
 
            Catch ex As Exception
                m_oErrors.WriteToEventLog(ex, EventLogEntryType.Error)
 
                Version = ConfigurationManager.AppSettings("HTA_Version").ToString
                ReturnCode = 99
                ReturnMessage = m_oErrors.GetErrorMessage(ReturnCode)
 
            End Try
 
            'Cleanup SQL
            Cleanup()
 
            Return instance
 
        End Function
 
 
 
<WebMethod()> _
    Public Function TestSQLConnect() As KeyValuePair(Of String, String)
        Dim Key As String
        Dim Value As String
 
        Dim kvp As New KeyValuePair(Of String, String)
        For Each kvp In PeaWebService.TestSQLConnect
            Key = kvp.Key
            Value = kvp.Value
        Next kvp
 
        Return kvp
 
    End Function

Open in new window

SP32-20080304-173313.gif
Yes YOu dont have the value ! Bcoz , Have a close look at it

 Dim kvp As New KeyValuePair(Of String, String)
        For Each kvp In PeaWebService.TestSQLConnect
            Key = kvp.Key
            Value = kvp.Value
        Next kvp
 
        Return kvp

For each iteration of the loop you will get a keyvalue pair! Am i right??  and last you are returning  keyvalue pair with null value???????


Regards
Renju


ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
No sweat! This is good learning! Below is what I have in the struct.

What I am getting from VS intellisense does not make sense to me since the Structure "serializable".

Take a look at the screen shot on the web method. How do I get past this?
<Serializable()> _
        Public Structure TestServiceResponse
            Public Version As String
            Public ReturnCode As Integer
            Public ReturnMessage As String
        End Structure

Open in new window

SP32-20080305-101800.gif
I got it. Complex types (more than 1 type in a collection) which needs to be returned a web service can be returned using a data table since it is serializable. I got rid of the Structure. Below is the final code.
Public Function TestSQLConnect() As DataTable
            Dim instance As New TestServiceResponse
            Dim oDBInfo As CustomerDBInfo
 
            Try
                oDBInfo = GetCustomerInfo()
 
                instance.Version = ConfigurationManager.AppSettings("HTA_Version").ToString
 
                'Attempt to connect to SQL server.
                If OpenPCON(oDBInfo) Then
                    instance.ReturnCode = 0
                Else
                    instance.ReturnCode = 1
                End If
 
                instance.ReturnMessage = m_oErrors.GetErrorMessage(instance.ReturnCode)
 
            Catch ex As Exception
                m_oErrors.WriteToEventLog(ex, EventLogEntryType.Error)
 
                instance.Version = ConfigurationManager.AppSettings("HTA_Version").ToString
                instance.ReturnCode = 99
                instance.ReturnMessage = m_oErrors.GetErrorMessage(instance.ReturnCode)
 
            End Try
 
            'Cleanup SQL
            Cleanup()
 
            Dim dt As DataTable
            Dim dr As DataRow
            dt = New DataTable("TestSQLConnect")
 
            dt.Columns.Add("Version")
            dt.Columns.Add("Return Code")
            dt.Columns.Add("Return Message")
 
            dr = dt.NewRow
            dr(0) = instance.Version
            dr(1) = instance.ReturnCode
            dr(2) = instance.ReturnMessage
            dt.Rows.Add(dr)
 
 
            Return dt
 
        End Function
 
 
<WebMethod()> _
    Public Function TestSQLConnect() As DataTable
 
        Return PeaWebService.TestSQLConnect
 
    End Function

Open in new window

SP32-20080305-110307.gif
Someone else should get the credit for this answer.
Well I thought I split the points 50/450 but it doesn't look that way does it.
I have submitted a request for help to split the points. Thanks for bringing that to my attention!
Thanks guys for your help!