1. #231
    Sencha User
    Join Date
    May 2012
    Posts
    1
    Vote Rating
    0
    christianpapauschek is on a distinguished road

      0  

    Default JSON generic type deserialization of method parameters

    JSON generic type deserialization of method parameters


    Since JSON.NET supports deserialization of generic .NET types, I rewrote the DirectProvider.Execute method to allow deserialization in this generic sense. The trick is to check the expected types of the invoked method via reflection.

    Note that I also removed the "SanitizeDates" method since it is no longer necessary. "ParseAsJson" is also not included anymore, but can be added again if needed.

    Code:
    internal object Execute(DirectRequest request)
    {
        DirectAction action = this.actions[request.Action];
        if (action == null)
            throw new DirectException("Unable to find action, " + request.Action);
    
    
        DirectMethod method = action.GetMethod(request.Method);
        if (method == null)
            throw new DirectException("Unable to find action, " + request.Method);
    
    
        JArray data = (JArray)request.RequestData["data"];
        int parameterCount = request.Data != null ? request.Data.Length : data.Count;
    
    
        if (parameterCount == 0)
        {
            if (method.Parameters > 0)
                throw new DirectException("Parameters length does not match");
        }
        else
        {
            if (parameterCount > 1 && method.IsForm)
            {
                throw new DirectException("Form methods can only have a single parameter.");
            }
            else if (parameterCount != method.Parameters)
            {
                throw new DirectException("Parameters length does not match");
            }
        } 
    
    
        try
        {
                    
            object[] param = new object[method.Parameters];
            if (request.Data != null)
            {
                // lets use given request data
                param = request.Data;
            }
            else
            {
                // Deserialize generic JSON to specific .NET method types
                for (int t = 0; t < param.Length; t++)
                {
                    Type paramType = method.ParameterInfos[t].ParameterType;
                    param[t] = JsonConvert.DeserializeObject(data[t].ToString(), paramType);
                }
            }
    
    
            Type type = action.Type;
            return method.Method.Invoke(type.Assembly.CreateInstance(type.FullName), param);
        }
        catch (TargetInvocationException ex)
        {
            // send application exception to browser
            if (ex.InnerException != null)
                throw new DirectException(ex.InnerException.ToString());
    
    
            throw new DirectException(ex.Message);
        }
        catch (Exception ex)
        {                
            throw new DirectException("Error occurred while calling Direct method: " + ex.Message);
        }
    }
    Hope this helps someone
    Last edited by christianpapauschek; 30 May 2012 at 4:48 AM. Reason: bugfix

  2. #232
    Sencha User
    Join Date
    Mar 2012
    Posts
    211
    Vote Rating
    0
    hieu79vn is an unknown quantity at this point

      0  

    Default Call a function in C# to get json string

    Call a function in C# to get json string


    Hi

    I have a data grid A and another grid B: When user click on a row of A, B will show a grid detail with the ID of the row clicked in A.
    I have a function called GetBlogList(int rowIDofA) on server (written in C#) which will return a json string.
    How can I call this function and pass the parameter when user click on a row of A by using Ext Direct Router?

    Furthermore, do you have a completed guide to use this library?

    Thank you



  3. #233
    Sencha User
    Join Date
    Oct 2011
    Posts
    61
    Vote Rating
    0
    azinyama is on a distinguished road

      0  

    Default


    Hi All!!! Still on there exception problem. Had dropped the project for a while. Now I'm back still with the same problem. My code is below.

    Code:
    Ext.define('Test.store.Tariff', 
    {
        extend          : 'Ext.data.Store',
        id                 : 'Tariffs',
        autoLoad        : false,
        autoSave        : false,
        autoSync        : true,
        remoteSort      : true, 
        pageSize        : 100,   
        paramOrder      : 'start|limit|page|search', 
        model           : 'Test.model.Tariff', 
        proxy           : {
                            type        : 'direct',
                            reader      : {
                                            type            : 'json',
                                            successProperty : 'success',
                                            totalProperty   : 'total',
                                            root            : 'data',
                                            idProperty      : 'Tariff_RowID'
                                        }, 
                            writer      : {
                                            type            : 'json',
                                            encode          : false,
                                            writeAllFields  : true
                                        }, 
                            api         : {
                                            create  : _tariffHandler.Create_Tariff,
                                            read    : _tariffHandler.Load_Tariff,
                                            update  : _tariffHandler.Update_Tariff,
                                            destroy : _tariffHandler.Delete_Tariff
                                        },
                            listeners   : {
                                            exception   : function(proxy, response, operation)
                                                        {
                                                            Ext.MessageBox.show(
                                                            {
                                                                title   : 'Remote Exception',
                                                                msg     : operation.getError(),
                                                                icon    : Ext.MessageBox.ERROR,
                                                                buttons : Ext.Msg.OK
                                                            });
                                                        }
                                        },
                            updateCallback: function (request, success) 
                                        {
                                            if (!request.operation.success && request.operation.hasException())
                                            {
                                            console.log(request.operation);
                                                Ext.Msg.show(
                                                {
                                                    title   : 'Tariff Update Error',
                                                    msg     : request.operation.getError(),
                                                    buttons : Ext.MessageBox.OK,
                                                    icon    : Ext.MessageBox.ERROR
                                                });
                                            }
                                        }
                        }
    });
    ASP.Net
    Code:
        <DirectMethod()> _
        <ParseAsJson()> _
        Public Function Update_Tariff(ByVal o As JObject) As Tariff
            Dim t As Tariff = Nothing
    
            Try
                'ASSUME NEXT TWO LINES FAIL AND MOVE TO CATCH AND THROUGH EXCEPTION
                t = Newtonsoft.Json.JsonConvert.DeserializeObject(Of Tariff)(o.ToString())
                t.Tariff_Update()
            Catch ex As DirectException
                Throw New DirectException("CUSTOMR EXCEPTION MESSAGE BEING  SEND HERE") '<--- CUSTOMR EXCEPTION MESSAGE BEING SENT HERE BUT 
            End Try
    
            Return t
        End Function
    It is only error message I keep getting is:

    "Error occurred while calling Direct method: Exception has been thrown by the target of an invocation."

  4. #234
    Sencha User
    Join Date
    Dec 2009
    Location
    Gdansk, Poland
    Posts
    25
    Vote Rating
    0
    stalek is on a distinguished road

      0  

    Default Sort and Filter params sent from grid

    Sort and Filter params sent from grid


    Hi,
    does anybody has working copy of this Direct provider with grid/store and remote sorting and filtering?
    I see sorters config value is converted to complex object on server side (after json conversion).
    I see message about different number of params so my method can't be called...
    Is it retired project?

    Thanks,
    Alex

  5. #235
    Ext JS Premium Member westy's Avatar
    Join Date
    Feb 2009
    Location
    Bath, UK
    Posts
    911
    Vote Rating
    41
    westy is a jewel in the rough westy is a jewel in the rough westy is a jewel in the rough

      0  

    Default


    It works with my version of Evan's router.

    You have create classes on the server-side that represents the sorters and filters, since the router can't automagically sort it out for you... this parameters need to get passed through and interpreted by your data layer.

    e.g. (sanitised and simplied versions for brevity - strings with fixed values should obviously be enums, but not posting the complete solution...):
    Code:
        public class SortParam
        {
            public string Property { get; set; }
            public string Direction { get; set; }  // One of "ASC"/"DESC"
        }
    
        public class FilterParam
        {
            public class FilterDetails
            {
                public string Comparison { get; set; }  // One of "eq", "lt" or "gt" for date values.
                public string Type { get; set; }  // One of string, boolean, date, numeric, list
                public string Value { get; set; }
                public string[] ListFilter { get; set; }
            }
    
            public FilterDetails Data { get; set; }
            public string Field { get; set; }
        }
    
        public class SearchCriteriaParam // This what Ext.Direct posts for paged grids, say.
        {
            public long? Page { get; set; }
            public long? Start { get; set; }
            public long? Limit { get; set; }
    
            public SortParam[] Sort { get; set; }
            public FilterParam[] Filter { get; set; }
        }
    Think that's enough posted for now...

    Hope that helps.
    Westy
    Product Architect
    Altus Ltd.

  6. #236
    Sencha User
    Join Date
    Dec 2009
    Location
    Gdansk, Poland
    Posts
    25
    Vote Rating
    0
    stalek is on a distinguished road

      0  

    Default


    Super!
    Thanks for so quick response. I use paged grid (so called infinite grid ) and I will try it later this evening.
    Does it mean if I provide SearchCriteriaParam as the only param on method definition to load data (Read from CRUD) it's converted automatically from set of sent attributes and will be passed as this object?

    Thanks,
    Alex

  7. #237
    Ext JS Premium Member westy's Avatar
    Join Date
    Feb 2009
    Location
    Bath, UK
    Posts
    911
    Vote Rating
    41
    westy is a jewel in the rough westy is a jewel in the rough westy is a jewel in the rough

      0  

    Default


    You'll need it as a param on your method yeah.

    Can't remember if anything needed on client... possibly paramOrder and/or paramsAsHash need setting as appropriate; I forget.
    Product Architect
    Altus Ltd.

  8. #238
    Sencha User
    Join Date
    Dec 2009
    Location
    Gdansk, Poland
    Posts
    25
    Vote Rating
    0
    stalek is on a distinguished road

      0  

    Default


    westy,
    life is not as simple as I thought after your suggestion
    When I run such simple test case like below I see incorrect value on Data property of ResponseObject:
    Code:
    [TestMethod()]
            public void DeserializeObjectTest()
            {
                string value =
                    // {"action":"IncidentListService","method":"Read","data":[1,0,100,[{"property":"TimeOfCall","direction":"DESC"}],null],"type":"rpc","tid":1}
                    "{\"action\":\"IncidentListService\",\"method\":\"Read\",\"data\":[1,0,100,[{\"property\":\"TimeOfCall\",\"direction\":\"DESC\"}],null],\"type\":\"rpc\",\"tid\":1}";
                Type type = typeof(DirectRequest);
                JsonSerializerSettings settings = null;
                DirectRequest actual = JsonConvert.DeserializeObject(value, type, settings) as DirectRequest;
            }
    Number of parameters on Data property is higher then number of params passed in JSON.
    This is because Data property is decorated with conversion attribute like below and has some code provided on Direct level that does wrong conversion:

    Code:
    [JsonConverter(typeof(ComplexObjectConverter))]        public object[] Data
            {
                get;
                set;
            }
    Because of this it causes the exception on Direct level when I try to call method with manually provided list of param...

  9. #239
    Sencha User
    Join Date
    Dec 2009
    Location
    Gdansk, Poland
    Posts
    25
    Vote Rating
    0
    stalek is on a distinguished road

      0  

    Default


    I found source of the problem of course. It's because incorrect conditions flow in code below:

    Code:
    private object[] ReadArray(JsonReader reader)
            {
                ArrayList output = new ArrayList();
                while (reader.Read())
                {
                    if (reader.TokenType == JsonToken.EndArray)
                    {
                        return output.ToArray();
                    }
                    if (reader.TokenType == JsonToken.StartArray)
                    {
                        output.Add(ReadArray(reader));
                    }
                    if (reader.TokenType == JsonToken.StartObject)
                    {
                        output.Add(ReadObject(reader));
                    }
                    else
                    {
                        output.Add(reader.Value);
                    }
                }
    
    
                throw new JsonReaderException();
            }
    I changed it to this version below with minimal changes (although it should be as effective as switch/case):

    Code:
    private object[] ReadArray(JsonReader reader)
            {
                ArrayList output = new ArrayList();
                while (reader.Read())
                {
                    if (reader.TokenType == JsonToken.EndArray)
                    {
                        return output.ToArray();
                    }
                    else
                    if (reader.TokenType == JsonToken.StartArray)
                    {
                        output.Add(ReadArray(reader));
                    }
                    else
                    if (reader.TokenType == JsonToken.StartObject)
                    {
                        output.Add(ReadObject(reader));
                    }
                    else
                    {
                        output.Add(reader.Value);
                    }
                }
    
    
                throw new JsonReaderException();
            }
    The issue was (is) after reading array object the TokeType is set to EndArray and then it executes last operation in message body that is Add(reader.Value)

    Hope it helps anybody...