I am having issues parsing JSON data from a web service. The web service is local on my machine, and I have added it as a Web Reference. Simple data types from the service work perfectly. However, if I call a method that returns a complex structure (such as an array of structures), the object values are Nothing.

For instance,

Dim ClientOffices As New Object
ClientOffices = NTGateway.GetClientOffices()

gives me an object with 31 item objects, all of which are empty.

This is the data that is returned from the web service method:

[{"Name":"Corporate Office","ID":1},{"Name":"Satellite Office","ID":43},{"Name":"Melville","ID":1370},{"N ame":"Orlando","ID":1383},{"Name":"terry","ID":138 5},{"Name":"marty","ID":1386},{"Name":1.0,"ID":138 7},{"Name":"dallas","ID":1389},{"Name":"Demo Company","ID":1391},{"Name":"Levi","ID":1436},{"Na me":"Broward","ID":1439},{"Name":"Morgan","ID":150 5},{"Name":"Scott","ID":1623},{"Name":"Katie","ID" :1625},{"Name":"Miami","ID":2183},{"Name":"Adapt", "ID":2190},{"Name":"High Point","ID":2604},{"Name":"Chicago","ID":2612},{"N ame":"jim","ID":2647},{"Name":"Hawaii","ID":2666}, {"Name":"Custom Solutions","ID":2669},{"Name":"Tina","ID":2886},{" Name":"Greensboro","ID":3027},{"Name":"Melissa","I D":3799},{"Name":"High Point","ID":3815},{"Name":"Education","ID":3996},{ "Name":"Med Surg","ID":3997},{"Name":"ER","ID":3998},{"Name":" critical care","ID":3999},{"Name":"Critical care","ID":4103},{"Name":"Main Office","ID":4192}]

It works if I use a jQuery parser, but I can't seem to get the same results in VB.

Thanks

Dani AI

Generated

Good find — the symptom (an object array with empty members) usually comes from a type-mismatch between what ColdFusion exposes over SOAP and what the .NET proxy expects. ColdFusion will often expose arrays-of-structs as impl:ArrayOf_xsd_anyType / xsd:anyType; the generated .NET proxy therefore gives object placeholders that don’t map the struct fields. That explains why a direct JSON consumer (jQuery) works while the SOAP web reference shows empty objects.

Practical options that avoid per-item hacks:

  • Make the service return a single JSON string (SerializeJSON(theArray)) and declare the function’s return type as string. SOAP will happily carry a plain string and the client can parse the whole JSON in one pass.
  • Expose the CFC method as JSON (CFC?method=getClientOffices&returnformat=json) and fetch it with WebClient/HttpWebRequest instead of using a SOAP Web Reference.
  • If SOAP must be used, change the service to return a strongly typed structure (a WSDL-friendly component or simple arrays of primitives) so the .NET proxy can generate correct types.

Example client workflow (VB.NET + Json.NET) — parse a JSON array into a typed list:

Public Class Office
    Public Property Name As String
    Public Property ID As Integer
End Class

Dim json As String
Using wc As New System.Net.WebClient()
    json = wc.DownloadString("http://localhost/service.cfc?method=getClientOffices&returnformat=json")
End Using

Dim offices = Newtonsoft.Json.JsonConvert.DeserializeObject(Of List(Of Office))(json)

Notes and troubleshooting: ensure .NET property names map to the JSON keys (or use <JsonProperty("Name")> to map different names). Inspect the raw response with a browser or Fiddler to confirm whether the SOAP body contains JSON or an xsd:anyType payload — that drives which approach is simplest and most robust.

I've found a "solution". It's not perfect, but it works pretty well. If you use SerializeJSON when returning this data from the ColdFusion web service, it will convert it into a properly formatted JSON string. In this case we are actually returning an array of structures, so instead of serializing the entire object, if you serialize each struct as you append it to the array, it gets returned as a impl:ArrayOf_xsd_anyType SOAP type. .NET has no trouble with this at all. Then there's a couple lines to write in .NET to convert that into objects:

<cfset retArray = ArrayNew(1) />

<cfloop query="queryToProcess">

<cfscript>

tempStruct = StructNew();

StructInsert(tempStruct, "Field1", queryToProcess.field1);
StructInsert(tempStruct, "Field2", queryToProcess.field2);

ArrayAppend(retArray, SerializeJSON(tempStruct));

</cfscript>

</cfloop>
Dim objTemp As Object 'This has to be created as an object instead of an array.
objTemp = WebServiceClass.GetData() 'This would be the web service class created by the Web Reference.

Dim serializer As New JavaScriptSerializer()
Dim theClass As New MyClass()
Dim theCollection As New MyClassCollection() 'These are your class objects
Dim index As Integer = 0

'Loop through each entity in the object
For index = 0 To objTemp.length - 1
theClass = serializer.Deserialize(Of MyClass)(objTemp(index)) 'Deserialize the JSON data
theCollection.Add(theClass) ' Add it to the collection
Next

The important thing here is that the Class created in .NET must have properties named exactly the same as the keys of the structure. Otherwise, they will not map properly.

I hope this helps someone else out there. I searched for hours to find a solution and found many others having the same problem, with no answer.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.