The Nitobi Complete UI for ASP.NET 2009 Library is designed to support very large data sets, through the use of Ajax callbacks to the server. With a smaller data set, you can use the Grid or other databound components in local mode, without making any Ajax requests. However, for most cases you will want to use these components in remote mode.
If your ASP.NET pages would benefit from ASP.NET server page caching, remote mode is necessary to prevent the ASP.NET environment from caching the data portion of the component. If your Data URL for your controls is not the same as the page they appear on, the page containing the controls can be cached on the server, which will improve performance.
Setting a remote handler of a Grid to a different ASP.NET page requires setting the Mode property to a remote option (LiveScolling, NonPaging, PagedLiveScroling or Standard), and the GetDataUrl and SaveDataUrl attributes to be set to the remote handler's URL. Here is a sample grid definition:
<ntb:Grid id="g" runat="server" Mode="LiveScrolling" Width="800" Height="300" GetDataUrl="DataHandler.ashx" SaveDataUrl="DataHandler.ashx"> <Columns> <ntb:KeyColumn DataField="ProductSku" /> <ntb:ImageColumn DataField="img" Width="20" CssStyle="padding-top:4px;" /> <ntb:TextColumn MaxLength="25" HeaderText="Text" DataField="ProductName" Width="200" ReadOnly="false" HorizontalAlign="Right" /> <ntb:CheckboxColumn HeaderText="IMG" DataField="BulkAction" ReadOnly="false" /> <ntb:NumberColumn HeaderText="Number" DataField="ProductSKU" Width="150" Mask="#,##0" /> <ntb:NumberColumn HeaderText="Currency" DataField="ProductPrice" width="150" Mask="$#,##0.00" /> <ntb:DateColumn HeaderText="Date" DataField="LastUpdated" mask="MM.dd.yyyy" ReadOnly="false" /> </Columns> </ntb:Grid>
The following C# code shows how the DataHandler accessed above is implemented:
public class DataHandler : IHttpHandler, IRequiresSessionState { public void ProcessRequest(HttpContext context) { XmlDataHandler da = new TestDataHandler(); da.checkForAndProcessAjaxRequest(context.Request, context.Response); } public bool IsReusable { get { return false; } } }
The ProcessRequest method creates a TestDataHandler object and then calls the checkForAndProcessAjaxRequest method on it. That method sends the response to the browser and ends the ASP.NET response. TestDataHandler is a subclass of the XmlDataHandler class and sets up the data providers in its constructor. You can see a full implementation of a custom XmlDataHandler subclass in the demos included with our ASP.NET package. In particular, you can find these classes and mechanism in action in the Sample/grid demos. The gridlivescrolling.aspx page exhibits exactly this approach. The TestDataHandler object instantiated in the code above is the equivalent of the EditorsDataHandler class, which then simply implements a few static data retrieval methods wrapped in the EditorsDataProvider static class.
Limits of Remote Ajax Data Access
One significant limit of remote Ajax data access is that your data handler won't have access to any other content on your original page, whether those are Nitobi components or other ASP.NET controls. The GET requests to get data for the components, and the POST requests to save data on the Grid, are contained by the ASP.NET wrappers, and additional data cannot easily be passed.
By default, the column-based controls pass all of the Columns details to the data handler based on the declaration in the web form. The compressed XML that is generated depends on the NitCols parameter that is passed to the server. Here is a sample request to load the grid:
/default.aspx?
did=&
NitCols=PENvbHVtbnNFbnRpdHk%2BPENvbHVtbnM%2BPEtleUNvbHVtbiBEYXRhRmllbGQ9Il
Byb2R1Y3RT3UiIE5hbWU9IlByb2R1Y3RTa3UiIC8%2BPEltYWdlQ29sdW1uIERhdGFGaWVsZD0iaW1nIiBOYW1lPS
JpbWciIC8%2BPFRleHRDb2x1bW4gRGF0YUZpZWxkPSJQcm9kdWN0TmFtZSIgTmFtZT0iUHJvZHVjdE5hbWUiIC8%
2BPENoZWNrYm94Q29sdW1uIERhdGFGaWVsZD0iQnVsa0FjdGlvbiIgTmFtZT0iQnVsa0FjdGlvbiIgLz48TnVtY
mVyQ29sdW1uIE1hc2s9IiMsIyMwIiBEYXRhRmllbGQ9IlByb2R1Y3RTS1UiIE5hbWU9IlByb2R1Y3RTS1UiIC8
%2BPE51bWJlckNvbHVtbiBNYXNrPSIkIywjIzAuMDAiIERhdGFGaWVsZD0iUHJvZHVjdFByaWNlIiBOYW1lPSJ
Qcm9kdWN0UHJpY2UiIC8%2BPERhdGVDb2x1bW4gTWFzaz0iTU0uZGQueXl5eSIgRGF0YUZpZWxkPSJMYX
N0VXBkYXRlZCIgTmFtZT0iTGFzdFVwZGF0ZWQiIC8%2BPENvbWJvQ29sdW1uIERhdGFTb3VyY2VJZD0icHJ
vZHVjdElkcyIgRGF0YUZpZWxkPSJQcm9kdWN0Q2F0ZWdvcnlJRCIgTmFtZT0iUHJvZHVjdENhdGVnb3J5SUQ
iIC8%2BPEN1c3RvbUNvbHVtbjEgQ2hvaWNlMT0iT3JhbmdlIiBSZWFkT25seT0iVHJ1ZSIgRGF0YUZpZWxkPS
JQcm9kdWN0Q2F0ZWdvcnlOYW1lIiBOYW1lPSJQcm9kdWN0Q2F0ZWdvcnlOYW1lIiAvPjwvQ29sdW1ucz48L
0NvbHVtbnNFbnRpdHk%2B&
GridId=ctl00_main_wc1_g&
RequestType=GET&TableId=_default&
StartRecordIndex=0&start=0&PageSize=50&
SortColumn=&SortDirection=Asc&
uid=1232506196257&nitobi_cachebust=1232506196257
There is currently no support in the ASP.NET Library for adding extra parameters - you would need to write custom JavaScript to modify the GetHandler, as in the Master-Detail samples on our open source component samples. Because of the size of the NitCols parameter, you may have trouble fitting any further parameters into the header - there are limits to the size of a GET request, depending which web browser is used on the client.
In this approach, you would initially define your GetDataUrl as, for example, "DataHandler.aspx?CustomerId=0"; you can then use JavaScript to modify the get handler in the browser.
If you are going to add additional parameters, it is advisable to set the control's IncludeColumnsInUrl attribute to false, to free up space in the request. If doing so, the ColumnsEntity object would have to be created with a set number of columns, rather than basing it on the request. You can then use the DataSourceId attribute of your control, as well as the GetDataUrl, and specify the correct provider in your XmlDataHandler object.
If IncludeColumnsInUrl is set to false, you will need to override the ProcessRequest method to create a new ColumnsEntity object. Here is some sample code for doing so:
public void ProcessRequest(HttpContext context) { XmlDataHandler da = new TestDataHandler(); string columnsXml = someMethodThatGetsColumnXml(); ColumnsEntity columns = ColumnsEntity.createFromXml(columnsXml); da.ColumnsNeededForResponse = columns; da.checkForAndProcessAjaxRequest(context.Request, context.Response); }