Does not contain a definition for 'ToPagedList' - c#

I am trying to implement Pagination to my code using PagedList and PagedList.Mvc
The problem I am facing is that I am getting an error
'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' occurred in
System.Core.dll but was not handled in user code
Additional information: 'System.Collections.Generic.List'
does not contain a definition for 'ToPagedList'
Following is my code for PJController.cs:
public ActionResult Index(SearchPostedJob objSearchPostedJob, int? page)
{
Result res = null;
try
{
objSearchPostedJob.page = (objSearchPostedJob.page == null ? 1 : objSearchPostedJob.page);
ViewBag.SearchPostedJob = objSearchPostedJob;
res = objPostedJobDAL.GetPostedJobs(ApplicationSession.CurrentUser.RecruiterId);
if (res.Status)
{
page = 1;
ViewBag.Message = "";
}
else
{
ViewBag.Message = Common.GetMessage(res.MessageId, "[Master]", "Keyword");
}
}
catch (Exception ex)
{
Common.WriteLog(ex);
throw ex;
}
var result = res.Results;
int pageSize = 3;
int pageNumber = (page ?? 1);
return View(result.ToPagedList(pageNumber, pageSize));
}
Below is the code for Index.cshtml:
#model PagedList.IPagedList<NOS.SC.PJ>
#using PagedList.Mvc;
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div class="postjob-form">
#using (Html.BeginForm("Index", "PostedJob", FormMethod.Get))
{
<div class="j_search" style="margin-left:3%;">
<input class="form-control" name="SearchKeyword" id="SearchKeyword" placeholder="Search Keyword" />
</div>
<div class="j_search">
<input id="pinput1" name="JobLocation" class="form-control" type="text" value="#ViewBag.SearchPostedJob.JobLocation" placeholder="Enter a location">
<input id="Latitude" name="Latitude" type="hidden" value="#ViewBag.SearchPostedJob.Latitude">
<input id="Longitude" name="Longitude" type="hidden" value="#ViewBag.SearchPostedJob.Longitude">
</div>
<div class="j_search">
<select class="form-control" name="Experience" id="Experience">
<option value="" selected>Select Experience</option>
#for (int i = 1; i <= 10; i++)
{
<option value="#i" #(ViewBag.SearchPostedJob.Experience == i ? "selected" : "")>#i</option>
}
</select>
</div>
<div class="j_search">
<select class="form-control" name="Salary" id="Salary">
<option value="" selected>Select Salary</option>
#for (int i = 1; i <= 10; i++)
{
<option value="#i" #(ViewBag.SearchPostedJob.Salary == i ? "selected" : "")>#i</option>
}
</select>
</div>
<div class="add-btn"><a class="btn btn-primary" href="~/PostedJob/Save?returnUrl=/PostedJob/Index">Add New Opening</a></div>
}
</div>
<div>
<table class="table" id="myTable">
<tr>
<th>
#Html.DisplayNameFor(model => model[0].JobTitle)
</th>
<th>
#Html.DisplayNameFor(model => model[0].JobLocation)
</th>
<th>
#Html.DisplayNameFor(model => model[0].NumberOfPositions)
</th>
<th>
#Html.DisplayNameFor(model => model[0].ValidFrom)
</th>
<th>
#Html.DisplayNameFor(model => model[0].ValidTo)<br />
</th>
<th>
#Html.DisplayNameFor(model => model[0].JobReference)
</th>
<th>
#Html.DisplayNameFor(model => model[0].Status)
</th>
<th>
Application
</th>
<th>
CloneJob
</th>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.JobTitle)
</td>
<td>
#Html.DisplayFor(modelItem => item.JobLocation)
</td>
<td>
#Html.DisplayFor(modelItem => item.NumberOfPositions)
</td>
<td>
#Html.DisplayFor(modelItem => item.ValidFrom)
</td>
<td>
#Html.DisplayFor(modelItem => item.ValidTo)<br />
#* #Html.ActionLink("Delete Resume", "DeleteResume", new { ResumeId = Model.ResumeId, returnUrl = "/Nurse/ProfileView" }, new { #class = "btnViewJobDetails" })*#
#if (!item.IsExtendJob)
{
#Html.ActionLink("ExtendJob", "ExtendJob", new { PostedJobId = item.PostedJobId, IsExtendJob = item.IsExtendJob, returnUrl = "/PostedJob/Index" }, new { #class = "btnViewJobDetails" })
}
else
{
<span class="pull-right" style="font-weight:bold; color:red;">JobExtended</span>
}
</td>
<td>
#Html.DisplayFor(modelItem => item.JobReference)
</td>
<td>
#Html.DisplayFor(modelItem => item.Status)
</td>
<td>
#Html.ActionLink("Applied(" + item.AppliedCnt + ")", "JobView", new { PostedJobId = item.PostedJobId, returnUrl = "/PostedJob/Index" }, new { #class = "btnViewJobDetails" })
</td>
<td>
#Html.ActionLink("JobClone", "CloneJob", new { PostedJobId = item.PostedJobId, returnUrl = "/PostedJob/Index" }, new { #class = "btnViewJobDetails" })
</td>
</tr>
}
</table>
Page #(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of #Model.PageCount
#Html.PagedListPager(Model, page => Url.Action("Index", new { page }))
</div>
#section Scripts
{
#Scripts.Render("~/bundles/jqueryui")
#Styles.Render("~/Content/themes/base/css")
#Scripts.Render("~/bundles/jqueryval")
<script>
function initMap() {
var input = document.getElementById('pinput1');
var autocomplete = new google.maps.places.Autocomplete(input);
autocomplete.addListener('place_changed', function () {
var place = autocomplete.getPlace();
console.log(JSON.stringify(place));
if (!place.geometry) {
window.alert("Autocomplete's returned place contains no geometry");
return;
}
var latlong = JSON.parse(JSON.stringify(place.geometry.location));
document.getElementById('Latitude').value = latlong.lat;
document.getElementById('Longitude').value = latlong.lng;
});
}
initMap();
</script>
<script>
$(document).ready(function () {
$("#SearchKeyword").on("keyup", function () {
var value = $(this).val().toLowerCase();
$("#myTable tr").filter(function () {
$(this).toggle($(this).text().toLowerCase().indexOf(value) > -1)
});
});
});
</script>
<script>
$(document).ready(function () {
$("#pinput1").on("keyup", function () {
var value = $(this).val().toLowerCase();
$("#myTable tr").filter(function () {
$(this).toggle($(this).text().toLowerCase().indexOf(value) > -1)
});
});
});
</script>
}

Try using this:
public ActionResult Index(FilterPostedJob objFilterPostedJob, int? page)
{
Result res = null;
try
{
objFilterPostedJob.CreatedBy = ApplicationSession.CurrentUser.RecruiterId;
objFilterPostedJob.page = (objFilterPostedJob.page == null ? 1 : objFilterPostedJob.page);
ViewBag.SearchPostedJob = objFilterPostedJob;
res = objPostedJobDAL.GetPostedJobs(objFilterPostedJob);
int pageSize = 10;
int pageNumber = (page ?? 1);
return View(((List<PostedJob>)res.Results).ToPagedList(pageNumber, pageSize));
}
catch (Exception ex)
{
Common.WriteLog(ex);
throw ex;
}
}
Using ToPagedList is an added advantage as all you need to do is to pass the PageNumber and PageSize

Related

How to filter data with method GetAll() and UnitOfWork (Repository Pattern)

I have an initial table in the Index Get method where I query all the columns I want to display, with GetAll() method. Here I also load the drop-down menus where I select the parameters.
/********INDEX GET*********/
[HttpGet]
public IActionResult Index()
{
BudgetVM = new BudgetViewModel()
{
FBudget = new FBudget(),
YearsList = _unitOfWork.Budget.GetYearsListForDropdown(),
CompanyList = _unitOfWork.Budget.GetCompanyListForDropDown(),
CustomerList = _unitOfWork.Budget.GetCustomerListForDropDown(),
ProductGroupList = _unitOfWork.Budget.GetProductGroupListForDropDown(),
LicensingAreaList = _unitOfWork.Budget.GetLicensingAreaListForDropDown(),
PharmaFormList = _unitOfWork.Budget.GetPharmaFormListForDropDown(),
LedgerScenarioList = _unitOfWork.Budget.GetLedgerScenarioListForDropDown(),
CurrencyList = _unitOfWork.Budget.GetCurrencyListForDropdown(),
//Lista di tutti i record
RecordsList = _unitOfWork.Budget.GetAll(includeProperties: "ItemMaster,Customer")
};
return View(BudgetVM);
}
Here is the view that will send the parameters to the Index Post method:
#model SalesBudget.Models.ViewModels.BudgetViewModel
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
<form method="post" asp-controller="Budget" asp-action="Index">
<div class="row">
<div class="col-6">
<br />
<h2 class="text-primary">Filter by</h2>
</div>
</div>
<div class="row">
<div class="col">
<div class="dropdown">
#*Parameter1: what I want to save in the db
Parameter2: actual list of items (dropdown menu)
Parameter3: default that I see in the dropdown
Parameter4: classes that I want to add*#
<!--BLOCCA IL PROGRAMMA IN DELETE-->
#Html.DropDownListFor(m => m.FBudget.CompanyId,
Model.CompanyList,
"--Company--",
new { #class = "form-control" })
</div>
<br />
<div class="dropdown">
#Html.DropDownListFor(m => m.FBudget.CustomerId,
Model.CustomerList,
"--Customer--",
new { #class = "form-control" })
</div>
<br />
</div>
<div class="col">
<div class="dropdown">
#Html.DropDownListFor(m => m.FBudget.Customer.LicensingArea,
Model.LicensingAreaList,
"--Licensing Area--",
new { #class = "form-control" })
</div>
<br />
<div class="dropdown">
#Html.DropDownListFor(m => m.FBudget.Year,
Model.YearsList,
"--Year--",
new { #class = "form-control" })
</div>
<br />
</div>
<div class="col">
<div class="dropdown">
#Html.DropDownListFor(m => m.FBudget.ItemMaster.ProductGroupId,
Model.ProductGroupList,
"--Product Group--",
new { #class = "form-control" })
</div>
<br />
<div class="dropdown">
#Html.DropDownListFor(m => m.FBudget.ItemMaster.PharmaFormId,
Model.PharmaFormList,
"--Pharma Form--",
new { #class = "form-control" })
</div>
<br />
</div>
<div class="col">
<div class="dropdown">
#Html.DropDownListFor(modelItem => modelItem.FBudget.Currency,
Model.CurrencyList,
"--Currency--",
new { #class = "form-control" })
</div>
<br />
<div class="dropdown">
#Html.DropDownListFor(m => m.FBudget.LedgerTypeId,
Model.LedgerScenarioList,
"--Scenario--",
new { #class = "form-control" })
</div>
<br />
</div>
<div class="dropdown">
<button type="submit" class="btn btn-primary form-control">Go</button>
</div>
</div>
</form>
<hr />
<div class="row">
<div class="col-6">
<h2 class="text-primary">Budget List</h2>
</div>
<div class="col-6">
<a asp-action="Upsert" class="btn btn-primary float-end"><i class="fas fa-plus"></i> Create New Budget</a>
</div>
</div>
<br />
<br />
<table class="table">
<thead>
<tr>
<th>
Customer
</th>
<th>
Decription
</th>
<th>
Curr
</th>
<th>
FoC
</th>
<th>
UM
</th>
<th>
Price
</th>
<th>
Quantity
</th>
<th>
Total amount
</th>
<th>
Action
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.RecordsList)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Customer.CustomerName)
</td>
<td>
#Html.DisplayFor(modelItem => item.ItemMaster.ItemDescription)
</td>
<td>
#Html.DisplayFor(modelItem => item.Currency)
</td>
<td>
#Html.DisplayFor(modelItem => item.FreeOfCharge)
</td>
<td>
#Html.DisplayFor(modelItem => item.UnitOfMeasure)
</td>
<td>
#Html.DisplayFor(modelItem => item.UnitPrice)
</td>
<td>
#Html.DisplayFor(modelItem => item.Quantity)
</td>
<td>
#Html.DisplayFor(modelItem => item.TotalAmount)
</td>
<td>
<a asp-action="Upsert" asp-route-id="#item.BudgetId">Edit</a> |
<a asp-action="Delete" asp-route-id="#item.BudgetId">Delete</a>
</td>
</tr>
}
</tbody>
</table>
And here is the Index Post method in the Controller:
/********INDEX POST*********/
[HttpPost]
public IActionResult Index(BudgetViewModel budget)
{
BudgetVM = new BudgetViewModel()
{
FBudget = new FBudget(),
YearsList = _unitOfWork.Budget.GetYearsListForDropdown(),
CompanyList = _unitOfWork.Budget.GetCompanyListForDropDown(),
CustomerList = _unitOfWork.Budget.GetCustomerListForDropDown(),
ProductGroupList = _unitOfWork.Budget.GetProductGroupListForDropDown(),
LicensingAreaList = _unitOfWork.Budget.GetLicensingAreaListForDropDown(),
PharmaFormList = _unitOfWork.Budget.GetPharmaFormListForDropDown(),
LedgerScenarioList = _unitOfWork.Budget.GetLedgerScenarioListForDropDown(),
CurrencyList = _unitOfWork.Budget.GetCurrencyListForDropdown(),
//Here isd where I try to filter data
RecordsList = _unitOfWork.Budget.GetAll(
filter: b => b.Year == budget.FBudget.Year
&& b.CompanyId == budget.FBudget.CompanyId
&& b.CustomerId == budget.FBudget.CustomerId
&& b.Customer.LicensingArea == budget.FBudget.Customer.LicensingArea
&& b.ItemMaster.ProductGroupId == budget.FBudget.ItemMaster.ProductGroupId
&& b.ItemMaster.PharmaFormId == budget.FBudget.ItemMaster.PharmaFormId
&& b.Currency == budget.FBudget.Currency
&& b.LedgerTypeId == budget.FBudget.LedgerTypeId
, includeProperties: "ItemMaster,Customer")
};
//return View(budget);
return View(BudgetVM);
}
Naturally with the logical operator && all fields must be inserted, otherwise the query result will be empty. How can I make these parameters optional, so that if I select only one filter (dropdown) the query is made only on that field, excluding the others?
Here is the GetAll() method:
public IEnumerable<T> GetAll(Expression<Func<T, bool>> filter = null, Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null, string includeProperties = null)
{
IQueryable<T> query = dbSet;
if (filter != null)
{
query = query.Where(filter);
}
//include properties will be comma seperated
if (includeProperties != null)
{
foreach (var includeProperty in includeProperties.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
query = query.Include(includeProperty);
}
}
if (orderBy != null)
{
return orderBy(query).ToList();
}
return query.ToList();
}
Thanks
You can either use something like PredicateBuilder to build the filter, or build it yourself using the System.Linq.Expressions namespace.
For example, assuming any filter properties which are not set will be null:
public static Expression<Func<Budget, bool>> BuildFilter(BudgetViewModel budget)
{
var b = Expression.Parameter(typeof(Budget), "b");
var filterParts = new List<Expression>();
if (budget.FBudget.Year is {} year)
{
var bugetYear = Expression.Property(b, nameof(Budget.Year);
var testYear = Expression.Constant(year);
filterParts.Add(Expression.Equal(budgetYear, testYear));
}
if (budget.FBudget.CompanyId is {} companyId)
{
var budgetCompanyId = Expression.Property(b, nameof(Budget.CompanyId));
var testCompanyId = Expression.Constant(companyId);
filterParts.Add(Expression.Equal(budgetCompanyId, testCompanyId));
}
if (budget.FBudget.CustomerId is {} customerId)
{
var budgetCustomerId = Expression.Property(b, nameof(Budget.CustomerId));
var testCustomerId = Expression.Constant(customerId);
filterParts.Add(Expression.Equal(budgetCustomerId, testCustomerId));
}
if (budget.FBudget.Customer.LicensingArea is {} licensingArea)
{
var budgetCustomer = Expression.Property(b, nameof(Budget.Customer));
var budgetLicensingArea = Expression.Property(budgetCustomer, nameof(Customer.LicensingArea));
var testLicensingArea = Expression.Constant(licensingArea);
filterParts.Add(Expression.Equal(budgetLicensingArea, testLicensingArea));
}
if (budget.FBudget.ItemMaster.ProductGroupId is {} productGroupId)
{
var budgetItemMaster = Expression.Property(b, nameof(Budget.ItemMaster));
var budgetProductGroupId = Expression.Property(budgetItemMaster, nameof(ItemMaster.ProductGroupId));
var testProductGroupId = Expression.Constant(productGroupId);
filterParts.Add(Expression.Equal(budgetProductGroupId, testProductGroupId));
}
if (budget.FBudget.ItemMaster.PharmaFormId is {} pharmaFormId)
{
var budgetItemMaster = Expression.Property(b, nameof(Budget.ItemMaster));
var budgetPharmaFormId = Expression.Property(budgetItemMaster, nameof(ItemMaster.PharmaFormId));
var testPharmaFormId = Expression.Constant(pharmaFormId);
filterParts.Add(Expression.Equal(budgetPharmaFormId, testPharmaFormId));
}
if (budget.FBudget.Currency is {} currency)
{
var budgetCurrency = Expression.Property(b, nameof(Budget.Currency));
var testCurrency = Expression.Constant(currency);
filterParts.Add(Expression.Equal(budgetCurrency, testCurrency));
}
if (budget.FBudget.LedgerTypeId is {} ledgerTypeId)
{
var budgetLedgerTypeId = Expression.Property(b, nameof(Budget.LedgerTypeId));
var testLedgerTypeId = Expression.Constant(ledgerTypeId);
filterParts.Add(Expression.Equal(budgetLedgerTypeId, testLedgerTypeId));
}
if (filterParts.Count == 0) return null;
var body = filterParts.Aggregate(Expression.AndAlso);
return Expression.Lambda<Func<Budget, bool>>(body, b);
}

Why am I am getting null entry for parameter 'CarLotID' of non-nullable type 'System.Int32' for method 'ActionResult DisplaySearchResults()

I am creating an MVC application and I am trying to display data on my table based on the selected values for multiple dropdowns once a button is clicked. I think I am assigning all the values in my code but I am new to coding so I am not sure if I am missing something.
This is my view
#model IgnitionHub2._0.Models.Car
#{
ViewBag.Title = "Car Search Page";
}
<h2>Cars</h2>
<div class="center-div">
<div class="form-inline">
#Html.DropDownListFor(model => model.CarLotID, new SelectList(Model.CarLotList, "CarLotID", "LotName"), "Select Car Lot", new { #class = "form-control" })
#Html.DropDownListFor(model => model.Model.MakeID, new SelectList(Model.MakeList, "MakeID", "Name"), "Select Make", new { #class = "form-control" })
#Html.DropDownListFor(model => model.ModelID, new SelectList(Model.ModelList, "ModelID", "Name"), "Select Model", new { #class = "form-control" })
<button id="search">Search</button>
</div>
</div>
<div id="searchResults">
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
<script src="~/Scripts/jquery-3.4.1.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
<script type="text/javascript">
$(document).ready(
function () {
var makeUrl = '#Url.Action("GetCarDetails")';
var models = $('#ModelID')
$('#Model_MakeID').change(function () {
models.empty();
$.getJSON(makeUrl, { MakeID: $(this).val() },function(data){
if (!data) {
return;
}
models.append($('<option></option>').val('').text('Please select'));
$.each(data, function(index, item) {
models.append($('<option></option>').val(item.Value).text(item.Name));
});
});
})
})
$(document).ready(function () {
var url = '#Url.Action("DisplaySearchResults","Car")';
$('#search').click(function () {
var carLotID = $('#CarLotID').val();
var makeID = $('#Model_MakeID').val();
var modelID = $('#ModelID').val();
alert(modelID);
$('#searchResults').load(url, { CarLotID: carLotID, MakeID: makeID, ModelID: modelID });
})
})
This is my Partial view
#model IEnumerable<IgnitionHub2._0.Models.Car>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.Year)
</th>
<th>
#Html.DisplayNameFor(model => model.Color)
</th>
<th>
#Html.DisplayNameFor(model => model.Mileage)
</th>
<th>
#Html.DisplayNameFor(model => model.BodyType)
</th>
<th>
#Html.DisplayNameFor(model => model.Drive)
</th>
<th>
#Html.DisplayNameFor(model => model.Available)
</th>
<th>
#Html.DisplayNameFor(model => model.Model.Name)
</th>
<th>
#Html.DisplayNameFor(model => model.CarLot.LotName)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Year)
</td>
<td>
#Html.DisplayFor(modelItem => item.Color)
</td>
<td>
#Html.DisplayFor(modelItem => item.Mileage)
</td>
<td>
#Html.DisplayFor(modelItem => item.BodyType)
</td>
<td>
#Html.DisplayFor(modelItem => item.Drive)
</td>
<td>
#Html.DisplayFor(modelItem => item.Available)
</td>
<td>
#Html.DisplayFor(modelItem => item.Model.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.CarLot.LotName)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.CarID }) |
#Html.ActionLink("Details", "Details", new { id=item.CarID }) |
#Html.ActionLink("Delete", "Delete", new { id=item.CarID })
</td>
</tr>
}
</table>
And this is my controller
public ActionResult Index()
{
var cars = db.Cars.Include(c => c.Model).Include(c => c.CarLot);
var makeList = db.Makes.ToList();
var modelList = db.Models.ToList();
var carLotList = db.CarLots.ToList();
var ViewModel = new Car
{
CarList = cars,
MakeList = makeList,
ModelList= modelList,
CarLotList = carLotList
};
return View(ViewModel);
}
public ActionResult DisplaySearchResults(int CarLotID, int MakeID, int ModelID)
{
var model = db.Cars.Where(c => c.Model.MakeID == MakeID && c.ModelID == ModelID &&
c.CarLotID == CarLotID).ToList();// build list based on parameter searchText
return PartialView("_Index", model);
}
public ActionResult _Index()
{
var cars = new List<Car>();
return PartialView(cars);
}
public JsonResult GetCarDetails(int MakeID)
{
db.Configuration.ProxyCreationEnabled = false;
var data = GetModels(MakeID).ToList();
//data = data.Where(x => x.Model.MakeID == MakeID).ToList();
return Json(data, JsonRequestBehavior.AllowGet);
}
Please Help! Thank you in advance!
According to the documentation, https://api.jquery.com/load/, .load() uses POST http request if you're passing an object as parameter, which you are doing right now with;
// {CarLotID:carLotID,MakeID:makeID,ModelID:modelID} is an object
$('#searchResults').load(url, { CarLotID: carLotID, MakeID: makeID, ModelID: modelID });
OPTION 1-- Since you didn't write your action method to be POST, you could just configure your .load() to use GET.
Use the code below for .load();
$('#searchResults').load(url+"?CarLotID="+carLotID+"&MakeID="+makeID+"&ModelID="+modelID);
then change
#Html.DropDownListFor(model => model.ModelID, new SelectList(Model.ModelList, "ModelID", "Name"), "Select Model", new { #id="ModelID", #class = "form-control" })
In your loop to refill the dropdown, use this instead;
$.each(data, function(index, item) {
models.append($('<option value="+item.MakeID+"></option>').text(item.Name));
});
updated script:
$('#Model_MakeID').change(function(){
models.empty();
$.getJSON(makeUrl, { MakeID: $(this).val() }, function(data){
if (!data) {
return;
}
models.append($('<option></option>').val('').text('Please select'));
// update this
$.each(data, function(index, item) {
models.append($('<option value="+item.Value+"></option>').text(item.Name));
});
});
});
OR OPTION 2-- just add [HttpPOST] attribute to your controller action.
[HttpPost] // add this
public ActionResult DisplaySearchResults(int CarLotID, int MakeID, int ModelID)
{
...
}

C# HTML.Actionlink strange behaviour on server

If someone can help, I would be very thankful.
I'm using C# in VS 2017 for an ASP.net Application.
In a razor view, I have this code:
<div class="text-center" >
<ul class="pagination">
#for (var i = 1; i <= ViewBag.SearchMetaData.SearchNumberOfPages; i++)
{
if (ViewBag.SearchMetaData.SearchCurrentPage == #i)
{
<li class="active"> #Html.ActionLink(#i.ToString(), "CI_SequenceBlocks_Pager_Form_Handler", new { id = #i, value = ViewBag.SearchMetaData.SearchString, inInstitutionProgramID = ViewData["SelectedInstitutionProgram"].ToString() },null)</li>
}
else
{
<li> #Html.ActionLink(#i.ToString(), "CI_SequenceBlocks_Pager_Form_Handler", "Home", new { id = #i, value = ViewBag.SearchMetaData.SearchString, inInstitutionProgramID = ViewData["SelectedInstitutionProgram"].ToString() },null)</li>
}
}
</ul>
</div>
}
It works great on my development machine. The actionlinks never fail.
However, when I publish to the server, I can click on the links 3 or 4 times and they work. After the 4th time, it is like the variables are forgotten. When I view the page source the links appear to correct. It seems to me something on the server is being reset. Does anyone have any ideas?
Here is more code:
____________EDIT AFTER THIS LINE__________________
Controller:
public ActionResult CI_SequenceBlocks()
{
string strIP = "";
string strSRCHString = "";
string strSRCHstringQry = "";
int intSRCHRequestedPage = 1;
int intSRCHPageSize = 10;
if (TempData["CI_SequenceBlocks_InstitutionProgram"] == null)
{
strIP = "0";
strSRCHString = "";
}
else
{
strIP = TempData["CI_SequenceBlocks_InstitutionProgram"].ToString();
strSRCHString = TempData["CI_SequenceBlocks_SRCHString"]?.ToString() ?? "";
};
ViewData["listInstitutionPrograms"] = new SelectList(MSSQL_CI_Repository.ListInstitutionProgramsForComboBoxes(), "Value", "Text");
ViewData["SelectedInstitutionProgram"] = strIP;
ViewData["inSRCHString"] = strSRCHString;
ViewBag.SRCHString = strSRCHString;
//ViewBag.InstitutionalProgram = strIP;
if (strSRCHString == "") { ViewBag.SRCHDescriptor = "NO_SEARCH_TERM"; } else { ViewBag.SRCHDescriptor = strSRCHString?.ToString() ?? "NO_SEARCH_TERM"; }
if (strSRCHString.Trim() == "")
{
strSRCHstringQry = "rttyghujmgdddh";
}
else
{
strSRCHstringQry = strSRCHString;
}
if(TempData["CI_SequenceBlocks_RequestedPage"] != null)
{
intSRCHRequestedPage = Convert.ToInt32(TempData["CI_SequenceBlocks_RequestedPage"]);
}
vm_CI_SequenceBlocksWithSearchMetaData obj = MSSQL_CI_Repository.ListCI_SequenceBlocksByInstitutionalProgramForFullTextSearch(Convert.ToInt32(strIP), strSRCHstringQry,intSRCHPageSize,intSRCHRequestedPage);
ViewBag.SearchMetaData = obj.SearchMetaData;
var model = obj.lstSequenceBlocks;
return View(model);
}
[HttpPost]
public ActionResult CI_SequenceBlocks_FullTextSearch(FormCollection form)
{
TempData["CI_SequenceBlocks_InstitutionProgram"] = form["HidInstitutionProgram"].ToString();
TempData["CI_SequenceBlocks_SRCHString"] = form["SRCHString"].ToString();
TempData["CI_SequenceBlocks_RequestedPage"] = 1;
return RedirectToActionPermanent("CI_SequenceBlocks");
}
public ActionResult CI_SequenceBlocks_Edit_Form_Handler(int id, string value, int inInstitutionProgramID)
{
TempData["CI_SequenceBlocks_InstitutionProgramID"] = inInstitutionProgramID;
TempData["CI_SequenceBlocks_SequenceBlockID"] = id;
if (value == "Edit_SequenceBlock_ID")
{
return RedirectToAction("CI_SequenceBlock_Edit");
}
else if (value == "Maintain_SequenceBlock_ID")
{
return RedirectToAction("CI_SequenceBlock_Maintain");
}
else
{
TempData["CI_SequenceBlocks_InstitutionProgram"] = inInstitutionProgramID;
return RedirectToAction("CI_SequenceBlocks");
}
}
public ActionResult CI_SequenceBlocks_Pager_Form_Handler(int id, string value, int inInstitutionProgramID)
{
TempData["CI_SequenceBlocks_InstitutionProgram"] = inInstitutionProgramID;
TempData["CI_SequenceBlocks_SRCHString"] = value;
TempData["CI_SequenceBlocks_RequestedPage"] = id;
return RedirectToActionPermanent("CI_SequenceBlocks");
}
[HttpPost]
public ActionResult CI_SequenceBlocks_ProgramChange(FormCollection form)
{
TempData["CI_SequenceBlocks_InstitutionProgram"] = form["SelectedInstitutionProgram"].ToString();
return RedirectToActionPermanent("CI_SequenceBlocks");
}
RouteConfig.cs
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}/{id2}/{id3}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional, id2 = UrlParameter.Optional, id3 = UrlParameter.Optional }
);
}
Full Razor Code:
#model IEnumerable<UTCI_Manager.Models.vm_CI_SequenceBlock>
#{
ViewBag.Title = "CI_SequenceBlocks";
}
<h2>CI_SequenceBlocks</h2>
#using (Html.BeginForm("CI_SequenceBlocks_ProgramChange", "Home", FormMethod.Post, new { id = "submitForm" }))
{
#Html.DisplayNameFor(model => model.InstitutionProgramID)
#Html.DropDownList("SelectedInstitutionProgram", (SelectList)ViewData["listInstitutionPrograms"], new { onchange = "this.form.submit();" })
}
#using (Html.BeginForm("CI_Sequenceblocks_FullTextSearch", "Home", FormMethod.Post, new { id = "submitForm" }))
{
if (ViewData["SelectedInstitutionProgram"].ToString() != "0")
{
<div class="input-group">
#Html.Hidden("HidInstitutionProgram", ViewData["SelectedInstitutionProgram"]?.ToString() ?? "0")
#Html.TextBox("SRCHString", ViewData["inSRCHString"].ToString(), new { #class = "form-control", #placeholder = "Search" })
<span class="input-group-btn">
<button class="btn btn-info" type='submit' value="Search">Search</button>
</span>
</div>
}
}
<table class="table table-striped" summary="List of Sequence Blocks">
<tr>
#* <th>
#Html.DisplayNameFor(model => model.SequenceBlockID)
</th>
<th>
#Html.DisplayNameFor(model => model.InstitutionProgramID)
</th>
*#
<th>
#Html.DisplayNameFor(model => model.Title)
</th>
<th>
#Html.DisplayNameFor(model => model.SequenceBlockDescription)
</th>
<th>
#Html.DisplayNameFor(model => model.SequenceBlockRequired)
</th>
#* <th>
#Html.DisplayNameFor(model => model.Minimum)
</th>
<th>
#Html.DisplayNameFor(model => model.Maximum)
</th>
*#
<th>
#Html.DisplayNameFor(model => model.SequenceBlockTimingMethod)
</th>
<th>
#Html.DisplayNameFor(model => model.Duration)
</th>
<th>
#Html.DisplayNameFor(model => model.StartDate)
</th>
<th>
#Html.DisplayNameFor(model => model.EndDate)
</th>
<th>
#Html.DisplayNameFor(model => model.ClerkshipModel)
</th>
<th>
#using (Html.BeginForm("CI_SequenceBlocks_AddSequenceBlock", "Home", FormMethod.Post, new { id = "submitForm" }))
{
if (ViewData["SelectedInstitutionProgram"].ToString() != "0")
{
#Html.Hidden("HidInstitutionalProgram", ViewData["SelectedInstitutionProgram"].ToString())
<input type="submit" value="Add Sequence Block" class="btn btn-sm" />
}
}
</th>
</tr>
#foreach (var item in Model)
{
<tr>
#Html.HiddenFor(modelItem => item.SequenceBlockID)
#Html.HiddenFor(modelItem => item.InstitutionProgramID)
#Html.HiddenFor(modelItem => item.Minimum)
#Html.HiddenFor(modelItem => item.Maximum)
<td>
#Html.DisplayFor(modelItem => item.Title)
</td>
<td>
#Html.DisplayFor(modelItem => item.SequenceBlockDescription)
</td>
<td>
#Html.DisplayFor(modelItem => item.SequenceBlockRequired)
</td>
<td>
#Html.DisplayFor(modelItem => item.SequenceBlockTimingMethod)
</td>
<td>
#Html.DisplayFor(modelItem => item.Duration)
</td>
<td>
#Html.DisplayFor(modelItem => item.StartDate)
</td>
<td>
#Html.DisplayFor(modelItem => item.EndDate)
</td>
<td>
#Html.DisplayFor(modelItem => item.ClerkshipModel)
</td>
<td>
#Html.ActionLink("Edit", "CI_SequenceBlocks_Edit_Form_Handler", new { id = item.SequenceBlockID, value = "Edit_SequenceBlock_ID", inInstitutionProgramID = item.InstitutionProgramID }) |
#Html.ActionLink("Maintain", "CI_SequenceBlocks_Edit_Form_Handler", new { id = item.SequenceBlockID, value = "Maintain_SequenceBlock_ID", inInstitutionProgramID = item.InstitutionProgramID })
</td>
</tr>
}
</table>
#if (ViewData["SelectedInstitutionProgram"].ToString() != "0")
{
<div class="text-center" >
<ul class="pagination">
#for (var i = 1; i <= ViewBag.SearchMetaData.SearchNumberOfPages; i++)
{
if (ViewBag.SearchMetaData.SearchCurrentPage == #i)
{
<li class="active"> #Html.ActionLink(#i.ToString(), "CI_SequenceBlocks_Pager_Form_Handler", new { id = #i, value = ViewBag.SearchMetaData.SearchString, inInstitutionProgramID = ViewData["SelectedInstitutionProgram"].ToString() },null)</li>
}
else
{
<li> #Html.ActionLink(#i.ToString(), "CI_SequenceBlocks_Pager_Form_Handler", "Home", new { id = #i, value = ViewBag.SearchMetaData.SearchString, inInstitutionProgramID = ViewData["SelectedInstitutionProgram"].ToString() },null)</li>
}
}
</ul>
</div>
}
#using (Html.BeginForm("CI_SequenceBlocks_AddSequenceBlock", "Home", FormMethod.Post, new { id = "submitForm" }))
{
if (ViewData["SelectedInstitutionProgram"].ToString() != "0")
{
<table class="table">
<tr>
<td>
#Html.Hidden("HidInstitutionProgram", ViewData["SelectedInstitutionProgram"].ToString())
</td>
</tr>
<tr>
<td>Add Sequence Block:</td>
<td> <input type="submit" value="Add Sequence Block" class="btn btn-sm" /> </td>
</tr>
</table>
}
}
____________NEW UPDATE____________
Found the issue:
I changed RedirectToActionPermanent to RedirectToAction. No more problems!
Thanks,
James

Sortable, draggable, orderable table + mvc not updating order correctly

I'm trying to add an orderable table to my view. The sorting works when doing it in the View New.cshtml. It uses jQuerys sortable. If I add some instructions (1-5 in this case) I can move them around thanks to the sortable script. But when I try to add a new instruction after the reordering, the order change from:
to
I guess it has something to do with the hidden form
#Html.HiddenFor(m => m.Recipe.Instructions[i].Number, new { #id = "Number"})
It needs to update its value when I reorder the fields in the sortable table.
What am I missing here?
RecipeController.cs
public ActionResult Create(NewRecipeViewModel viewModel, string command)
{
//...more code...
var instructionList = new List<Instruction>();
if (viewModel.Recipe.Instructions != null)
{
for (int i = 0; i < viewModel.Recipe.Instructions.Count; i++)
{
var instruction = new Instruction
{
Id = viewModel.Recipe.Instructions[i].Id,
Name = viewModel.Recipe.Instructions[i].Name,
Number = viewModel.Recipe.Instructions[i].Number
};
instructionList.Add(instruction);
}
}
if (command.Equals("AddInstruction"))
{
var instruction = new Instruction
{
Name = viewModel.NewInstruction.Name,
Number = viewModel.Recipe.Instructions.Count + 1
};
recipe.Instructions.Add(instruction);
viewModel.Recipe = recipe;
return View("New", viewModel);
}
//...more code...
}
New.cshtml
<div class="form-group" style="margin-top: 170px;">
<label class="col-md-2 control-label">
Lägg till instruktion:
</label>
<div class="col-md-10">
#Html.TextBoxFor(m => m.NewInstruction.Name, new { #class = "form-control" })
</div>
</div>
<div class="form-group" style="margin-top: 300px;">
<label class="col-md-2 control-label">
</label>
<div class="col-md-10">
<button type="submit" name="command" value="AddInstruction" class="btn btn-primary">Add instruction</button>
</div>
</div>
<div class="form-group" style="margin-top: 100px;">
<label class="col-md-2 control-label">
Instructions:
</label>
<div class="col-md-10">
<table class="table table-bordered table-hover pagin-table" style="margin-top: 10px">
<thead>
<tr bgcolor="#f5f5f5">
<th>Order:</th>
<th>Instruction:</th>
</tr>
</thead>
<tbody id="sortable">
#if (Model.Recipe.Instructions != null)
{
for (int i = 0; i < Model.Recipe.Instructions.Count; i++)
{
<tr>
#Html.HiddenFor(m => Model.Recipe.Instructions[i].Id)
<td class="order">
#Model.Recipe.Instructions[i].Number
#Html.HiddenFor(m => m.Recipe.Instructions[i].Number, new { #id = "Number"})
</td>
<td>
#Model.Recipe.Instructions[i].Name
#Html.HiddenFor(m => m.Recipe.Instructions[i].Name)
</td>
</tr>
}
}
</tbody>
</table>
</div>
</div>
<script type="text/javascript">
$(document).ready(function() {
$('#sortable').sortable({
update : function(event, ui) {
$('td.order').each(function(index) {
var order = index + 1;
$(this).find('span').text(order);
$(this).find('.Number').val(order);
});
}
});
});
</script
EDIT:
Added
instructionList.Sort((s1, s2) => s1.Number.CompareTo(s2.Number));
to RecipeController.cs. The rest is credit to Stephen Muecke.
RecipeController.cs
public ActionResult Create(NewRecipeViewModel viewModel, string command)
{
//...more code...
var instructionList = new List<Instruction>();
if (viewModel.Recipe.Instructions != null)
{
for (int i = 0; i < viewModel.Recipe.Instructions.Count; i++)
{
var instruction = new Instruction
{
Id = viewModel.Recipe.Instructions[i].Id,
Name = viewModel.Recipe.Instructions[i].Name,
Number = viewModel.Recipe.Instructions[i].Number
};
instructionList.Add(instruction);
}
instructionList.Sort((s1, s2) => s1.Number.CompareTo(s2.Number));
}
//...more code...
}
New.cshtml
#* More code *#
<td class="order">
<span>#Model.Recipe.Instructions[i].Number</span>
#Html.HiddenFor(m => m.Recipe.Instructions[i].Number, new {#class = "Number"})
</td>
#* More code *#
<script type="text/javascript">
$(document).ready(function() {
$('#sortable').sortable({
update : function(event, ui) {
$('td.order').each(function(index) {
var order = index + 1;
$(this).find('span').text(order);
$(this).find('.Number').val(order);
});
}
});
});
</script
Your selector in the update function is incorrect and would return undefined (you are missing the # (id selector) and in anycase the $ creates a jQuery object, so it would be .val(...), not value=....
However using $('#Number').val(index + 1) will not work correctly since it would only ever update the first element with id="Number". Duplicateid` attributes are invalid html.
Use a class name and relative selectors instead. Change the html to
<td class="order">
<span>#Model.Recipe.Instructions[i].Number</span>
#Html.HiddenFor(m => m.Recipe.Instructions[i].Number, new { #class = "Number"})
</td>
and then the script to
$('#sortable').sortable({
update : function(event, ui) {
$('td.order').each(function(index) {
var order = index + 1;
$(this).find('span').text(order );
$(this).find('.Number').val(order );
});
}
});
In your markup, change Model to your projected variable m within your 'Html.HiddenFor()' HTML helpers.
<tr>
#Html.HiddenFor(m => m.Recipe.Instructions[i].Id)
<td class="order">
#Model.Recipe.Instructions[i].Number
#Html.HiddenFor(m => m.Recipe.Instructions[i].Number, new { #id = "Number"})
</td>
<td>
#Model.Recipe.Instructions[i].Name
#Html.HiddenFor(m => m.Recipe.Instructions[i].Name)
</td>
</tr>

Show Limited Number of Page Links at a time in ASP.net MVC

I am displaying page links with the help of PagedList in ASP.net MVC. But the issue is if there are 100 pages then all links show at the same time but i want to show 10 links at a time. How can it be achieved. Please Help. Thanks.. Below is the working Code.
Index.cshtml
#model PagedList.IPagedList<MvcPagingList.Models.Employee>
#{
ViewBag.Title = "Employees";
}
<link href="#Url.Content("~/bootstrap/css/bootstrap.min.css")" rel="stylesheet" type="text/css" />
<link href="#Url.Content("~/bootstrap/css/bootstrap.css")" rel="stylesheet" type="text/css" />
<h2>
Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
#using (Html.BeginForm())
{
<p>
Search By Name : #Html.TextBox("SearchString", ViewBag.CurrentFilter as string)
<input type="submit" value="Search" /></p>
}
<table>
<tr>
<th>
#Html.Label("Last Name")
</th>
<th>
#Html.Label("First Name")
</th>
<th>
#Html.Label("Department ID")
</th>
<th>
#Html.ActionLink("Salery", "Index", new { sortOrder = ViewBag.NameSortParm, currentFilter = ViewBag.CurrentFilter })
</th>
<th>
</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.LastName)
</td>
<td>
#Html.DisplayFor(modelItem => item.FirstName)
</td>
<td>
#Html.DisplayFor(modelItem => item.DepartmentID)
</td>
<td>
#Html.DisplayFor(modelItem => item.Salary)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.EmployeeID }) |
#Html.ActionLink("Details", "Details", new { id = item.EmployeeID }) |
#Html.ActionLink("Delete", "Delete", new { id = item.EmployeeID })
</td>
</tr>
}
</table>
<div class="pagination pagination-right">
<ul>
<li>
#for (int p = 1; p <= Model.PageCount; p++)
{
#p
}
</li>
</ul>
</div>
HomeController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MvcPagingList.Models;
using PagedList;
namespace MvcPagingList.Controllers
{
public class HomeController : Controller
{
EmployeeEntities dbEntities = new EmployeeEntities();
public ViewResult Index(string sortOrder, string currentFilter, string searchString, int? page)
{
ViewBag.CurrentSort = sortOrder;
ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "Salery desc" : "";
//ViewBag.DateSortParm = sortOrder == "HireDate" ? "HireDate desc" : "HireDate";
if (Request.HttpMethod == "GET")
{
searchString = currentFilter;
}
else
{
page = 1;
}
ViewBag.CurrentFilter = searchString;
var employees = from s in dbEntities.Employees
select s;
if (!String.IsNullOrEmpty(searchString))
{
employees = employees.Where(s => s.LastName.ToUpper().Contains(searchString.ToUpper())
|| s.FirstName.ToUpper().Contains(searchString.ToUpper()));
}
switch (sortOrder)
{
case "Salery desc":
employees = employees.OrderByDescending(s => s.LastName);
break;
default:
employees = employees.OrderBy(s => s.LastName);
break;
}
int pageSize = 3;
int pageNumber = (page ?? 1);
return View(employees.ToPagedList(pageNumber, pageSize));
}
}
}
I faced the same issue & solved it by studying the following Code :-
http://msdn.microsoft.com/en-us/magazine/gg650669.aspx
You will have to use webgrid for this.
http://www.w3schools.com/aspnet/showfile_c.asp?filename=try_webpages_cs_004

Categories