Converting String to Structure - vb.net

I am successfully converted structure data to string here in plain and (as suggested) in XML serialized way which obviously every has it's own good and bad side effects.
This is sample structure:
Public Structure myList
Dim a As String
Dim b As Integer
Dim c As Double
End Structure
Dim myInstance As New myList
myInstance.a = "Nemo"
myInstance.b = 10
myInstance.c = 3.14
Now I have 2 functions for converting structure data to string:
Dim xString As String = oStructToString(myInstance)
Public Function oStructToString(ByVal obj As Object) As String
Dim structString As String = ""
Dim i As Integer
Dim myType As Type = obj.GetType()
Dim myField As System.Reflection.FieldInfo() = myType.GetFields()
For i = 0 To myField.Length - 1
structString &= myField(i).GetValue(obj)
If i = myField.Length - 1 Then Exit For
structString &= Convert.ToChar(161)
Next i
Return structString
End Function
Dim xString As String = xStructToString(myInstance)
Public Function xStructToString(ByVal obj As Object) As String
Dim x As New Xml.Serialization.XmlSerializer(obj.GetType)
Dim sw As New IO.StringWriter()
x.Serialize(sw, obj)
Return sw.ToString
End Function
But I can't get data back from string to structure.
Public Function oStringToStruct(ByVal xString As String) As Object
So I can call:
Dim mySecondInstance As New myList = oStringToStruct(xString)
Or
Dim mySecondInstance As New myList = xStringToStruct(xString)
How to do that?
So far I came to this:
Public Function xStringToStruct(ByVal xString As String) As Object
Dim x As New Xml.Serialization.XmlSerializer() ''<- what here?
Dim sr As New IO.StringReader(xString)
Return x.Deserialize(sr)
End Function
and this...
By help of har07 still one error remains here...
Public Function oStringToStruct(ByVal xString As String, ByVal type As Type) As Object
Dim structString() As String = xString.Split(Convert.ToChar(161))
Dim myType As Type = type.GetType()
Dim myField As System.Reflection.FieldInfo() = myType.GetFields()
For i As Integer = 0 To structString.Length - 1
myField(i).SetValue(type, structString(i)) ''here crashes
Next i
Return type
End Function

Deserialize xml string back to struct is easier :
Public Function xStringToStruct(ByVal xString As String, ByVal type As Type) As Object
Dim x As New Xml.Serialization.XmlSerializer(type)
Dim sw As New IO.StringReader(xString)
Return x.Deserialize(sw)
End Function
You can use it like so :
Dim xObject As myList = xStringToStruct(xString, GetType(myList))

Related

How to pass dynamically created type to function?

I am trying to get data from SQL query and convert to List of objects.
From SQL each time I get dataset with variable number of columns and different names of columns.
So I am trying to write some universal code to get and convert this dataset.
Dim MySqlStr As String
MySqlStr = "exec someStoredProcedure "
Try
MyAdapter = New SqlClient.SqlDataAdapter(MySqlStr, Declarations.MyNETConnStr)
MyAdapter.SelectCommand.CommandTimeout = 600
MyAdapter.Fill(MyDs)
'-----Dictionary of columns with types
Dim MyDict = New Dictionary(Of String, Type)
For i As Integer = 0 To MyDs.Tables(0).Columns.Count - 1
MyDict.Add(MyDs.Tables(0).Columns(i).ToString, MyDs.Tables(0).Columns(i).DataType)
Next
'----Dynamic type
Dim MyCls As Type
MyCls = CreateClass("DynClass", MyDict)
Dim MyObj As Object = Activator.CreateInstance(MyCls)
'-----Use newtonsoft
Dim json As String = JsonConvert.SerializeObject(MyDs, Formatting.Indented)
'-----here is a problem
'-----I am tryin to deserialize json
'-----but get a message that MyCls is not defined
'-----how to pass dynamically created type to function correctly?
Dim jsonData = JsonConvert.DeserializeObject(Of List(Of MyCls))(json)
SfDataGrid2.DataSource = jsonData
Catch ex As Exception
End Try
Public Shared Function CreateClass(ByVal className As String, ByVal properties As Dictionary(Of String, Type)) As Type
Dim myDomain As AppDomain = AppDomain.CurrentDomain
Dim myAsmName As New AssemblyName("MyAssembly")
Dim myAssembly As AssemblyBuilder = myDomain.DefineDynamicAssembly(myAsmName, AssemblyBuilderAccess.Run)
Dim myModule As ModuleBuilder = myAssembly.DefineDynamicModule("MyModule")
Dim myType As TypeBuilder = myModule.DefineType(className, TypeAttributes.Public And TypeAttributes.Class)
'Dim getSetAttr As MethodAttributes = MethodAttributes.Public And MethodAttributes.SpecialName And MethodAttributes.HideBySig
Dim getSetAttr As MethodAttributes = MethodAttributes.Public
myType.DefineDefaultConstructor(MethodAttributes.Public)
For Each o In properties
Dim prop As PropertyBuilder = myType.DefineProperty(o.Key, PropertyAttributes.HasDefault, o.Value, Type.EmptyTypes)
Dim field As FieldBuilder = myType.DefineField("_" + o.Key, o.Value, FieldAttributes.Private)
Dim getter As MethodBuilder = myType.DefineMethod("get_" + o.Key, getSetAttr, o.Value, Type.EmptyTypes)
Dim getterIL As ILGenerator = getter.GetILGenerator()
getterIL.Emit(OpCodes.Ldarg_0)
getterIL.Emit(OpCodes.Ldfld, field)
getterIL.Emit(OpCodes.Ret)
prop.SetGetMethod(getter)
Dim setter As MethodBuilder = myType.DefineMethod("set_" + o.Key, getSetAttr, Nothing, New Type() {o.Value})
Dim setterIL As ILGenerator = setter.GetILGenerator()
setterIL.Emit(OpCodes.Ldarg_0)
setterIL.Emit(OpCodes.Ldarg_1)
setterIL.Emit(OpCodes.Stfld, field)
setterIL.Emit(OpCodes.Ret)
prop.SetSetMethod(setter)
Next
Return myType.CreateType()
End Function
Please help with this

VB API Result converts decimal numbers

I have a simple API Post like this
<HttpPost>
Public Function testPost() As IEnumerable(Of sp_select)
Dim _tmplist As New List(Of sp_select)
Dim _Content = jsonSerializer.Deserialize(Of myparams)(Request.Content.ReadAsStringAsync().Result)
Dim mandant = _Content.mandant
Using mycon As New dal_globalDataContext
Dim _result = mycon.sp_select(CType(mandant, Decimal)).ToList
If Not _result.Any = False Then
For Each entry In _result
_tmplist.Add(entry)
Next
End If
End Using
Return _tmplist
End Function
All good. But If I parse the result like this:
Public Sub testPost()
Dim client = New System.Net.Http.HttpClient()
client.BaseAddress = New Uri("http://localhost:62068")
client.DefaultRequestHeaders.Accept.Clear()
client.DefaultRequestHeaders.Accept.Add(New System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"))
Dim _datasource As IEnumerable(Of Object) = Nothing
Dim _content = New With {.mandant = 0}
Dim serializer As New JavaScriptSerializer()
Dim arrayJson As String = serializer.Serialize(_content)
Dim responseTask = client.PostAsync("/actionapi/dataSource/testPost/", New StringContent(arrayJson))
responseTask.Wait()
Dim result = responseTask.Result
If result.IsSuccessStatusCode Then
Dim readTask = result.Content.ReadAsAsync(Of IList(Of sp_select))()
readTask.Wait()
_datasource = readTask.Result
Any decimal property of the class has an decimal point. So 1 will be 1.0
Do you know how to prevent this behaviour?

Add two string arrays to dictionary

I want to merge two string arrays in a Dictionary
I tried this:
Dim array1() As String = {"A","B"}
Dim array2() As String = {"a","b"}
Dim Dict As Dictionary(Of String, String)
For i = 0 To array1.Count() - 1
Dict.Add(array1(i), array2(i))
Next
but i got Null
Dim array1() As String = {"A","B"}
Dim array2() As String = {"a","b"}
Dim Dict As New Dictionary(Of String, String)
For i = 0 To array1.Count() - 1
Dict.Add(array1(i), array2(i))
Next
You don't New the Dictionary, i.e. no object to work with.

Return value of function on VB6

I have a question regarding on returning the value of function in VB6.0..below is my code
Public Function tracePackageError(oPackage As DTS.Package) As String
Dim ErrorCode As Long
Dim ErrorSource As String
Dim ErrorDescription As String
Dim ErrorHelpFile As String
Dim ErrorHelpContext As Long
Dim ErrorIDofInterfaceWithError As String
Dim i As Integer
For i = 1 To oPackage.Steps.Count
If oPackage.Steps(i).ExecutionResult = DTSStepExecResult_Failure Then
oPackage.Steps(i).GetExecutionErrorInfo ErrorCode, ErrorSource, ErrorDescription, _
ErrorHelpFile, ErrorHelpContext, ErrorIDofInterfaceWithError
End If
Next i
End Function
how am i gonna return the value of my function? Please help :(
I think this would work for you...
Public Function tracePackageError(oPackage As DTS.Package) As String
Dim ErrorCode As Long
Dim ErrorSource As String
Dim ErrorDescription As String
Dim ErrorHelpFile As String
Dim ErrorHelpContext As Long
Dim ErrorIDofInterfaceWithError As String
Dim i As Integer
For i = 1 To oPackage.Steps.Count
If oPackage.Steps(i).ExecutionResult = DTSStepExecResult_Failure Then
oPackage.Steps(i).GetExecutionErrorInfo ErrorCode, ErrorSource, ErrorDescription, _
ErrorHelpFile, ErrorHelpContext, ErrorIDofInterfaceWithError
tracePackageError = ErrorDescription
End If
Next i
End Function
Try it out and let me know

How can pass collection list between aspx pages?

I tried to create list of object type and get through session the class type list from another page,but it is not working simply coming out of the code when assigment is done.
Public Sub GetvalueContains(ByVal txtFilterText As String, ByVal strColPropertyName As String, ByVal collectionName As String)
Dim FilteredAgentsList As New List(Of Object)
FilteredAgentsList = CType(HttpContext.Current.Session("FilteredAgentsList"), Object)
AgentList = Session("AgentList")
FilteredAgentsList = CType(HttpContext.Current.Session("AgentList"), Object)
Dim FilteredAgentsListdetails As New List(Of Object)
FilteredAgentsListdetails = HttpContext.Current.Session("FilteredAgentsListdetails")
Dim indx As Integer = 0
Dim indexx As Integer = collectionName.IndexOf("_")
indexx = indexx + 1
Dim str As String = collectionName.Substring(indexx, collectionName.Length - indexx)
Dim grdagents As GridView = HttpContext.Current.Session("grdAgents")
If FilteredAgentsListdetails.Count > 0 Then
FilteredAgentsList = FilteredAgentsListdetails
End If
Dim AgentListTemp As List(Of Object) = HttpContext.Current.Session("AgentListTemp")
AgentListTemp = FilteredAgentsList
'FilteredAgentsListdetails = New List(Of Agents)
strColPropertyName = GetPropertyNameAtIndex(AgentListTemp, Convert.ToInt32(hdncellindex.Value))
txtFilterText = txtFilterText.Replace("*", "")
Dim resultList As IEnumerable(Of Object)
resultList = AgentListTemp.Where(Function(x) x.[GetType]().GetProperty(strColPropertyName).GetValue(x, Nothing).ToString().StartsWith(txtFilterText))
'AgentListTemp = CType(resultList.ToList(), List(Of Agents))
'FilteredAgentsListdetails = AgentListTemp
grdagents.DataSource = Nothing
grdagents.DataBind()
grdagents.DataSource = resultList
grdagents.DataBind()
End Sub
how to get the session value in above code?or any other method to pass list from one page to other.