'Object reference not set to an instance of an object' Error when trying to move contents from view page to another - asp.net-mvc

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!

Related

Controller can't receive model data [duplicate]

This question already has answers here:
Post an HTML Table to ADO.NET DataTable
(2 answers)
Closed 6 years ago.
Hi I want to grab all user modify data.
My question is why controller can't receive the model data from View in my project.
Please explain why this error was caused and how to solve it.
Models:
public class ShoppingCart
{
public List<ShoppingCartItemModel> items = new List<ShoppingCartItemModel>();
public IEnumerable<ShoppingCartItemModel> Items
{
get { return items; }
}
}
public class ShoppingCartItemModel
{
public Product Product
{
get;
set;
}
public int Quantity { get; set; }
}
Controller
[HttpPost]
public RedirectToRouteResult EditFromCart(ShoppingCart MyModel)
{
ShoppingCart cart = GetCart();
foreach (var CartItem in cart.items)
{
foreach (var ReceiveModelItem in MyModel.items)
{
if (CartItem.Product.ProductID == ReceiveModelItem.Product.ProductID)
{
CartItem.Quantity = ReceiveModelItem.Quantity;
}
}
}
return RedirectToAction("Index", "ShoppingCart");
}
View
#model ShoppingCart
#{
ViewBag.Title = "購物車內容";
}
<h2>Index</h2>
<table class="table">
<thead>
<tr>
<th>
Quantity
</th>
<th>
Item
</th>
<th class="text-right">
Price
</th>
<th class="text-right">
Subtotal
</th>
</tr>
</thead>
<tbody>
#using (Html.BeginForm("EditFromCart", "ShoppingCart", FormMethod.Post))
{
foreach (var item in Model.items)
{
<tr>
<td class="text-center">
#item.Product.ProductName
</td>
<td class="text-center">
#item.Product.Price.ToString("c")
</td>
<td class="text-center">
#( (item.Quantity * item.Product.Price).ToString("c"))
</td>
<td class="text-left">
#Html.EditorFor(model => item.Quantity, null, "UserInputQuantity")
#Html.Hidden("ProductId", item.Product.ProductID)
</td>
</tr>
}
<tr>
<td colspan="3">
<input class="btn btn-warning" type="submit" value="Edit">
</td>
</tr>
}
</tbody>
</table>
You must explicitly create a hidden input for each property in your complex object that you want to be bound. IEnumerables and binding don't play very nicely directly out of the box - it looks like MVC has better base support for IList<> and arrays, but you'll still have to enumerate the collection and create hidden inputs for each item. Have a look at this link. So, ideally your view should be:
#model ShoppingCart
#{
ViewBag.Title = "購物車內容";
}
<h2>Index</h2>
<table class="table">
<thead>
<tr>
<th>
Quantity
</th>
<th>
Item
</th>
<th class="text-right">
Price
</th>
<th class="text-right">
Subtotal
</th>
</tr>
</thead>
<tbody>
#using (Html.BeginForm("EditFromCart", "ShoppingCart", FormMethod.Post))
{
for (int i = 0; i < Model.items.Count(); ++i)
{
<tr>
<td class="text-center">
#Model.items[i].Product.ProductName
</td>
<td class="text-center">
#Model.items[i].Product.Price.ToString("c")
</td>
<td class="text-center">
#( (Model.items[i].Quantity * Model.items[i].Product.Price).ToString("c"))
</td>
<td class="text-left">
#Html.EditorFor(model => Model.items[i].Quantity)
#Html.HiddenFor(model => Model.items[i].Product.ProductID)
#Html.HiddenFor(model => Model.items[i].Product.ProductName)
#Html.HiddenFor(model => Model.items[i].Product.Price)
</td>
</tr>
}
<tr>
<td colspan="3">
<input class="btn btn-warning" type="submit" value="Edit">
</td>
</tr>
}
</tbody>
</table>
Names are not correctly set for your text and hidden inputs:
#Html.EditorFor(model => item.Quantity, null, "UserInputQuantity")
#Html.Hidden("ProductId", item.Product.ProductID)
If you inspect elements you can see names are UserInputQuantity and ProductId, but they should be
items[i].Quantity and items[i].Product.ProductID respectively.
You can take a look at this link:
MVC Model binding of complex objects

How to handle errors in Razor view engine?

How to handle errors in Razor (i.e. Null Exception)other than (try/catch)?
I do not want to insert (try/catch) block in every razor block.
Example (The (Model.ListofEntity) or (Item.Values) may be null and an exception might occur):
<table class="table">
<tr>
<th>
<div id="chkCheckAll" class="divCheckbox">
</div>
</th>
#foreach (var column in Model.ListofEntity.Columns)
{
int t = Convert.ToInt32(" ");
<th>
#column
</th>
}
</tr>
#foreach (CVMEntities.Item Item in Model.ListofEntity.Items)
{
<tr>
<td>
<div id=#Item.ID class="divCheckbox">
</div>
</td>
#foreach (var Value in Item.Values)
{
<td>
#Value
</td>
}
</tr>
}
</table>

No model binding with editor template

I have following view:
#model StockItemDetailModel
#using (Html.BeginForm("EditDetails", "StockItem"))
{
<div class="ItemDetails">
<table class="datagrid">
<tr>
<th colspan="3">#Model.StockItemPropertiesCaption</th>
</tr>
<tr>
<td class="label">#Model.StoreLabel</td>
<td class="value">#Html.DisplayFor(item => item.Store)</td>
<td></td>
</tr>
<tr>
<td class="label">#Model.BuildingLabel</td>
<td class="value">#Html.DevExpress().TextBoxFor(model => model.Building).GetHtml()</td>
<td class="validationError">#Html.ValidationMessageFor(model => model.Building)</td>
</tr>
...
<tr>
<td colspan="3">#Html.EditorFor(model => model.AmountModel, "Amounts")</td>
> </tr>
<tr>
<td colspan="3" class="validationError">#Html.ValidationMessageFor(model => model.AmountModel)</td>
</tr>
<tr />
</table>
</div>
<br />
<input type="submit" class="button" value="#Model.SaveButtonLabel" />
}
The partial View "Amounts" is as follows:
#model AmountModel
<table>
<tr>
<td class="label">#Model.AmountLabel</td>
<td class="value">
#Html.DevExpress().SpinEditFor(model => model.DenormalizedNetAmount,
settings =>
{
settings.Name = "DenormalizedNetAmount";
settings.Width = 153;
settings.Properties.DisplayFormatString = #"0.0,0";
settings.Number = 0;
}).GetHtml()
</td>
<td class="value">
#Html.DevExpress().ComboBoxFor(model => model.NetAmountUnit,
settings =>
{
settings.Name = "NetAmountUnit";
settings.Width = 60;
}).BindList(args => this.Model.AllUnits, args => this.Model.AllUnits).GetHtml()
</td>
</tr>
...
</table>
This is the AmountModel:
public class AmountModel
{
public decimal DenormalizedNetAmount { get; set; }
public string NetAmountUnit { get; set; }
...
public string AmountLabel
{
get { return i18n.StockItemDetailModel_AmountLabel; }
}
...
}
But the values of the input fields are not in the model in the Controller created by the model binder.
Why does the model binder not recognize the values in the editor template?
When I passed the FormCollection the values where correctly passed under the names "AmountModel.~"
public ActionResult EditDetails(FormCollection collection)
{
var netamount = collection["AmountModel.DenormalizedNetAmount"]; //correct value!
...
}
Do NOT specify the Name property when using the strong-typed (***For) helpers.
See the MVC Data Editors - Model Binding and Editing learning resource on the DevExpress forum.

View renders but doesn't update

Ive got a view that i pass a model to. I want it to render out a table out of a list in the model. It does that just fine it renders the view in that case that if i debugg it i can se the values goes to the right places. But the browser never updates. If i press ctrl+R in the browser it renders the view again in the exact same way but this time it show the list in the browser. Can i make this update everytime the view renders so that i don't have to press ctrl+R?
[HttpPost]
public ActionResult CreateResource(ViewModel view)
{
view.ResourceDateCreated = DateTime.Now;
viewmodel = view;
Session["ViewModel"]=viewmodel;
return View("Index", viewmodel);
}
The view:
<table class="table">
<tr>
<th>
MetaDataName
</th>
<th>
MetaDataDescription
</th>
<th>
LanguageCode
</th>
<th>
UserId
</th>
<th>
MetaDataDateCreated
</th>
#*<th>#Html.DisplayNameFor(model => model.MetaList)</th>*#
</tr>
#if (Model.Metadata.Count != 0)
{
foreach (var item in Model.Metadata)
{
<tr>
<td>
#item.MetaDataName
</td>
<td>
#item.MetaDataDescription
</td>
<td>
#item.LanguageCode
</td>
<td>
#item.UserId
</td>
<td>
#item.MetaDataDateCreated.ToString()
</td>
<td>
<table>
<tr>
<th>
MetaListId
</th>
</tr>
#if (item.MetaList.Count != 0)
{
foreach (var list in item.MetaList)
{
<tr>
<td>
#list.MetaListId
</td>
</tr>
}
}
</table>
</td>
</tr>
}
}
</table>

How to pass a list of objects to a [HTTPPost]controller parameter, in ASP.Net MVC?

i have the next view:
#model IEnumerable<L5ERP.Model.BLL.BusinessObjects.MTR_MonthlyTransfer>
#using (Html.BeginForm("ExpenseMonthlyTransferProcessing", "BudgetTransfer", Model.ToList())){
<table class ="divTable">
<tr>
<th>Transferir</th>
<th>
Clave
</th>
<th>
Monto
</th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.CheckBoxFor(x => item.MTR_Bool, new { #class = "checkMTR", #checked = "checked" })
</td>
<td>
#Html.TextBoxFor(x => item.MTR_Key, new {#class = "longInput" })
</td>
<td>
#String.Format("{0:F}", item.MTR_Amount)
</td>
</tr>
}
</table>
}
and my controller like this
[HttpPost]
public ActionResult ExpenseMonthlyTransferProcessing(List<MTR_MonthlyTransfer> lstMtr)
{ return View(lstMTR); }
But when i do the post my list is null, how can i send my list through the submit button ?
You should change the #model to an array (L5ERP.Model.BLL.BusinessObjects.MTR_MonthlyTransfer[]) or something else that implements IList<>:
#model L5ERP.Model.BLL.BusinessObjects.MTR_MonthlyTransfer[]
#for (var i = 0; i < Model.Length; i ++) {
<tr>
<td>
#Html.CheckBoxFor(x => Model[i].MTR_Bool, new { #class = "checkMTR", #checked = "checked" })
</td>
<td>
#Html.TextBoxFor(x => Model[i].MTR_Key, new {#class = "longInput" })
</td>
<td>
#String.Format("{0:F}", item.MTR_Amount)
</td>
</tr>
receive a FormCollection and parse the items in it manually
Use F12 to check the post in your navigator to see if it are sending the content you expected.

Resources