-
30 Jul 2009 7:27 AM #61
Is this router considered the "official" router for .NET and ExtJs by Ext? Or is this completely a community thing?
I'm happy to contribute to a google code project if one is set up. Just let me know. I _think_ its pretty well set, but I'm continuing to convert my project over to Ext.Direct, so I might trip across other issues.
Dave
-
30 Jul 2009 8:18 AM #62
Direct methods with complex types
Direct methods with complex types
Ok, back to what I was getting to my post about passing the JSON through and then deserialize each parameter into the actual types of the Direct method...
This needs some serious revision, but I'm just hacking to make it work right now. The object[] Data property is still being deserialized with the ComplexObjectConverter, but I'm overwriting it later. I added a string DataJson property to the DirectRequest class and populate it using a helper function and modified code in the DirectProcessor.Execute method as shown here:
Helper function:
Updated portion of DirectProcessor.Execute:Code:private static string[] GetDataJson(JObject o) { JArray data = (JArray)o["data"]; string[] dataJson = new string[data.Count]; for (int i = 0; i < data.Count; i++) { string j = JsonConvert.SerializeObject(data[i]); dataJson[i] = j; } return dataJson; }
And then in the DirectProvider class, I added a function that deserializes each value in the DataJson array to the actual types in the Direct method and call it from a modified DirectProvider.Execute() method as shown here:Code:else { UTF8Encoding encoding = new UTF8Encoding(); string json = encoding.GetString(httpRequest.BinaryRead(httpRequest.TotalBytes)); JsonSerializerSettings jsettings = new JsonSerializerSettings() { ObjectCreationHandling = ObjectCreationHandling.Auto }; List<DirectRequest> requests = JsonConvert.DeserializeObject<List<DirectRequest>>(json, jsettings); if (requests.Count > 0) { JArray jRequests = JArray.Parse(json); int idx = 0; foreach (DirectRequest request in requests) { request.DataJson = GetDataJson((JObject)jRequests[idx]); responses.Add(DirectProcessor.ProcessRequest(provider, request)); } } else { DirectRequest request = JsonConvert.DeserializeObject<DirectRequest>(json, jsettings); JObject o = JObject.Parse(json); request.DataJson = GetDataJson(o); responses.Add(DirectProcessor.ProcessRequest(provider, request)); } }
New function:
Updated portion of DirectProvider.Execute:Code:private void SetDataTypes(MethodInfo method, DirectRequest request) { int idx = 0; foreach (ParameterInfo p in method.GetParameters()) { object o = JsonConvert.DeserializeObject(request.DataJson[idx], p.ParameterType); request.Data[idx] = o; idx++; } }
And this way, my Direct method can have complex custom classes as parameters. This is a lot easier to use than parsing nested Dictionary<string,object> objects. For example:Code:try { object[] parameters = { request.Data }; if (!method.IsForm) { this.SetDataTypes(method.Method, request); parameters = request.Data; } return method.Method.Invoke(type.Assembly.CreateInstance(type.FullName), parameters); } catch (Exception ex) { throw new DirectException("Error occurred while calling Direct method: " + ex.Message); }
Any thoughts? Does this seem like a good idea?Code:[DirectMethod] public string MyDirectMethod(MyComplexCustomClass myObject)
-
30 Jul 2009 9:42 AM #63
I'm not sure why I hacked that together like I did, but I now see that it would be much easier/cleaner to simply make the Data property of the DirectRequest a JArray type rather than an object[] type. This could then be re-serialized and deserialized into the proper types within the DirectoProvider class.
-
30 Jul 2009 9:56 AM #64
Then again, the DirectRequest fails to deserialize when Data is a JArray (I'm not sure why). I'm actually in way over my head here.
-
30 Jul 2009 12:03 PM #65
I see where you are going, I think, and think that its the next natural progression. Let me restate what you said in a simpler way and see if I'm on base:
- You want to be able to specify custom types for objects that are passed to your direct method.
- You want Ext.Direct to look at the method before deserializing the passed in JSON.
- You want Ext.Direct to attempt to deserialize the json property into the object type listed in the method.
This makes sense to me, as long as there was a fall back of Dictionary<> or some similar style name / value pair object - if its an object, or a string. It would actually be pretty slick, in places that it makes sense, to basically just pass through a business object from the client side, through the JSONConverter, then have it right there in your method to save, etc.
I'm doing something sort of similar, but in my case I'm taking name / value pairs of form data from the dictionary and running a little process to populate my business objects. I sort of like having the extra layer of abstraction there in case I need it, but there might be places that I'd like to pass an object straight through. Would be a time saver at least.
So, were you able to get this all working, or no? If not, I can take a look at the code again and try to figure out how I'd implement it.
Dave
- You want to be able to specify custom types for objects that are passed to your direct method.
-
31 Jul 2009 6:15 AM #66
You explained it much better than me. I do have a working implementation (as I described in the previous post), but like I said, it is a hack. As for falling back to a Dictionary<>, it handles that just fine, because if Dictionary<> is the type of the parameter in your Direct method, it will attempt to deserialize to that (maybe I'm not following you).
I will post my code when I have a chance to code it properly.
By the way, this doesn't work for form-type Direct methods. Ext won't send a complex JSON object along with the form values. Instead, I just serialize my object and send it as a string along with the form values.
-
31 Jul 2009 6:29 AM #67
Latest Json.Net 3.5 breaks Ext.Direct .Net
Latest Json.Net 3.5 breaks Ext.Direct .Net
By the way, the deserializer in the latest version of Json.Net 3.5 changed enough to break this Ext.Direct .Net implementation.
It fails on this line:
My guess is that this just needs to move into a try/catch block and that this line would work if the json really was a batch of requests, but I haven't tested that.Code:List<DirectRequest> requests = JsonConvert.DeserializeObject<List<DirectRequest>>(json, jsettings);
-
31 Jul 2009 6:43 AM #68
Same here on the forms. I'm using some of my own code that will grab all field objects from a higher object down, and create a parameters object to pass along. I do this because I do some custom stuff in the client code with validation and with checking to see if a reason for the update is needed.
I'm still waiting on confirmation, but I posed this question to James at Newtonsoft and he (I think) is making some Json.net changes so that objects that look like this in JSON will get converted into JObjects and JArrays automatically. So, once that code is ready and eventually into Ext.Direct then some of my issues MAY be moot.
Will keep you up to date if I hear anything.
-
31 Jul 2009 6:45 AM #69
Yeah, I saw that, but I didn't pursue it further since that version of Json.Net is beta still. If James adds in the bit about JObject and Jarray like I talked about, then it might be worth grabbing the latest and fixing the issue. Of course, technically we should wait until its out of "beta".

-
5 Aug 2009 7:27 AM #70
Session in Direct Methods
Session in Direct Methods
FYI: In order to access the Session in Direct methods, your generic web handler needs to implement IRequiresSessionState or IReadOnlySessionState (for read only access).
For example, your handler should look like:
Code:public class MyHandler: DirectHandler, IRequiresSessionState


Reply With Quote