PDA

View Full Version : Bug in Direct.NET (EXT.JS 3.1.1) ?



stalek
12 Feb 2010, 5:07 AM
I use Direct.NET and on client side I very often use DirectFn instead of API configuration object with read method (in such case the params are encoded as an array, so they are embeded in [] brackets). In such case everything works ok.

When I started using API configuration object (DirectProxy) to implement full CRUD, the params started encoding without [] brackets so as a naked object with {} brackets. This way Newtonsoft.Json is trying to decode simple object as a list/array and throws en exception (version 3.5 of Newtosoft.Json). Earlier version of Newtonsoft.Json just returns empty Object as a result of deserialization (also incorrect behavior). To correct this strange behavior I did something like below (file DirectProcessor.cs, method Execute, line 44 - I corrected else clause and added try/catch clause):


//...
else
{
UTF8Encoding encoding = new UTF8Encoding();
string json = encoding.GetString(httpRequest.BinaryRead(httpRequest.TotalBytes));

List<DirectRequest> requests = new List<DirectRequest>();

try
{
requests = JsonConvert.DeserializeObject<List<DirectRequest>>(json);
}
catch
{
}

if (requests.Count > 0)
{
foreach (DirectRequest request in requests)
{
responses.Add(DirectProcessor.ProcessRequest(provider, request));
}
}
else
{
DirectRequest req = JsonConvert.DeserializeObject<DirectRequest>(json);
responses.Add(DirectProcessor.ProcessRequest(provider, req));
}
}


Maybe there is some configuration value to embed params for read method on DirectProxy to encode the params as an array with [] again?

I hope it helps if you encounter problems similar to mine ... :)

Alek

evant
15 Feb 2010, 12:25 AM
I'm not quite sure I follow, can you post what the request looks like from fbug?

stalek
15 Feb 2010, 1:15 AM
Hi,
I think it has been caused because of the number of the request per POST operation, not just because using configuration object for API).

This is json string that comes from httpRequest.BinaryRead method (this is one request per post only):


{"action":"DictionaryElemService","method":"Read","data":[0,50,"SortOrder","ASC",null,"a2f53a6b-65a5-4d81-9b1d-1463128fbeea"],"type":"rpc","tid":5}

The same value is in the request from firebug.

The issue is it's trying to decode request as a list when it's not a list. It has been sent as a simple json object but it doesn't consider such case here.

This is the operation it does always in DirectProcessor.Execute method without considering if it's array of objects in json string or not:


requests = JsonConvert.DeserializeObject<List<DirectRequest>>(json);


In such case it should be such operation for simple json object (without generic List<>):


DirectRequest req = JsonConvert.DeserializeObject<DirectRequest>(json);

Gunmen
16 Feb 2010, 10:57 AM
I'm not quite sure I follow, can you post what the request looks like from fbug?

http://www.extjs.com/forum/showthread.php?p=437284#post437284 ?

czwiryk
17 Feb 2010, 6:17 AM
Stalek, you are correct; this is caused by a combination of Ext.Direct's batching of requests and a change in the Newtonsoft.Json library. I followed the approach used in the ASP.NET MVC implementation of Ext.Direct to work around the issue:



var reader = new StreamReader(httpRequest.InputStream, new UTF8Encoding());
var json = reader.ReadToEnd();

if (json.StartsWith("[") && json.EndsWith("]"))
{
var requests = JsonConvert.DeserializeObject<IList<DirectRequest>>(json);
foreach (var request in requests)
{
responses.Add(ProcessRequest(provider, request));
}
}
else
{
var request = JsonConvert.DeserializeObject<DirectRequest>(json);
responses.Add(ProcessRequest(provider, request));
}


This would replace the contents of the else block in your first post.

stalek
17 Feb 2010, 6:30 AM
Yes, it's more proper workaround ;) and size of the change is similar ...