-
16 Jan 2008 4:27 AM #1
Question on MetaData, Jayrock, JsonReader, JsonStore
Question on MetaData, Jayrock, JsonReader, JsonStore
Hi all,
I'm planning to use Jayrock's JSON-RPC web services written in .NET to pass data from FDO datastore (see FDO Data Access Technology) to ExtJS-enabled client. Similar JsonReader/JsonStore question has been answered here many times I guess, but I need some tips to glue pieces together. There's also one tiny difference when talking about this specific JsonStore implementation. BTW, JavaScript is not my native dev platform - I'm on .NET and still mix OOP concepts between the two in my head (SOAP/XML and JSON differences included)... so please have understanding when reading this post
Here's my problem - I need to grab both data structure (metadata) and data itself, in a single call to a web service. Jayrock's JSON-RPC does a great job of serializing managed objects to JSON streams, of course, having in mind that object structure needs to conform to what's expected on a client side.
Now, managed FDO reader sitting on server side provides both structure (metadata) and associated data. I could, of course, establish two web methods - one getter for the metadata and the other for data itself, but that would make two (bah) calls to the server - the second one would use metadata returned from the first one to define fields. So, I guess I need to serialize my .NET class to ressemble Store object to include field definitions - but I don't know whether I need to superclass (well, inherit) either ExtJS JsonStore or JsonReader to parse resulting structure. Any help on this is highly welcome
Regards,
Maksim Sestic
-
16 Jan 2008 4:58 AM #2
Some visual aids on this...
Some visual aids on this...
I guess I understood the ExtJS basics right:

Regards,
Maksim Sestic
-
17 Jan 2008 1:48 AM #3
Solution - API documentation says it all...
Solution - API documentation says it all...
Well, some of you would say - RTFM
... So i did. Although very cryptic for an ExtJS beginner like me, this specific API documentation paragraph on JsonReader explains a lot:
...Using the MetaData property, and the Store's metachange event, it is possible to have a Store-driven control initialize itself. The metachange event handler may interrogate the MetaData property (which may contain any user-defined properties needed) and the MetaData.fields property to perform any configuration required...
I simply missed to interpret this correctly, so I started from scratch with DataProxy and Store abstract classes... and ended up with working example. Guess what? When I took a look at JsonStore source I was stunned - it was actually what I came up with too
. To conclude - ExtJS already exposes necessary funcionality, it's simply up to developer to prepare functional object to get serialized to JSON using Jayrock's JSON-RPC:
Access to additional (FDO-specific) MetaData fields is easily achieved via MetaData.fields.Code:{ 'metaData': { root: 'fields', schemaName: 'featureSchema', className: 'featureClass', ...other related FDO attributes... fields: [ {name: 'propertyName1', type: 'string'}, {name: 'propertyName2', type: 'float'}, {...} ], }, 'results': 2, 'fields': [ { 'propertyName1': '...', 'propertyName2': '...' }, {...} ] }
Regards,
Maksim Sestic
-
17 Jan 2008 3:18 AM #4
Now for the Record structure...
Now for the Record structure...
Of course, I'm still struggling with elegant solution to the Record part of above example - namely, Jayrock's JSON-RPC serializes object structure in the following manner:
This will, when properly instantiated and all, get MyOtherClass serialized to:Code:Public Class MyOtherClass Public root As MyClass End Class Public Class MyClass Public name As String Public type As String End Class
As you can see, properties were serialized in propertyName:propertyValue manner which is fine unless you need a JS array where first member differs by name, while second member differs by type:Code:{'root':[{name: 'nameValue', type: 'typeValue'}]}
So this is exactly how ExtJS Record gets initialized - via array. Notably, though, .NET classes cannot have neither arbitrary property names nor types throughout different instances (see 'propertyName1','propertyName2'...). Establishing a proxy structure (class) with strict property names and types to reflect a FDO class would, naturally, diminish a purpose of dynamically instantiated data structure, so I was thinking if it's possible to instantiate a Record via following structure:Code:{'propertyName1': 'A String property value'}, {'propertyName2': 10}, ...
I guess not (?)... Any ideas?Code:{name: 'propertyName1', value: 'A String property value'}, {name: 'propertyName2', value: 10}, ...
Regards,
Maksim Sestic
-
17 Jan 2008 4:03 AM #5
The last piece of the puzzle - solved
The last piece of the puzzle - solved
Well, solved Record structure too. To create a JS array ressembling to:
you need to serialize instantiated .NET class having this specific generic type:Code:{'propertyName1': 'A String property value'}, {'propertyName2': 10}, ...
where fields property represents a Record structure. To get the structure filled with a single record you should simply use:Code:Public Class FeatureClass Public metaData As MetaData Public results As Integer Public fields As New List(Of Hashtable) End Class
...since Hashtable receives a String key type and Object value type. Short and elegant at the same time. This is the last piece of the puzzle, applicable to any data store (not just FDO-based one).Code:Dim fc As New FeatureClass ... Dim h As New Hashtable h.Add(propertyName, propertyValue) fc.fields.Add(h)
Regards,
Maksim Sestic
-
18 Jan 2008 3:03 AM #6
Problems with Store implementation
Problems with Store implementation
I tought that having valid JSON stream will get my problem solved, but alas...
Store object won't parse incoming JSON. When received via:
Response returned to successCallbackFn function looks like (formatted for easier reading):Code:// Parameters to getMyClass method, part of JsonRpcService var params = { featureSourceName: 'GisServer', className: 'Road', propertyName: 'StreetName', valueFilter: '', isGrouped: 1, isOrdered: 1 } var buf = { id: 1, // JsonRpcService needs this identifier method: 'getMyClass', // Name of the targeted JsonRpcService method params: params // Parameters to getMyClass method, as defined above } var encodedParams = Ext.util.JSON.encode(buf); Ext.Ajax.request({ url: 'http://.../JsonRpcService.ashx', method: 'POST', params: encodedParams, success: function(response) {successCallbackFn(response)}, failure: function(response) {failureCallbackFn(response)} });
Firebug reports a successful POST to JsonRpcService.ashx having post part look like:Code:{ "id":1, "result":{ "metaData":{ "root":"fields", "id":"StreetName", "fields":[ {"name":"StreetName","type":"string"} ] }, "results":307, "fields":[ {"StreetName":"1st Street"}, {"StreetName":"2nd Street"}, {...} ] } }
{"id":1,"method":"getStringProperty","params":{"featureSourceName":"GisServer","className":"Road","propertyName":"StreetName","valueFilter":"","isGrouped":1,"isOrdered":1}} and header part Content-Type set to text/plain; charset=utf-8.
Having it prepared right (?), I went further to create Reader object that will consume said JSON stream, for passing it further to the Store:
Debugger receives following exception:Code:function successCallbackFn(response){ var reader = new Ext.data.JsonReader(); reader.read(response); // As per API documentation, but fails here... };
Record has no properties
[Break on this error] f = Record.prototype.fields, fi = f.items, fl = f.length;
I guess I'm missing something in response.responseText, but - what exaclty?
Regards,
Maksim Sestic
-
21 Jan 2008 1:31 AM #7
Discussion continued on a new thread...
Discussion continued on a new thread...
Following thread holds the rest of discussion related to Jayrock's JSON-RPC problem:
http://extjs.com/forum/showthread.php?t=23603
Regards,
Maksim Sestic


Reply With Quote