I have a search controller that has a large number of parameters (the search criteria). I want to page through the results using MVCContrib - IPagination. This is all good the problem is how to generate the Link on the Html.Pager. I've tried this in the view
#Html.Pager(Model.Results).Link(p =>
Url.Action("Search", new {
Model.Criteria } ))
but is doesn't work. Do I need to register a route so that the Url.Action understands how to form the link?
Controller code below....
public ViewResult Search(JobSearch search, int? page, IAuthenticatedUser authenticatedUser)
{
// perform search
var query = _jobRepository.CreateQuery<IPagedJobSearch>();
query.SiteId = authenticatedUser.SiteId;
query.JobId = search.Criteria.JobId;
query.Lot = search.Criteria.LotNumber;
query.Street = search.Criteria.StreetInfo.Name;
query.StreetNumber = search.Criteria.StreetInfo.Number;
query.Suburb = search.Criteria.Suburb;
query.Council = search.Criteria.Council;
query.ClientRef = search.Criteria.ClientOrderNumber;
query.ItemsPerPage = 15;
query.PageNumber = page ?? 1;
var pagedResult = query.Execute(); ......
You don't show all of your markup but you'll need to specify each of your parameters like this:
<%= Html.Pager(Model.AssetsPagedList)
.First("First")
.Last("Last")
.Next("Next")
.Previous("Previous")
.Link(currentPage => Url.Action("Browse", new {
page = currentPage,
searchTerm = Model.SearchModel.SearchTerm,
excludedWords = Model.SearchModel.ExcludedWords,
minPrice = Model.SearchModel.MinPrice,
maxPrice = Model.SearchModel.MaxPrice,
locationId = Model.SearchModel.LocationId,
catalogId = Model.SearchModel.CatalogId
}))
%>
Once you have the correct parameters, you'll need to create a controller that accepts each of them:
public ActionResult Browse(int? id, string searchTerm, int? locationId,
GridSortOptions gridSortOptions, int? page, string excludedWords,
decimal? minPrice, decimal? maxPrice, int? catalogId)
{
}
Related
I have two action methods in my Controller class:
DetailsAll: to get some data and display in the view
SaveAsPDF: Called on windows.load of DetailsAll.cshtml which should save DetailsAll view as pdf
My issue is in SaveAsPDF Action method. Here I am trying to use Rotativa ActionAsPdf and subsequently BuildFile methods to generate and save the PDF. However, when executing the line "BuildFile", it is not hitting the breakpoint in my DetailsAll Action method, subsequently causing the PDF to be generated blank.
Could you please help where I am going wrong?
[HttpGet]
public ActionResult DetailsAll()
{
var selectionBuilder = builderFactory.GetGeocodeReportSelectionViewModelBuilder();
var companyList = selectionBuilder.Build();
List<GeocodeReportViewModel> viewModel = new List<GeocodeReportViewModel>();
foreach(SelectListItem record in companyList.Companies)
{
var builder = builderFactory.GetGeocodeReportViewModelBuilder(int.Parse(record.Value));
viewModel.Add(builder.Build());
}
var model = new AllGeocodeReportViewModel
{
GeocodeReports = viewModel
};
return View(model);
}
[HttpGet]
public string SaveAsPDF()
{
var report = new ActionAsPdf("DetailsAll")
{
FileName = "OEM_GeocodeReport_" + System.DateTime.Now.ToString("MMYY") + ".pdf",
PageSize = Size.A4,
PageOrientation = Orientation.Landscape,
PageMargins = { Left = 1, Right = 1 }
};
byte[] pdf = report.BuildFile(ControllerContext);
System.IO.File.WriteAllBytes("C:\\" + report.FileName, pdf);
return "true";
}
Finally found the issue after extensive search. I need to send Authentication cookies along with the BuildFile request for this to work. Added the below code and it generates PDF correctly now:
public void SaveAsPDF()
{
var cookies = Request.Cookies.AllKeys.ToDictionary(k => k, k => Request.Cookies[k].Value);
var report = new ActionAsPdf("DetailsAll")
{
FileName = "OEM_GeocodeReport_" + System.DateTime.Now.ToString("MMyy") + ".pdf",
PageSize = Size.A4,
PageOrientation = Orientation.Portrait,
PageMargins = { Left = 3, Right = 3 },
FormsAuthenticationCookieName = System.Web.Security.FormsAuthentication.FormsCookieName,
Cookies = cookies
};
byte[] pdf = report.BuildFile(ControllerContext);
System.IO.File.WriteAllBytes("C:\\" + report.FileName, pdf);
}
DataSourceResult does not contain a definition for ToDataSourceResult and the best extension method overload QueryableExtensions.ToDataSourceResult(DataTable, DataSourceRequest) requires a receiver of type DataTable
var results = db.Accounts.ToDataSourceResult(
request,
o => new {
ID = o.ID,
AccCode = o.AccCode,
AccName = o.AccName,
Phone = o.Phone,
Email = o.Email,
DateBirth = o.DateBirth,
Address = o.Address,
Type = o.Type
}
);
return Json(results.ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
Your results var is already a DataSourceResult so you don't have to do it again in the Json().
How to get viewbag data, i created one controller in that data is fetch from data base and try to show the data in view but it is not displaying data.
public ActionResult Show()
{
List<Models.Employees> lst = new List<Models.Employees>();
Models.Employees obj = new Models.Employees();
DataSet ds =new Models.BL.InsertBL().GetShow(obj);
lst = (from DataRow drw in ds.Tables[0].Rows
select new Models.Employees
{
Enames = drw["Ename"].ToString(),
DepartId =Convert .ToInt32(drw["Departmentid"]),
EmailIds = drw["Emailid"].ToString(),
Adress = drw["Address"].ToString()
}).ToList();
ViewBag.Sasi = lst;
return View();
}
#{
ViewBag.Title = "Show";
Layout = "~/Views/Shared/VideoLayout.cshtml";
var vv = ViewBag.Sasi;
}
In this scenario I would recommend you strongly typed views:
return View(lst);
and in View:
#model List<Models.Employees>
Your question, try this:
(List<Models.Employees>)ViewBag.Sasi
I have several jqgrids running and all are functioning fine. However, when I do a search, I am only displaying ten search results per page. Whenever there are more than ten results, clicking on page two has no effect on the grid. Here is one of my controller actions, pay particular attention to the if satatement where search is true....
EDIT
I think I may have found a clue as to what may be causing my issue. You see I have several subgrids under the main grid. In terms of my java code I have object-A which has a list of object-B
, thus A has a subgrid of B. The way i am building up the json string to feed to the grid is by iterating over the list of B contained in A. I did not write a query of some kind to say order by, and limit the results etc.
So i guess the real question should be how to build a finder on a collection so that the contents can be arranged and ordered as i wish?
Here is the action I am calling for one of my entities described as B above. Pay particular attention to where i said person.getContacts()
#RequestMapping(value = "contactjsondata/{pId}", method = RequestMethod.GET)
public #ResponseBody String contactjsondata(#PathVariable("pId") Long personId, Model uiModel, HttpServletRequest httpServletRequest) {
Person person = Person.findPerson(personId);
String column = "id";
if(httpServletRequest.getParameter("sidx") != null){
column = httpServletRequest.getParameter("sidx");
}
String orderType = "DESC";
if(httpServletRequest.getParameter("sord") != null){
orderType = httpServletRequest.getParameter("sord").toUpperCase();
}
int page = 1;
if(Integer.parseInt(httpServletRequest.getParameter("page")) >= 1){
page = Integer.parseInt(httpServletRequest.getParameter("page"));
}
int limitAmount = 10;
int limitStart = limitAmount*page - limitAmount;
List<Contact> contacts = new ArrayList<Contact>(person.getContacts());
double tally = Math.ceil(contacts.size()/10.0d);
int totalPages = (int)tally;
int records = contacts.size();
StringBuilder sb = new StringBuilder();
sb.append("{\"page\":\"").append(page).append("\", \"records\":\"").append(records).append("\", \"total\":\"").append(totalPages).append("\", \"rows\":[");
boolean first = true;
for (Contact c: contacts) {
sb.append(first ? "" : ",");
if (first) {
first = false;
}
sb.append(String.format("{\"id\":\"%s\", \"cell\":[\"%s\", \"%s\", \"%s\"]}",c.getId(), c.getId(), c.getContactType().getName() ,c.getContactValue()));
}
sb.append("]}");
return sb.toString();
}
To fix the issue with pagination you need to replace the following block of code
for (Contact c: contacts) {
sb.append(first ? "" : ",");
if (first) {
first = false;
}
sb.append(String.format("{\"id\":\"%s\", \"cell\":[\"%s\", \"%s\", \"%s\"]}",c.getId(), c.getId(), c.getContactType().getName() ,c.getContactValue()));
}
with:
for (int i=limitStart; i<Math.min(records, limitStart+limitAmount); i++){
Contact c = contacts[i];
sb.append(first ? "" : ",");
if (first) {
first = false;
}
sb.append(String.format("{\"id\":\"%s\", \"cell\":[\"%s\", \"%s\", \"%s\"]}",c.getId(), c.getId(), c.getContactType().getName() ,c.getContactValue()));
}
Another option is using loadonce:true to let the jqGrid handle pagination and sorting. In this case you don't need to make changes described above
I need to return a single instance of my viewmodel class from my repository in order to feed this into a strongly-typed view
In my repository, this works fine for a collection of viewmodel instances:
IEnumerable<PAWeb.Domain.Entities.Section> ISectionsRepository.GetSectionsByArea(int AreaId)
{
var _sections = from s in DataContext.Sections where s.AreaId == AreaId orderby s.Ordinal ascending select s;
return _sections.Select(x => new PAWeb.Domain.Entities.Section()
{
SectionId = x.SectionId,
Title = x.Title,
UrlTitle = x.UrlTitle,
NavTitle = x.NavTitle,
AreaId = x.AreaId,
Ordinal = x.Ordinal
}
);
}
But when I attempt to obtain a single entity, like this:
public PAWeb.Domain.Entities.Section GetSection(int SectionId)
{
var _section = from s in DataContext.Sections where s.SectionId == SectionId select s;
return _section.Select(x => new PAWeb.Domain.Entities.Section()
{
SectionId = x.SectionId,
Title = x.Title,
UrlTitle = x.UrlTitle,
NavTitle = x.NavTitle,
AreaId = x.AreaId,
Ordinal = x.Ordinal
}
);
}
I get
Error 1 Cannot implicitly convert type
'System.Linq.IQueryable<PAWeb.Domain.Entities.Section>' to
'PAWeb.Domain.Entities.Section'. An explicit conversion exists
(are you missing a cast?)"
This has got to be simple, but I'm new to c#, and I can't figure out the casting. I tried (PAWeb.Domain.Entities.Section) in various places, but no success. Can anyone help??
Your query is returning an IQueryable, which could have several items. For example, think of the difference between an Array or List of objects and a single object. It doesn't know how to convert the List to a single object, which one should it take? The first? The last?
You need to tell it specifically to only take one item.
e.g.
public PAWeb.Domain.Entities.Section GetSection(int SectionId)
{
var _section = from s in DataContext.Sections where s.SectionId == SectionId select s;
return _section.Select(x => new PAWeb.Domain.Entities.Section()
{
SectionId = x.SectionId,
Title = x.Title,
UrlTitle = x.UrlTitle,
NavTitle = x.NavTitle,
AreaId = x.AreaId,
Ordinal = x.Ordinal
}
).FirstOrDefault();
}
This will either return the first item, or null if there are no items that match your query. In your case that won't happen unless the table is empty since you don't have a where clause.