1. #61
    Ext User Dave.Sanders's Avatar
    Join Date
    Mar 2008
    Posts
    131
    Vote Rating
    0
    Dave.Sanders is on a distinguished road

      0  

    Default


    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

  2. #62
    Sencha Premium Member
    Join Date
    Jun 2008
    Posts
    47
    Vote Rating
    1
    mbajema is on a distinguished road

      0  

    Default 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:
    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;
            }
    Updated portion of DirectProcessor.Execute:
    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));
                    }
                }
    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:

    New function:
    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++;
                }
            }
    Updated portion of DirectProvider.Execute:
    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);
                }
    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:
    [DirectMethod]
    public string MyDirectMethod(MyComplexCustomClass myObject)
    Any thoughts? Does this seem like a good idea?
    Mark Bajema
    Youth Mentoring Software from Innovative Mentoring

  3. #63
    Sencha Premium Member
    Join Date
    Jun 2008
    Posts
    47
    Vote Rating
    1
    mbajema is on a distinguished road

      0  

    Default


    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.
    Mark Bajema
    Youth Mentoring Software from Innovative Mentoring

  4. #64
    Sencha Premium Member
    Join Date
    Jun 2008
    Posts
    47
    Vote Rating
    1
    mbajema is on a distinguished road

      0  

    Default


    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.
    Mark Bajema
    Youth Mentoring Software from Innovative Mentoring

  5. #65
    Ext User Dave.Sanders's Avatar
    Join Date
    Mar 2008
    Posts
    131
    Vote Rating
    0
    Dave.Sanders is on a distinguished road

      0  

    Default


    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:
    1. You want to be able to specify custom types for objects that are passed to your direct method.
    2. You want Ext.Direct to look at the method before deserializing the passed in JSON.
    3. 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

  6. #66
    Sencha Premium Member
    Join Date
    Jun 2008
    Posts
    47
    Vote Rating
    1
    mbajema is on a distinguished road

      0  

    Default


    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.
    Mark Bajema
    Youth Mentoring Software from Innovative Mentoring

  7. #67
    Sencha Premium Member
    Join Date
    Jun 2008
    Posts
    47
    Vote Rating
    1
    mbajema is on a distinguished road

      0  

    Exclamation 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:
    Code:
    List<DirectRequest> requests = JsonConvert.DeserializeObject<List<DirectRequest>>(json, jsettings);
    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.
    Mark Bajema
    Youth Mentoring Software from Innovative Mentoring

  8. #68
    Ext User Dave.Sanders's Avatar
    Join Date
    Mar 2008
    Posts
    131
    Vote Rating
    0
    Dave.Sanders is on a distinguished road

      0  

    Default


    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.

  9. #69
    Ext User Dave.Sanders's Avatar
    Join Date
    Mar 2008
    Posts
    131
    Vote Rating
    0
    Dave.Sanders is on a distinguished road

      0  

    Default


    Quote Originally Posted by mbajema View Post
    By the way, the deserializer in the latest version of Json.Net 3.5 changed enough to break this Ext.Direct .Net implementation.
    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".

  10. #70
    Sencha Premium Member
    Join Date
    Jun 2008
    Posts
    47
    Vote Rating
    1
    mbajema is on a distinguished road

      0  

    Default 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
    Mark Bajema
    Youth Mentoring Software from Innovative Mentoring