This is a migrated thread and some comments may be shown as answers.

ObjectDataSource custom paging, sorting, filtering problems, howto?

1 Answer 340 Views
Grid
This is a migrated thread and some comments may be shown as answers.
ligu
Top achievements
Rank 1
ligu asked on 19 Apr 2012, 06:24 PM
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:
<%@ 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; }
    }
}

1 Answer, 1 is accepted

Sort by
0
Marin
Telerik team
answered on 24 Apr 2012, 09:27 AM
Hi,

 Normally the grid supports automatic paging, filtering and sorting when bound do ObjectDataSource. You do not need any additional custom paging configuration in order to enable the paging. If you do need to stick to the custom paging functionality then you should perform manually the entire paging and decide how many records to pass in each case. More information on the custom paging feature can be found here:
http://www.telerik.com/help/aspnet-ajax/grid-custom-paging.html 
I do not see any reason why the filtering will throw exception in this case. You can check the FilterExpression property of the MasterTableView and whether it passes the correct filter expression to the datasource.
Normally the grid respects the width setting that is passed to it. It can be some other problem with page layout or other parent elements on the page that cause the grid to span wider than needed. Or the columns can be stretched too wide if they had lots of data inside.

Greetings,
Marin
the Telerik team
If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the RadControls for ASP.NET AJAX, subscribe to their blog feed now.
Tags
Grid
Asked by
ligu
Top achievements
Rank 1
Answers by
Marin
Telerik team
Share this question
or