How to handle errors in Razor view engine? - asp.net-mvc

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>

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

Not showing partial view result inside table body in asp.net MVC

I have written code to implement search using ajax in asp.net MVC. I have written an action inside my controller (Admincontroller) using partial view which is supposed to fetch data. I want to display the partial view result inside table body in my Index page.
The search function is working fine, but it is not displaying the result inside table body with id "searchresult" (Inside Index page). instead of that it is giving result. I wanted the result from search in table format. now result is displayed like below in http://localhost:1274/Admin/Search.
2786 Mens L/S 4000
here is my Index.cshtml
#model IEnumerable<TestEntityFramework.Models.trProducts>
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_AdminLayout.cshtml";
AjaxOptions ajax = new AjaxOptions
{
UpdateTargetId = "searchresult",
Confirm = "Are you sure to start search?",
InsertionMode = InsertionMode.Replace,
LoadingElementId="Loadhere"
};
}
<h2>Index</h2>
<script src="~/scripts/jquery.unobtrusive-ajax.js"></script>
<script src="~/scripts/jquery.unobtrusive-ajax.min.js"></script>
<div class="panel-heading">
<div>
#Html.ActionLink("Create New", "Create",null, new{ #class="btn btn- primary" })
</div>
</div>
<div class="panel-body">
<table class="table table-striped table-bordered table-condensed table- hover table-responsive">
<tr>
<th>
#Html.DisplayNameFor(model => model.prod_type)
</th>
<th>
#Html.DisplayNameFor(model => model.prod_name)
</th>
<th>
#Html.DisplayNameFor(model => model.prod_desc)
</th>
<th>
#Html.DisplayNameFor(model => model.prod_price)
</th>
<th>
#Html.DisplayNameFor(model => model.prod_qty)
</th>
<th>
#Html.DisplayNameFor(model => model.prod_category)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.prod_type)
</td>
<td>
#Html.DisplayFor(modelItem => item.prod_name)
</td>
<td>
#Html.DisplayFor(modelItem => item.prod_desc)
</td>
<td>
#Html.DisplayFor(modelItem => item.prod_price)
</td>
<td>
#Html.DisplayFor(modelItem => item.prod_qty)
</td>
<td>
#Html.DisplayFor(modelItem => item.prod_category)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new {id=item.product_id}) |
#Html.ActionLink("Details", "Details", new { id=item.product_id }) |
#Html.ActionLink("Delete", "Delete", new { id=item.product_id })
</td>
</tr>
}
</table>
</div>
<div class="col-lg-8">
<table class="table table-bordered table-striped table-hover">
<thead>
<tr>
<th>
Product Id
</th>
<th>
Product Name
</th>
<th>
Price
</th>
<th>
</th>
</tr>
</thead>
<tbody id="searchresult">
#Html.Action("Search", new { pr_name = "" })
</tbody>
</table>
#using (Ajax.BeginForm("Search", ajax))
{
<div id="Loadhere">
#Html.TextBox("pr_name")
<button class="btn btn-primary">Search</button>
</div>
}
</div>
and my partialview Search.cshtml looks as below
#model IEnumerable<TestEntityFramework.Models.trProducts>
#foreach(var m in Model)
{
<tr>
<td>
#m.product_id
</td>
<td>
#m.prod_name
</td>
<td>
#m.prod_price
</td>
</tr>
}

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>

Getting Incorrect razor syntax errors

I have the following code and I want to put the table headers outside of the #foreach but when i move it outside It no longer sees the closing tag. Thanks
#foreach (var item in Model)
{
<div class="data" ><label for="fullName" >Name: </label>#item.UserName.Replace('.', '')</div>
if (Model.Count > 0)
{
<table class="data">
<tr>
<th>
Work Date
</th>
<th>
Change Details
</th>
<th>
Ip Address
</th>
<th></th>
</tr>
<tr>
<td>
#{
var stringDate = item.WorkDate.ToShortDateString();
}
#Html.DisplayFor(modelItem => stringDate)
</td>
<td>
#Html.DisplayFor(modelItem => item.ChangeDetail)
</td>
<td>
#Html.DisplayFor(modelItem => item.IpAddress)
</td>
</tr>
</table>
}
<br />
<hr />
}
So this is kinda what I'm trying to accomplish, but it keeps giving me errors no matter what way I try it.
<table class="data">
<tr>
<th>
Work Date
</th>
<th>
Change Details
</th>
<th>
Ip Address
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<div class="data" ><label for="fullName" >Name: </label>#item.UserName.Replace('.','')</div>
if (Model.Count > 0)
{
<tr>
<td>
#{
var stringDate = item.WorkDate.ToShortDateString();
}
#Html.DisplayFor(modelItem => stringDate)
</td>
<td>
#Html.DisplayFor(modelItem => item.ChangeDetail)
</td>
<td>
#Html.DisplayFor(modelItem => item.IpAddress)
</td>
</tr>
</table>
}
<br />
<hr />
}
You must have your table closing tag outside of the for each loop.
Short answer: the closing tag </table> has to be placed outside of the foreach loop.
Long answer: You should put the Model.Count > 0 outside of the foreach loop because the moment you enter the code block within the loop, Model.Count > 0 always evaluates to true because you have at least one item.
If – and only if – your model contains any items, you print out the table header. After that, you append one row for each item in Model. Both <table> and </table> have to occur within the same level of nesting.
#if (Model.Count > 0)
{
<table class="data">
<tr>
<th>Date</th>
<th>Change Details</th>
<th>Ip Address</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<div class="data" >
<label for="fullName" >Name: </label>
#item.UserName.Replace('.', ' ')
</div>
#{
var stringDate = item.WorkDate.ToShortDateString();
}
<tr>
<td>#Html.DisplayFor(modelItem => stringDate)</td>
<td>#Html.DisplayFor(modelItem => item.ChangeDetail)</td>
<td>#Html.DisplayFor(modelItem => item.IpAddress)</td>
</tr>
}
</table>
<br />
<hr />
}
You should consider moving the logic (#item.UserName.Replace('.', ' ')) out of the view into the corresponding controller action.

How can I insert mulitple rows in table at once in MVC asp .net?

I am new at MVC asp .net.
I have a grid in which I am adding rows.
Now I want to perform mulitple rows insertion in a table at once.
How can I do that. SO multiple rows will be added in MVC.
Any help would be appericiated.
You want to learn how to ModelBind to a Collection. There are many answers here already for this technique.
https://stackoverflow.com/search?q=model+binding+to+a+collection
http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx
Do you mean something like this?.
<table class="table" style="vertical-align: middle;">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.title)
</th>
<th style="text-align: center;">
#Html.DisplayNameFor(model => model.imgAr)
</th>
<th>
#Html.DisplayNameFor(model => model.created)
</th>
<th></th>
</tr>
</thead>
<tbody id="tblOfContent">
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.title)
</td>
<td style="text-align: center;">
<img src="~/newsImages/#item.imgAr" class="img-thumbnail" />
</td>
<td>
#item.created.ToShortDateString()
</td>
<td>
#Html.ActionLink("Details", "Edit", new { id = item.id }) |
#Html.ActionLink("Details", "Details", new { id = item.id })
</td>
</tr>
}
</tbody>
</table>
and in the Controller something like this:
public ActionResult Index()
{
return View(newsService.GetAll().OrderByDescending(x => x.created));
}

Resources