passing whole datatable from view to the controller action method - asp.net-mvc

I have the view below:
<table cellpadding="0" cellspacing="0" border="0" class="display mobile_dt1" id="SearchResults">
<thead>
<tr>
#* <input type="checkbox" name="Test" onclick="SetAllCheckBoxes('PartialViewName')" *#
<th id="CHCKID" class="checkBoxClass">Check All #Html.CheckBox("checkboxall", new { #id = "checkall", #name = "StatusList" })</th>
<th>Export</th>
<th>Request ID</th>
<th id="RQSTNMSRCHID" style="display: none">#BVPConstants.RQSTNMSRCH</th>
<th id="RQSTSTTSSRCHID">#BVPConstants.RQSTSTTSSRCH</th>
<th>Strategic Initiative</th>
<th id="BSNGRPL1ID">#BVPConstants.BSNGRPL1</th>
<th id="EXCTVSPNSRID">#BVPConstants.EXCTVSPNSR</th>
<th id="RQSTCLSFNID">#BVPConstants.RQSTCLSFN</th>
<th id="BUSNDBYDTID">#BVPConstants.BUSNDBYDT</th>
<th id="CRTDBYSRCHID">#BVPConstants.CRTDBYSRCH</th>
<th id="CRTDONID">#BVPConstants.CRTDON</th>
</tr>
</thead>
<tbody>
#if (Model != null)
{
foreach (var SearchResult in Model)
{
<tr>
<td class="chck">#Html.CheckBox("checkboxall", new { #id = "check" })</td>
<td>#Html.ActionImage("", "", new { #Id = "export" }, null, null, null, "~/Content/img/ico/filePDFUpload.png", "Download")</td>
<td>#Html.ActionLink(SearchResult.RequestId.ToString(), "Edit", "BusinessRequest", new { requestId = SearchResult.RequestId }, new { #onerror = "closeLoading()", #onload = "closeLoading()", #onclick = "showLoading()" })</td>
<td>#Html.ActionLink(SearchResult.RequestName.ToString(), "Edit", "BusinessRequest", new { requestId = SearchResult.RequestId }, new { #onerror = "closeLoading()", #onload = "closeLoading()", #onclick = "showLoading()" }) </td>
<td>#SearchResult.Status</td>
<td>#SearchResult.StrategicInitiativeNumber</td>
<td>#SearchResult.BusinessGroup</td>
<td>#SearchResult.ExecutiveSponsorNumber</td>
<td>#SearchResult.RequestClassification</td>
<td>#SearchResult.BusinessNeedByDate</td>
<td>#SearchResult.CreatedBy</td>
<td>#SearchResult.CRTTs</td>
</tr>
}
}
</tbody>
</table>
I want to send the SearchResults datatable to the below controller method:
public PartialViewResult ExportToExcel(DataTable table) {
List<SearchRequestModel> srchlist = new List<SearchRequestModel>();
StringWriter stringWriter = new StringWriter();
var grid = new GridView();
grid.DataSource = table;
grid.DataBind();
Response.ClearContent();
Response.AddHeader("Content-Disposition", "attachment; filename=Prioritization.xls");
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
HtmlTextWriter htmlTextWriter = new HtmlTextWriter(stringWriter);
grid.RenderControl(htmlTextWriter);
Response.Write(stringWriter.ToString());
Response.End();
return PartialView("_SearchHistory", srchlist);
}

The Action Method parameter maps automatically the Request.Form. That said, you will only be able to make your DataTable parameter work (has values) if you have form fields in your table.
Since you don't want to allow the user to edit the data I would recommend you to use hidden fields. You can do them either "manually" (<input type="hidden" />) or use the MVC Html helper (#Html.HiddenFor()).

Related

'Object reference not set to an instance of an object' Error when trying to move contents from view page to another

I have a button in my Index.html page which shows another view page: Reports.cshtml, there is a table inside the page, now I want to remove this button and let the table showing on my Index.html page directly, but when I paste the table to the code it shows an error:
Error
Part of my view code are showed below:
<table id="hardware-data-table" class="table table-striped table-hover">
<thead bgcolor="silver">
<tr>
<th hidden="hidden">
#Html.LabelFor(model => model.Report_HardwareListByExpiration.FirstOrDefault().InvHardwareID)
</th>
<th>
#Html.LabelFor(model => model.Report_HardwareListByExpiration.FirstOrDefault().Equipment)
</th>
<th>
#Html.LabelFor(model => model.Report_HardwareListByExpiration.FirstOrDefault().HardwareModel)
</th>
<th>
#Html.LabelFor(model => model.Report_HardwareListByExpiration.FirstOrDefault().WL_EndDateFormatted)
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.Report_HardwareListByExpiration)
{
if (item.WL_EndDate < DateTime.Now && item.WL_EndDate > DateTime.Now.AddYears(-99))
{
<tr>
<td hidden="hidden">
#item.InvHardwareID
</td>
<td>
#item.Equipment
</td>
<td>
#item.HardwareModel
</td>
<td style="background-color: #ff726f">#item.WL_EndDateFormatted</td>
</tr>
}
if (item.WL_EndDate > DateTime.Now && item.WL_EndDate < DateTime.Now.AddYears(99))
{
<tr>
<td hidden="hidden">
#item.InvHardwareID
</td>
<td>
#item.Equipment
</td>
<td>
#item.HardwareModel
</td>
<td style="background-color: orange">
#item.WL_EndDateFormatted
</td>
</tr>
}
}
</tbody>
</table>
My Report controller code are showed below:
public class ReportsController : Controller
{
// GET: Report
public ActionResult Reports()
{
if (Session["UserID"] == null || !(bool)Session["IsLoggedIn"])
{
return RedirectToAction("Login", "Account");
}
ViewModel myViewModel = new ViewModel
{
User = GetSessionInfoFromSessions(),
Params = new ParametersModel
{
Start_Date = new DateTime(2015, 12, 31),
End_Date = DateTime.Now.AddDays(60)
}
};
myViewModel.Report_HardwareListByExpiration = InvHardwareModel.Report_HardwareListByExpiration(myViewModel);
return View(myViewModel);
}
And my hardware Model:
public static List<InvHardwareModel> Report_HardwareListByExpiration(ViewModel myViewModel)
{
try
{
var myAssManEnt = new AssetManagementEntities();
var myUspList = myAssManEnt.usp_Report_InvHardware_ByExpirationDates
(
agencyID : myViewModel.User.AgencyID,
deptID : myViewModel.User.DeptID,
roleID : myViewModel.User.RoleID,
startDate : myViewModel.Params.Start_Date,
endDate : myViewModel.Params.End_Date
).ToList();
var myReturnList = new List<InvHardwareModel>();
foreach(usp_Report_InvHardware_ByExpirationDates_Result myItem in myUspList)
{
myReturnList.Add(Models.InvHardwareModel.ToModel(myItem));
}
return myReturnList;
}
catch(Exception e)
{
throw ErrorHandler.MyException(e, "InvHardwareModel.Report_HardwareListByExpiration");
}
}
The code works perfect when its in the other view page, but shows exception when I move it to my home page, any ideas? Thank you so much!

error while posting pagedlist from view to the controller

I've an indexed page in MVC with data that displays in a table format from the database and using paging. I want to edit only one column of the table. Can I post the paging list to the controller for editing. If so how?
I'm able to edit with normal list getting error while passing PagedList
--- this is my index page----
#model PagedList.IPagedList<emp_prac.Models.Employee>
#using PagedList.Mvc;
#*#model List<emp_prac.Models.Employee>*#
#using (Html.BeginForm("UpdateOrder", "Employee", FormMethod.Post))
{
Html.AntiForgeryToken();
Html.EditorForModel();
ViewBag.Title = "Employee Details";
<h2>Employee Details</h2>
<p>
#Html.ActionLink("Create New", "InsertEmployee")
</p>
<table class="table">
<thead>
<tr>
<th>Edit</th>
<th>Delete</th>
<th>Name</th>
<th>Email</th>
<th>Phone No</th>
<th>Salary</th>
<th>Joining Date</th>
<th>PDF</th>
<th>Status</th>
<th>Order</th>
</tr>
</thead>
<tbody>
#for (int i = 0; i < Model.Count; i++)
{
<tr>
<td>#Html.ActionLink("Edit", "EditEmployee", new { id = Model[i].emp_id }) </td>
<td>#Html.ActionLink("Delete", "DeleteEmployee", new { id = Model[i].emp_id }, new { onclick = "return confirm('Are you sure you want to delete?');", #class = "btn-btn-default" }) </td>
<td>#Html.DisplayFor(model => model[i].emp_name)</td>
<td>#Html.DisplayFor(model => model[i].emp_email)</td>
<td>#Html.DisplayFor(model => model[i].emp_phone_no)</td>
<td>#Html.DisplayFor(model => model[i].emp_salary)</td>
<td>#Html.DisplayFor(model => model[i].emp_joining_date)</td>
<td>#Html.ActionLink("PDF", "UploadPdf", new { id = Model[i].emp_id }) </td>
<td>#(Html.DisplayFor(model => model[i].emp_status).ToString() == "1" ? "Active" : "Inactive")</td>
<td>#Html.TextBoxFor(model => model[i].emp_order, new { style = "width: 35px" })</td>
<td>#Html.HiddenFor(model => model[i].emp_id)</td>
</tr>
}
</tbody>
</table>
<button type="submit" value="Order" onclick="location.href='#Url.Action("UpdateOrder","Employee")'">Order</button>
}
<br />
Page #(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of #Model.PageCount
#Html.PagedListPager(Model, page => Url.Action("Index", new { page }))`
---This is my controller action method---
[HttpPost]
public ActionResult UpdateOrder(PagedList<Employee> obj_view)
{
foreach (var abc in obj_view)
{
Employee obj = new Employee();
obj.emp_order = abc.emp_order;
obj.emp_id = abc.emp_id;
obj.Mode = "O";
Employee.InsertUpdateEmployee(obj);
}
return RedirectToAction("Index");
}
I looked deeply into your code , as per my point of view, below line may cause the error.
**<button type="submit" value="Order" onclick="location.href='#Url.Action("UpdateOrder","Employee")'">Order</button>
}**
Reason:
When you post the data through the form post, you no need to specify the onclick in the submit button
Solution:
Just replace the above line with simple submit button like this
**<input type="submit" value="Order" class="btn btn-default" />**
And see in the button click event whether you get the data or not using breakpoint.
Hope you will surely get the data now , kindly let me know your thoughts or feedbacks
Thanks
Karthik

MVC 5 get value of CheckBox Checked in controller with Ajax.BeginForm

I use MVC 5 and I try to get the value of the checkbox checked in the controller but so far it always return null.
Here is my code:
In View
#using (Ajax.BeginForm("Delete",
"User",
new AjaxOptions
{
HttpMethod = "POST",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "table",
OnSuccess = "Success",
OnFailure = "Fail"
}))
{
Add
<button type="submit">Delete</button>
<div id="table">
#{Html.RenderPartial("_UserTable", Model);
</div>
}
My Partial View
<table>
<thead>
<tr>
<th></th>
<th>Name</th>
<th>Email</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
<input type="checkbox" namespace="userCheck" value="#Html.DisplayFor(modelItem => item.UserName)"/>
</td>
<td>
#Html.DisplayFor(modelItem => item.UserName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Email)
</td>
</tr>
}
</tbody>
</table>
And My Controller
public ActionResult
Delete(string[] userCheck)
{
for (int ix = 0; ix < userCheck.Length; ix++)
{
// do something with userCheck[ix]
}
return Index();
}
My button works and go to the Delete Action but userCheck is always null.
How can I get the value of the multiple checkbox?
Thanks

A Column not showing in a Responsive DataTable for Mobile

I implemented a responsive dataTable for mobile (iPhone), it is showing all the columns except for the last column with the CRUD action links, like Edit, Details, and Delete.
Mobile View
Desktop View
The dataTable is also not showing the plus icon to expand & close certains columns. What am I missing in creating the dataTable?
<div class="table-responsive">
<table id="dataTable" class="table table-striped table-bordered dt-responsive nowrap" cellspacing="0" style="width: 100%;">
<thead>
<tr>
<th>
#Html.ActionLink("Last Name", "Index", new { sortOrder = ViewBag.NameSortParm, currentFilter = ViewBag.CurrentFilter })
</th>
<th>
First Name
</th>
<th>
#Html.ActionLink("Enrollment Date", "Index", new { sortOrder = ViewBag.DateSortParm, currentFilter = ViewBag.CurrentFilter })
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.LastName)
</td>
<td>
#Html.DisplayFor(modelItem => item.FirstMidName)
</td>
<td>
#Html.DisplayFor(modelItem => item.EnrollmentDate)
</td>
<td>
#Html.ActionLink("Details", "Details", new { id = item.ID })
#if (User.IsInRole("Admin"))
{
#:|
#Html.ActionLink("Edit", "Edit", new { id = item.ID })#: |
#Html.ActionLink("Delete", "Delete", new { id = item.ID })
}
else
{
}
</td>
</tr>
}
</tbody>
</table>
</div>
I was missing a JavaScript tag for responsive dataTable and the number of children of my <tr> element didn't match the number of <th> elements that were a child of the <thead> element."

Paging is not working in MVC4

I am designing one page where I am displaying some details with paging. Page works fine except paging. When i click on second page nothing happens. All data cureently displayed will also go. Also when i hit on second page control wont go to my action method. This is my pager code.
#Html.PagedListPager(Model.logDetails, page => Url.Action("Index",
new { page, currentFilter = ViewBag.CurrentFilter, filterdateTime=ViewBag.filterdateTimepageSize, }))
Page #(Model.logDetails.PageCount < Model.logDetails.PageNumber ? 0 : Model.logDetails.PageNumber) of #Model.logDetails.PageCount
This is my action method code.
[HttpPost]
public ActionResult Index(int? clientId, DateTime? dateofAction,string typeofDocument,string employeeID,string citizenId,int? currentFilter,DateTime? filterdateTime,int? page)
{
DB_KYC3Entities db = new DB_KYC3Entities();
ViewBag.docTypes = new SelectList(db.tm_doc_type, "doc_typeid", "doctype_name");
if (clientId != null)
{
page = 1;
}
else
{
clientId = currentFilter;
}
if(dateofAction!=null)
{
page = 1;
}
else
{
dateofAction = filterdateTime;
}
ViewBag.CurrentFilter = clientId;
ViewBag.filterdateTime = dateofAction;
int pageSize = 8;
int pageNumber = (page ?? 1);
VerificationLogBAL obj = new VerificationLogBAL();
int docType = obj.GetDocDetails(typeofDocument);
List<logDetails> logDetails = obj.getlogDetails(clientId?? default(int), dateofAction?? DateTime.Now, docType, employeeID, citizenId);
IPagedList<logDetails> pagedLog = logDetails.ToPagedList(pageNumber, pageSize);
logDetailsEnumeration model = new logDetailsEnumeration();
ViewBag.checkData = logDetails.Count;
model = new logDetailsEnumeration()
{
logDetails= pagedLog
};
return View("Index",model);
}
This is my view code.
<div class="forms">
#using (Html.BeginForm("Index", "VerificationLog", FormMethod.Post))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<div class="message"></div>
<div class="loginUsernamePassword">
<i class="fa fa-user"></i>
<table width="100%" border="0" cellspacing="0" cellpadding="0" class="dataTable tableHover">
<tr>
<th width="8%" scope="col">Client ID</th>
<th width="20%" scope="col">
<div class="form-box form-box-default">
#Html.TextBox("clientId", ViewBag.CurrentFilter as string, new { #id = "clientId", #placeholder = "Client ID", #class = "form-control", #maxlength = 20 })
</div>
</th>
<th width="10%" scope="col">Date Of Action</th>
<th width="20%" scope="col">
<div class="form-box form-box-default">
#Html.TextBox("dateofAction", ViewBag.filterdateTime as string, new { #id = "dateofAction", #placeholder = "Date Of Action", #class = "txtBox form-control calender validate[required]" })
</div>
</th>
<th width="15%" scope="col">Type Of Document</th>
<th width="17%" scope="col">
<div class="form-box form-box-default">
#*#Html.TextBox("typeofDocument", ViewBag.filterdateTime as string, new { #id = "typeofDocument", #placeholder = "Type Of Document", #class = "form-control", #maxlength = 20 })*#
#Html.DropDownList("docTypes",null,new {#id = "typeofDocument", #placeholder = "Type Of Document", #class = "form-control"})
</div>
</th>
</tr>
<tr>
<th width="15%" scope="col">Employee ID</th>
<th width="17%" scope="col">
<div class="form-box form-box-default">
#Html.TextBox("employeeID", ViewBag.filterdateTime as string, new { #id = "employeeID", #placeholder = "Employee ID", #class = "form-control", #maxlength = 20 })
</div>
</th>
<th width="15%" scope="col">Citizen ID</th>
<th width="17%" scope="col">
<div class="form-box form-box-default">
#Html.TextBox("citizenId", ViewBag.filterdateTime as string, new { #id = "citizenId", #placeholder = "Citizen ID", #class = "form-control", #maxlength = 20 })
</div>
</th>
<th width="10%" scope="col" colspan="2">
<input type="submit" value="Search" class="btn btn-primary btn-cons search" />
</tr>
</table>
</div>
}
</div>
#if (Model != null && Model.logDetails.Count != 0)
{
<br />
<h2>Verification Log</h2>
<br />
<div id="GridDetails">
<table width="100%" border="0" cellspacing="0" cellpadding="0" class="dataTable tableHover">
<tr>
<th>Label</th>
<th>Value</th>
<th>UpdatedOn</th>
<th>UpdatedBy</th>
<th>UpdatedStatus</th>
<th>RejectComment</th>
</tr>
#foreach (var group in Model.logDetails)
{
<tr>
<td>#group.contentLabel</td>
<td>#group.contentValue</td>
<td>#group.updatedOn</td>
<td>#group.updatedBy</td>
<td>#group.updatedStatus</td>
<td>#group.rejectComment</td>
</tr>
}
</table>
[HttpGet]
public ActionResult Index()
{
DB_KYC3Entities db = new DB_KYC3Entities();
ViewBag.docTypes = new SelectList(db.tm_doc_type, "doc_typeid", "doctype_name");
return View();
}
When i click on second page control wont go to my index method also. Also i have 5 textboxes so do i need to preserve the all 5 text box values in viewbag? Can someone tell me? Thanks in advance
PagedListPager makes a GET call, not a POST, so you need to remove the [HttpPost] attribute from the Index() method. Associated with that, you need to change the form to also make a GET
#using (Html.BeginForm("Index", "VerificationLog", FormMethod.Get))
And yes, you need to preserve the all 5 text box values in viewbag (or better using a view model) and add those values in the pagers Url.Action() in the same way your are adding currentFilter and filterdateTime

Resources