Hi!
I have my solution setup as follows (image also attached):
Data <--> Business <--> WCF Service <--> Intranet <--> WCF Client <--> Website
I have attempted to implement paging but it is not the most optimal way. Here is the code that starts with the website and ends in the Data Layer:
View:
@(Html.Kendo().Grid(Model.SearchResults) .Name("GridSearchResults") .HtmlAttributes(new { style = "height: 400px" }) .EnableCustomBinding(true) .Columns(columns => { columns.Bound(p => p.ParkingCardId).Title("Id").Width(80).ClientTemplate("<a href='" + Url.Action("ParkingCardDetail", "CardRequest", new { parkingCardId = "#= ParkingCardId #'" }) + ">#= ParkingCardId #</a>"); columns.Bound(p => p.Name).Title("Name"); columns.Bound(p => p.Company).Title("Company"); columns.Bound(p => p.CardType).Title("Card Type").Width(100); columns.Bound(p => p.DrivingLicenseNo).Title("License #"); columns.Bound(p => p.SeasonPassNo).Title("Season Pass #"); columns.Bound(p => p.Status).Title("Status"); columns.Bound(p => p.ReceiptNo).Title("Receipt #").Width(140).ClientTemplate("<a href='" + Url.Action("Report1", "Ajax", new { billNo = "#= ReceiptNo #'" }) + ">#= ReceiptNo #</a>"); }) .Pageable() .Scrollable() .DataSource(dataSource => dataSource .Ajax() .PageSize(30) .Read(read => read .Action("IndexResults", "CardRequest") .Data("searchExtraParameters") ) ))
Controller:
public async Task<ActionResult> Index(){ ViewBag.Module = (int)PageModule.SearchCardRequests; await GetMasterLookForRequest(lookupManager, billingManager); return View(new ParkingCardSearchViewModel());} public async Task<ActionResult> IndexResults([DataSourceRequest(Prefix = "Grid")] DataSourceRequest request, int? companyId, int? categoryId, int? serviceId, int? paymentModeId, int? statusId, int? extraSearch, string extraSearchKeywords){ ViewBag.Module = (int)PageModule.SearchCardRequests; #region Apply paging if (request.PageSize == 0) { request.PageSize = 30; } var pager = new PagingHelper { Skip = 0, Take = request.PageSize }; if (request.Page > 0) { pager.Skip = (request.Page - 1) * request.PageSize; } #endregion // Get results var results = await searchManager.GetCardRequestForSearch(pager, companyId, categoryId, serviceId, paymentModeId, statusId, extraSearch, extraSearchKeywords); var result = new DataSourceResult() { Data = results.Item2, // Process data (paging and sorting applied) Total = results.Item1 // Total number of records }; //Return the result as JSON. return Json(result);}
Client:
public async Task<Tuple<int, IList<SearchCardRequest>>> GetCardRequestForSearch(PagingHelper pager, int? companyId, int? categoryId, int? serviceId, int? paymentMode, int? statusId, int? extraSearchId, string searchKeywords){ try { var result = await proxy.CallAsync(m => m.GetCardRequestForSearch(pager, companyId, categoryId, serviceId, paymentMode, statusId, extraSearchId, searchKeywords)); return result; } catch (FaultException<CarParkFault> fault) { throw new ClientException("Exception from server for GetCardRequestForSearch: " + fault.Message); } catch (Exception exp) { throw new ClientException("General exception from server for GetCardRequestForSearch: " + exp.Message); }}
Service:
[OperationContract][FaultContract(typeof(CarParkFault))]Tuple<int, IList<BDO.SearchCardRequest>> GetCardRequestForSearch(BDO.PagingHelper pager, int? companyId, int? categoryId, int? serviceId, int? paymentMode, int? statusId, int? extraSearchId, string searchKeywords); public Tuple<int, IList<BDO.SearchCardRequest>> GetCardRequestForSearch(BDO.PagingHelper pager, int? companyId, int? categoryId, int? serviceId, int? paymentMode, int? statusId, int? extraSearchId, string searchKeywords) { Tuple<int, IList<BDO.SearchCardRequest>> objMaster; try { using (var context = new BLL.SearchLogic()) { objMaster = context.GetCardRequestForSearch(pager, companyId, categoryId, serviceId, paymentMode, statusId, extraSearchId, searchKeywords); } } catch (Exception ex) { throw new FaultException<CarParkFault>( new CarParkFault { Message = ex.Message, Result = false, Description = ex.ToString() }, new FaultReason("Service failed to serve GetCardRequestForSearch()") ); } return objMaster;}
Business:
public Tuple<int, IList<BDO.SearchCardRequest>> GetCardRequestForSearch(BDO.PagingHelper pager, int? companyId, int? categoryId, int? serviceId, int? paymentMode, int? statusId, int? extraSearchId, string searchKeywords){ Tuple<int, IList<BDO.SearchCardRequest>> responseObject; try { responseObject = searchRepo.GetCardRequestForSearch(pager, companyId, categoryId, serviceId, paymentMode, statusId, extraSearchId, searchKeywords); } catch (Exception exp) { throw new BusinessLayerException("GetCardRequestForSearch Failed: " + exp.Message, exp); } return responseObject;}
Data:
public Tuple<int, IList<BDO.SearchCardRequest>> GetCardRequestForSearch(BDO.PagingHelper pager, int? companyId, int? categoryId, int? serviceId, int? paymentMode, int? statusId, int? extraSearchId, string searchKeywords){ #region Setup IList<BDO.SearchCardRequest> result; var sqlConnection = new SqlConnection { ConnectionString = WebConfigurationManager.ConnectionStrings["BlaBla"].ConnectionString }; var sqlDataAdapter = new SqlDataAdapter { SelectCommand = new SqlCommand { CommandType = CommandType.Text, Connection = sqlConnection } }; var dataSet = new DataSet(); #endregion try { var sqlSearch = @" SELECT ParkingCards.ParkingCardId , ParkingCards.Name , ParkingCards.CompanyId , ParkingCards.SeasonPassNo , Companies.NameE AS Company , ParkingCards.Nationality , ParkingCards.Status , ParkingCards.CardType , ParkingCards.DrivingLicenseNo , ParkingCards.Amount , ParkingCards.PaymentMode , ParkingCards.ReceiptNo , ParkingCards.VehicleNo , ParkingCards.IsBlock "; if (categoryId != null) { sqlSearch = sqlSearch + " FROM ParkingCards LEFT OUTER JOIN Companies ON ParkingCards.CompanyId = Companies.CompanyId "; } else { sqlSearch = sqlSearch + " FROM Category INNER JOIN Companies ON Category.CategoryId = Companies.CategoryId RIGHT OUTER JOIN ParkingCards ON Companies.CompanyId = ParkingCards.CompanyId "; } sqlSearch = sqlSearch + " where ParkingCardId > 0 and status in (0,2,4,5,6,7,15)"; #region Dynamic "Where"s if (categoryId != null) { sqlSearch = sqlSearch + " and Companies.CategoryId = " + categoryId.Value; } if (companyId != null) { sqlSearch = sqlSearch + " and ParkingCards.CompanyId = " + companyId.Value; } if (serviceId != null) { sqlSearch = sqlSearch + " and ParkingCards.ServiceCode = " + serviceId.Value; } if (paymentMode != null) { sqlSearch = sqlSearch + " and ParkingCards.PaymentMode = " + paymentMode.Value; } if (statusId != null) { sqlSearch = sqlSearch + " and ParkingCards.Status = " + statusId.Value; } if (extraSearchId != null && !string.IsNullOrWhiteSpace(searchKeywords)) { if (extraSearchId.Value == 1) { // ParkingCardId sqlSearch = sqlSearch + " AND ParkingCards.ParkingCardId = '" + searchKeywords + "'"; } else if (extraSearchId.Value == 2) { // AirportPassNumber sqlSearch = sqlSearch + " and ParkingCards.AirportPassNumber = '" + searchKeywords + "'"; } else if (extraSearchId.Value == 3) { // StaffNo sqlSearch = sqlSearch + " and ParkingCards.StaffNo = '" + searchKeywords + "'"; } else if (extraSearchId.Value == 4) { // SeasonPassNo sqlSearch = sqlSearch + " and ParkingCards.SeasonPassNo like '%" + searchKeywords + "%'"; } else if (extraSearchId.Value == 5) { // Name sqlSearch = sqlSearch + " and ParkingCards.Name like '%" + searchKeywords + "%'"; } } #endregion sqlConnection.Open(); sqlDataAdapter.SelectCommand.CommandText = sqlSearch + " Order by ParkingCardID desc"; sqlDataAdapter.Fill(dataSet); result = new List<BDO.SearchCardRequest>(); if (dataSet.Tables.Count == 1) { foreach (DataRow dataRow in dataSet.Tables[0].Rows) { var newRecord = new BDO.SearchCardRequest(); try { newRecord.ParkingCardId = dataRow.Field<int>("ParkingCardId"); newRecord.Name = dataRow.Field<string>("Name"); newRecord.CompanyId = dataRow.Field<int?>("CompanyId"); newRecord.SeasonPassNo = dataRow.Field<string>("SeasonPassNo"); newRecord.Company = dataRow.Field<string>("Company"); newRecord.Nationality = dataRow.Field<string>("Nationality"); newRecord.StatusId = dataRow.Field<byte?>("Status"); newRecord.Status = CommonFunctions.GetStatusAgainstStatusId(newRecord.StatusId); newRecord.CardTypeId = dataRow.Field<int>("CardType"); newRecord.CardType = CommonFunctions.GetCardTypeAgainstCardTypeId(newRecord.CardTypeId); newRecord.DrivingLicenseNo = dataRow.Field<string>("DrivingLicenseNo"); newRecord.Amount = dataRow.Field<decimal?>("Amount"); newRecord.PaymentModeId = dataRow.Field<int>("PaymentMode"); newRecord.PaymentMode = CommonFunctions.GetPaymentModeAgainstPaymentModeId(newRecord.PaymentModeId); newRecord.ReceiptNo = dataRow.Field<string>("ReceiptNo"); newRecord.VehicleNo = dataRow.Field<string>("VehicleNo"); newRecord.IsBlock = dataRow.Field<bool?>("IsBlock"); newRecord.IsBlockS = CommonFunctions.GetYesNoForBool(newRecord.IsBlock); } catch (Exception e) { throw new RecordReadingException("Error adding new SearchCardRequest: " + e.Message + "\nFaulting Row: " + dataRow.ItemArray.DebugArray(), e); } result.Add(newRecord); } } } finally { dataSet.Dispose(); sqlDataAdapter.Dispose(); sqlConnection.Dispose(); } return new Tuple<int, IList<BDO.SearchCardRequest>>(result.Count, result.Skip(pager.Skip).Take(pager.Take).ToList());}
Result:
It seems that the data on the grid is not changing when changing page and everytime, I'm reading the whole data just to get a new page. Is there a better way to do this?
