Oct 14, 2012, 9:07 PM
[CLOSED] Async Store with AJAX Proxy (ASHX) does not update store on client side after successful request
Hi,
In the Examples Explorer is this neat example of autosync:
https://examples2.ext.net/#/GridPanel/Update/AutoSave/
If I edit it locally to force the updated data to be completely different (simulating some scenario where your update causes server to create new values for whatever reason), then those new values (which the user did not type) is correctly rendered to the screen once the store update response is successfully returned.
For reference all I did in the HandleChanges method in the above example is changed the following to update the "Last" property:
So, now I took the same example and used an AJAX proxy instead to an ASHX to do the same thing but this time it doesn't work the same way (the response from the server seems to be ignored)
Here is some sample code.
1) TestPerson.cs
The main difference I notice is in the JSON format of the response. The ExamplesExplorer, which uses the "OnBeforeStoreChanged" event on the Store, and code-behind produces this kind of JSON response:
In the Examples Explorer is this neat example of autosync:
https://examples2.ext.net/#/GridPanel/Update/AutoSave/
If I edit it locally to force the updated data to be completely different (simulating some scenario where your update causes server to create new values for whatever reason), then those new values (which the user did not type) is correctly rendered to the screen once the store update response is successfully returned.
For reference all I did in the HandleChanges method in the above example is changed the following to update the "Last" property:
if (e.Action == StoreAction.Update)
{
foreach (TestPerson updated in persons)
{
updated.Last += " blah blah"; // new line
this.UpdatePerson(updated);
e.ResponseRecords.Add(updated);
}
}
This means if I update the Last field (or any other field in that row) the Last field will always have " blah blah" added to the end from the server. That is great.So, now I took the same example and used an AJAX proxy instead to an ASHX to do the same thing but this time it doesn't work the same way (the response from the server seems to be ignored)
Here is some sample code.
1) TestPerson.cs
public class TestPerson
{
public int? Id { get; set; }
public string Email { get; set; }
public string First { get; set; }
public string Last { get; set; }
public static List<TestPerson> GetPeople
{
get
{
return new List<TestPerson>
{
new TestPerson{Id=1, Email="fred@flintstone.com", First="Fred", Last="Flintstone"},
new TestPerson{Id=2, Email="wilma@flintstone.com", First="Wilma", Last="Flintstone"},
new TestPerson{Id=3, Email="pebbles@flintstone.com", First="Pebbles", Last="Flintstone"},
new TestPerson{Id=4, Email="barney@rubble.com", First="Barney", Last="Rubble"},
new TestPerson{Id=5, Email="betty@rubble.com", First="Betty", Last="Rubble"},
new TestPerson{Id=6, Email="bambam@rubble.com", First="BamBam", Last="Rubble"}
};
}
}
}
2. Cut down ASPX<%@ Page Language="C#" %>
<!DOCTYPE html>
<html>
<head runat="server">
<title>Grid with AutoSave - Ext.NET Examples</title>
</head>
<body>
<form runat="server">
<ext:ResourceManager runat="server" />
<h1>Grid with AutoSave</h1>
<p>An Error has been simulated on the server-side: Attempting to update a record having ODD-numbered id will generate this errror. This error can be handled by listening to the "exception" event upon your Store.</p>
<ext:Store ID="Store1" runat="server" AutoSync="true">
<Model>
<ext:Model runat="server" IDProperty="Id" Name="Person">
<Fields>
<ext:ModelField Name="Id" Type="Int" UseNull="true" />
<ext:ModelField Name="Email" />
<ext:ModelField Name="First" />
<ext:ModelField Name="Last" />
</Fields>
</ext:Model>
</Model>
<Proxy>
<ext:AjaxProxy Url="TestPersons/Get.ashx">
<Reader>
<ext:JsonReader Root="Data" TotalProperty="TotalRecords" />
</Reader>
<Writer>
<ext:JsonWriter Root="Data" Encode="true" WriteAllFields="false" />
</Writer>
<API Update="TestPersons/Update.ashx" />
</ext:AjaxProxy>
</Proxy>
</ext:Store>
<ext:GridPanel
ID="GridPanel1"
runat="server"
Icon="Table"
Frame="true"
Title="Users"
Height="400"
Width="500"
StoreID="Store1"
StyleSpec="margin-top: 10px">
<ColumnModel>
<Columns>
<ext:Column runat="server" Text="ID" Width="40" DataIndex="Id" />
<ext:Column runat="server" Text="Email" Flex="1" DataIndex="Email">
<Editor>
<ext:TextField runat="server" />
</Editor>
</ext:Column>
<ext:Column runat="server" Text="First" Flex="1" DataIndex="First">
<Editor>
<ext:TextField runat="server" />
</Editor>
</ext:Column>
<ext:Column runat="server" Text="Last" Flex="1" DataIndex="Last">
<Editor>
<ext:TextField runat="server" />
</Editor>
</ext:Column>
<ext:CommandColumn runat="server" Width="70">
<Commands>
<ext:GridCommand Text="Reject" ToolTip-Text="Reject row changes" CommandName="reject" Icon="ArrowUndo" />
</Commands>
<PrepareToolbar Handler="toolbar.items.get(0).setVisible(record.dirty);" />
<Listeners>
<Command Handler="record.reject();" />
</Listeners>
</ext:CommandColumn>
</Columns>
</ColumnModel>
<Plugins>
<ext:CellEditing runat="server" />
</Plugins>
</ext:GridPanel>
</form>
</body>
</html>
3. Get ASHX:public class Get : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "application/json";
var data = TestPerson.GetPeople;
var paging = new Paging<TestPerson>(data, data.Count);
context.Response.Write(JSON.Serialize(paging));
}
public bool IsReusable
{
get { return false; }
}
}
4. Update.ashxpublic class Update : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
var response = new StoreResponseData();
var dataHandler = new StoreDataHandler(context);
List<Dictionary<string, string>> data = dataHandler.ObjectData<Dictionary<string, string>>();
foreach (Dictionary<string, string> list in data)
{
try
{
// normally update system with list values
// as example only:
if (list.ContainsKey("Last"))
{
list["Last"] += " blah blah blah";
}
// return the data as response
response.Data = JSON.Serialize(data);
}
catch (Exception e)
{
// logging, etc.
response.Success = false;
response.Message = e.Message;
}
}
response.Return();
}
public bool IsReusable
{
get { return false; }
}
}
Notice in the update I am using Dictionary<string, string> rather than strongly typed TestPerson - this is because I have set WriteAllFields="false" in the JsonWriter - using true seems to have the same result.The main difference I notice is in the JSON format of the response. The ExamplesExplorer, which uses the "OnBeforeStoreChanged" event on the Store, and code-behind produces this kind of JSON response:
{serviceResponse:{success:true,data:{data:[{"Id":4,"Email":"barney@rubble.com","First":"Barney","Last":"Rubbles blah blah"}]}}}
Whereas with the ASHX approach I get this:{data:[{"Id":"5","Email":"betty@rubble.com","First":"Betty","Last":"Rubbles blah blah blah"}]}
I could not see how to get my response data to match the "OnBeforeStoreChanged" version - at least not just using the StoreResponseData class in Update.ashx? Have I missed something (probably obvious!) ?
Last edited by Daniil; Oct 16, 2012 at 5:06 AM.
Reason: [CLOSED]