Scenario:
I should implement a grid with paging, sorting, filtering, and CRUD on a simple database table.
Database can be accessed only through a WCF service layer.
Paging, sorting, filtering should be done on service layer.
I use RadGrid 2011Q3 and ASP.NET 4.0, IE8, Win7 32bit
I've managed to implement the paging, sorting and filtering using ObjectDataSource with custom paging and some hacking, but there are problems:
- RadGrid calls the ObjectDataSource Select method with maximumRows=-1, no matter what is in PageSize property
(I did a workaround, but this is strange)
- paging works fine until the first attempt to filtering. After the first filtering, the Pager hides, and remains hidden until closing and reopening the page in browser!
- I use System.Linq.Dynamic on WCF service layer to do the filtering, with the filterexpression coming from RadGrid. It's ok for numeric columns, but throws exception on string columns on every type of filtering except of IsNull and IsNotNull filtering. (See attached exception)
- despite setting RadGrid width propery to 1000px, grid spans more wider on screen
ManageXXXs.aspx:
ManageXXXs.aspx.cs:
XXXSource.cs
Server side:
I should implement a grid with paging, sorting, filtering, and CRUD on a simple database table.
Database can be accessed only through a WCF service layer.
Paging, sorting, filtering should be done on service layer.
I use RadGrid 2011Q3 and ASP.NET 4.0, IE8, Win7 32bit
I've managed to implement the paging, sorting and filtering using ObjectDataSource with custom paging and some hacking, but there are problems:
- RadGrid calls the ObjectDataSource Select method with maximumRows=-1, no matter what is in PageSize property
(I did a workaround, but this is strange)
- paging works fine until the first attempt to filtering. After the first filtering, the Pager hides, and remains hidden until closing and reopening the page in browser!
- I use System.Linq.Dynamic on WCF service layer to do the filtering, with the filterexpression coming from RadGrid. It's ok for numeric columns, but throws exception on string columns on every type of filtering except of IsNull and IsNotNull filtering. (See attached exception)
- despite setting RadGrid width propery to 1000px, grid spans more wider on screen
ManageXXXs.aspx:
<%@ Page Title="" Language="C#" MasterPageFile="~/Admin.Master" AutoEventWireup="true" CodeBehind="ManageXXXs.aspx.cs" Inherits="Admin.UI.Pages.ManageXXXs" %>
<%@ Register TagPrefix="telerik" Namespace="Telerik.Web.UI" Assembly="Telerik.Web.UI" %>
<
asp:Content
ID
=
"Content1"
ContentPlaceHolderID
=
"head"
runat
=
"server"
>
</
asp:Content
>
<
asp:Content
ID
=
"Content2"
ContentPlaceHolderID
=
"ContentPlaceHolder1"
runat
=
"server"
>
<
telerik:RadGrid
runat
=
"server"
ID
=
"grid"
Width
=
"1000px"
AllowPaging
=
"True"
AllowCustomPaging
=
"true"
PageSize
=
"20"
AllowSorting
=
"true"
DataSourceID
=
"objectDataSource"
AllowFilteringByColumn
=
"true"
>
<
PagerStyle
Mode
=
"NextPrevAndNumeric"
/>
<
MasterTableView
DataKeyNames
=
"XXXID"
AutoGenerateColumns
=
"false"
EditMode
=
"InPlace"
ShowHeadersWhenNoRecords
=
"true"
NoMasterRecordsText
=
"---"
CommandItemDisplay
=
"Top"
>
<
Columns
>
<
telerik:GridEditCommandColumn
ButtonType
=
"LinkButton"
/>
<
telerik:GridBoundColumn
DataField
=
"XXXID"
HeaderText
=
"XXXID"
ReadOnly
=
"true"
/>
<
telerik:GridBoundColumn
DataField
=
"Isin"
HeaderText
=
"Isin"
/>
<
telerik:GridBoundColumn
DataField
=
"InstrumentCode"
HeaderText
=
"InstrumentCode"
/>
<
telerik:GridBoundColumn
DataField
=
"RIC"
HeaderText
=
"RIC"
/>
<
telerik:GridBoundColumn
DataField
=
"Ticker"
HeaderText
=
"Ticker"
/>
<
telerik:GridBoundColumn
DataField
=
"DefaultMarket"
HeaderText
=
"DefaultMarket"
/>
<
telerik:GridBoundColumn
DataField
=
"ForceClosingPrice"
HeaderText
=
"ForceClosingPrice"
/>
<
telerik:GridBoundColumn
DataField
=
"MarketId"
HeaderText
=
"MarketId"
/>
<
telerik:GridBoundColumn
DataField
=
"Active"
HeaderText
=
"Active"
/>
<
telerik:GridBoundColumn
DataField
=
"PriceStep"
HeaderText
=
"PriceStep"
/>
</
Columns
>
</
MasterTableView
>
</
telerik:RadGrid
>
<
asp:ObjectDataSource
ID
=
"objectDataSource"
runat
=
"server"
SelectMethod
=
"Select"
TypeName
=
"XXXSource"
DataObjectTypeName
=
"Admin.Entities.XXX"
EnablePaging
=
"true"
StartRowIndexParameterName
=
"startRowIndex"
MaximumRowsParameterName
=
"maximumRows"
SortParameterName
=
"sortColumns"
OnObjectCreating
=
"objectDataSource_ObjectCreating"
/>
</
asp:Content
>
ManageXXXs.aspx.cs:
namespace
Admin.UI.Pages
{
public
partial
class
ManageXXXs : PageBase
{
XXXClient client =
new
XXXClient();
protected
override
void
OnLoad(System.EventArgs e)
{
base
.OnLoad(e);
grid.VirtualItemCount =
this
.client.GetXXXCount(
new
RequestBase<
string
> { OperatorId =
this
.OperatorId }).Result;
}
protected
void
objectDataSource_ObjectCreating(
object
sender, System.Web.UI.WebControls.ObjectDataSourceEventArgs e)
{
e.ObjectInstance =
new
XXXSource(
this
.client,
this
,
this
.OperatorId, grid.PageSize, grid.MasterTableView.FilterExpression);
}
}
}
XXXSource.cs
using
System;
using
System.Collections.Generic;
using
System.ComponentModel;
using
Admin.Entites;
using
Admin.ServiceContracts;
namespace
Admin.UI.UIFramework
{
[DataObject]
public
class
XXXSource
{
XXXAdminService.XXXAdminClient client;
PageBase pageBase;
int
operatorId;
int
pageSize;
string
filter;
public
XXXSource(XXXAdminService.XXXAdminClient client, PageBase pageBase,
int
operatorId,
int
pageSize,
string
filter)
{
this
.client = client;
this
.pageBase = pageBase;
this
.operatorId = operatorId;
this
.pageSize = pageSize;
this
.filter = filter;
}
[DataObjectMethod(DataObjectMethodType.Select)]
public
List<XXX> Select(
int
startRowIndex,
int
maximumRows,
string
sortColumns)
{
try
{
var request =
new
GetXXXsRequest
{
OperatorId = operatorId,
StartRowIndex = startRowIndex,
MaximumRows = pageSize,
SortColumns = sortColumns,
Filter = filter
};
var response = client.GetXXXs(request);
if
(response.ReturnCode == ReturnCode.OK)
{
return
response.XXXs;
}
else
{
pageBase.DisplayMessages(response.ReturnMessages);
}
}
catch
(Exception ex)
{
Logger.Error(ex);
pageBase.DisplayMessage(
"Error!"
);
}
return
null
;
}
public
int
SelectCount()
{
try
{
var request =
new
RequestBase<
string
>
{
OperatorId = operatorId,
Param = filter
};
var response = client.GetXXXCount(request);
if
(response.ReturnCode == ReturnCode.OK)
{
return
response.Result;
}
else
{
pageBase.DisplayMessages(response.ReturnMessages);
}
}
catch
(Exception ex)
{
Logger.Error(ex);
pageBase.DisplayMessage(
"Error!"
);
}
return
-1;
}
}
}
Server side:
using
System;
using
System.Linq;
using
System.Linq.Dynamic;
using
Admin.DAL;
using
Admin.Entites;
using
Admin.ServiceContracts;
using
System.Collections.Generic;
namespace
Admin.Services
{
public
class
XXXService : IXXX
{
private
void
InitLogger()
{
Logger.InitLogger(
"AdminServicesLogger"
);
}
public
XXXAdminService() :
this
(
true
) { }
public
XXXAdminService(
bool
initLogger)
{
if
(initLogger)
{
InitLogger();
}
}
public
GetXXXsResponse GetXXXs(GetXXXsRequest request)
{
Logger.Info(
"GetXXXs started"
);
var response =
new
GetXXXsResponse();
try
{
using
(FrontContext ctx =
new
FrontContext())
{
//IQueryable<XXX> retList;
List<XXX> retList;
if
(
string
.IsNullOrWhiteSpace(request.Filter))
retList = ctx.XXXs.ToList();
else
retList = ctx.XXXs.Where(request.Filter).ToList();
//IOrderedQueryable<XXX> retList2;
IOrderedEnumerable<XXX> retList2;
if
(!
string
.IsNullOrWhiteSpace(request.SortColumns))
{
var parts = request.SortColumns.Split(
' '
);
if
(parts[1] ==
"ASC"
)
{
if
(parts[0] ==
"Active"
)
retList2 = retList.OrderBy(pi => pi.Active);
else
if
(parts[0] ==
"PriceStep"
)
retList2 = retList.OrderBy(pi => pi.PriceStep);
...........
}
else
if
(parts[1] ==
"DESC"
)
{
if
(parts[0] ==
"Active"
)
retList2 = retList.OrderByDescending(pi => pi.Active);
else
if
(parts[0] ==
"PriceStep"
)
retList2 = retList.OrderByDescending(pi => pi.PriceStep);
............
}
}
else
retList2 = retList.OrderBy(pi => pi.PiacInstrumentumID);
response.XXXs = retList2.Skip(request.StartRowIndex).Take(request.MaximumRows).ToList();
response.ReturnCode = ReturnCode.OK;
}
}
catch
(Exception ex)
{
Logger.Error(ex);
response.ReturnCode = ReturnCode.Failed;
response.AddReturnMessage(
new
TechnicalError(ex));
}
Logger.Info(
"GetXXXs finished"
);
return
response;
}
public
ResponseBase<
int
> GetXXXCount(RequestBase<
string
> request)
{
Logger.Info(
"GetXXXCount started"
);
var response =
new
ResponseBase<
int
>();
try
{
using
(XXXContext ctx =
new
XXXContext())
{
if
(
string
.IsNullOrWhiteSpace(request.Param))
response.Result = ctx.XXXs.Count();
else
response.Result = ctx.XXXs.Where(request.Param).Count();
response.ReturnCode = ReturnCode.OK;
}
}
catch
(Exception ex)
{
Logger.Error(ex);
response.ReturnCode = ReturnCode.Failed;
response.AddReturnMessage(
new
TechnicalError(ex));
}
Logger.Info(
"GetXXXCount finished"
);
return
response;
}
public
AddModifyXXXResponse AddModifyXXX(AddModifyXXXRequest request)
{
....
}
public
DeleteXXXResponse DeleteXXX(DeleteXXXRequest request)
{
....
}
}
}
using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Text;
using
System.Data.Entity;
using
Admin.Entites;
namespace
Admin.DAL
{
public
class
XXXContext : DbContext
{
public
XXXContext()
:
base
(
"ConnectionString"
)
{
}
public
DbSet<XXX> XXXs {
get
;
set
; }
protected
override
void
OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<XXX>().ToTable(
"XXX"
);
modelBuilder.Entity<XXX>().HasKey(x =>
new
{ x.XXXID });
}
}
}
namespace
Admin.Entites
{
public
class
XXX
{
public
int
XXXID {
get
;
set
; }
public
string
Isin {
get
;
set
; }
public
int
? InstrumentCode {
get
;
set
; }
public
string
RIC {
get
;
set
; }
public
string
Ticker {
get
;
set
; }
public
int
? DefaultMarket {
get
;
set
; }
public
short
ForceClosingPrice {
get
;
set
; }
public
int
? MarketId {
get
;
set
; }
public
int
? Active {
get
;
set
; }
public
decimal
? PriceStep {
get
;
set
; }
}
}