Partial View linkage to controller and model [duplicate] - asp.net-mvc

This question already has answers here:
#Html.Action in Asp.Net Core
(10 answers)
Closed 6 years ago.
I am new to .Net and MVC and I seem to hit a problem that I can´t fix. I am trying to follow a couple of tutorials but I have failed when it comes to partial views. I looked up a lot of answers here and on different websites and still nothing works. I can´t figure out what I am doing wrong.
This is my partial controller:
public class PartialController : Controller
{
public ActionResult _PartialView()
{
var model = new Partial();
model.Count = 2;
return PartialView(model);
}
}
And this is my Partial View:
#model WebApplication1Tutorial.Models.Partial
<div>
The magic number is:
#Html.DisplayFor(model => model.Count)
</div>
I call this view in Index.cshtml by the following command:
<div>
#Html.Partial("/Views/Partial/_PartView.cshtml",new Partial())
</div>
And finally this is the model:
public class Partial
{
public int Count { get; set; }
}
Everything that I tried comes up with the webpage displaying the text and the number 0. I really have no idea what else to do. I know it is something easy but I can´t see it.
Thanks for the help.
Edit. The code for the index view:
#model MovieGenreViewModel
#{
ViewData["Title"] = "Index";
}
<h2>Index</h2>
<p>
<a asp-action="Create">Create New</a>
</p>
<form asp-controller="Movies" asp-action="Index" method="get">
<p>
<select asp-for="movieGenre" asp-items="Model.genres">
<option value="">All</option>
</select>
Title: <input type="text" name="SearchString" >
<input type="submit" value="Filter" />
</p>
</form>
<table class="table">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.movies[0].Genre)
</th>
<th>
#Html.DisplayNameFor(model => model.movies[0].Price)
</th>
<th>
#Html.DisplayNameFor(model => model.movies[0].ReleaseDate)
</th>
<th>
#Html.DisplayNameFor(model => model.movies[0].Title)
</th>
<th>
#Html.DisplayNameFor(model => model.movies[0].Rating)
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.movies) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Genre)
</td>
<td>
#Html.DisplayFor(modelItem => item.Price)
</td>
<td>
#Html.DisplayFor(modelItem => item.ReleaseDate)
</td>
<td>
#Html.DisplayFor(modelItem => item.Title)
</td>
<td>
#Html.DisplayFor(modelItem => item.Rating)
</td>
<td>
<a asp-action="Edit" asp-route-id="#item.ID">Edit</a> |
<a asp-action="Details" asp-route-id="#item.ID">Details</a> |
<a asp-action="Delete" asp-route-id="#item.ID">Delete</a>
</td>
</tr>
}
</tbody>
</table>
<div>
#{ Html.RenderAction("_PartialView"); }
</div>

When you pass your partial like with the #Html.Partial, you also pass a new Model and the _PartialView() method is not invoked so the model is not populated with the value 2.
You could use #Html.Action helper:
<div>
#Html.Action("/Views/Partial/_PartView.cshtml")
</div>

Related

Is there a way I can add and bind checkboxes to my MVC Table

I am trying to add a checkbox so I can selects a row from my list and from there use that row to generate a letter.
I was wondering how I would be able to add a checkbox and bind it to the data I have tried a few ways using something similar to:
checkbox(m => m[i].Lesson)
However it would never accept the i in brackets and come up with an error. below is the layout of my index for the lessons model currently.
Here is the Lessons Index:
#model IEnumerable<FinalMusicApp.Models.Lesson>
#{
ViewBag.Title = "Index";
}
<h2>Lessons</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
#using (Html.BeginForm("Index", "Students", FormMethod.Get))
{
//Search options
<b>Search Options: </b> #Html.RadioButton("Option", "Instrument")<text>Instrument</text>#Html.RadioButton("Option", "Tutor")<text>Tutor</text>#Html.RadioButton("Option", "Term")<text>Term</text>#Html.TextBox("Search")
<input type="submit" name="submit" value="Search" />
}
<form method="post">
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.IsChecked)
</th>
<th>
#Html.DisplayNameFor(model => model.LessonDate)
</th>
<th>
#Html.DisplayNameFor(model => model.LessonTime)
</th>
<th>
#Html.DisplayNameFor(model => model.Duration.TimeTaken)
</th>
<th>
#Html.DisplayNameFor(model => model.Instrument.InstrumentName)
</th>
<th>
#Html.DisplayNameFor(model => model.Letter.Paid)
</th>
<th>
#Html.DisplayNameFor(model => model.Student.FullName)
</th>
<th>
#Html.DisplayNameFor(model => model.Tutor.TutorName)
</th>
<th>
CRUD
</th>
<th>
Make a letter
</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.CheckBoxFor(modelItem => item.IsChecked)
</td>
<td>
#Html.DisplayFor(modelItem => item.LessonDate)
</td>
<td>
#Html.DisplayFor(modelItem => item.LessonTime)
</td>
<td>
#Html.DisplayFor(modelItem => item.Duration.TimeTaken)
</td>
<td>
#Html.DisplayFor(modelItem => item.Instrument.InstrumentName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Letter.Paid)
</td>
<td>
#Html.DisplayFor(modelItem => item.Student.FullName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Tutor.TutorName)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.LessonId }) |
#Html.ActionLink("Details", "Details", new { id = item.LessonId }) |
#Html.ActionLink("Delete", "Delete", new { id = item.LessonId })
</td>
<td>
#Html.ActionLink("Generate Letter", "Create", "Letters")
</td>
</tr>
}
</table>
</form>
I am trying to add a checkbox so I can selects a row from my list
Do you want something like below?
In the view add a checkbox, for example I use the property CourseName in my model instead, you can use your property:
#Html.CheckBox("CourseName", new { value = item.CourseName })
#Html.DisplayFor(modelItem => item.CourseName)
Then in the controller, we can get CourseName value, and get other property value accord to the CourseName, but we need load the list again, we cannot send the full list from view to controller :
var courserow = model.FirstOrDefault(m => m.CourseName == CourseName);
result:

How to render a table from a view in the footer section of _Layout view?

I am developing a solution to enter project-split times in the fullcalendar jquery application. A SQL view shows incomplete days (where entered time is not equal to 8 hours) and renders the table from the entity model in the Generate view:
#model IEnumerable<support_tickets.Models.DailyHours>
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Generate</title>
</head>
<body>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.Start)
</th>
<th>
#Html.DisplayNameFor(model => model.Week)
</th>
<th>
#Html.DisplayNameFor(model => model.Hours)
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Start)
</td>
<td>
#Html.DisplayFor(modelItem => item.Week)
</td>
<td>
#Html.DisplayFor(modelItem => item.Hours)
</td>
</tr>
}
</table>
</body>
</html>
I'd like to render the same table in the footer section of the _Layout view, to see everything on one page. Any assistance is greatly appreciated. Thanks
This is what worked for me - creating a partial view from the PartialViewResult action.
In Controller:
public PartialViewResult IncompleteDays()
{
ticketsEntities entities = new ticketsEntities();
var ent = entities.DailyHours.ToList();
return PartialView(ent);
}
Create a partial View from the action, with the table:
#model IEnumerable<support_tickets.Models.DailyHours>
<div class="row justify-content-center">
<div class="col-auto">
<table class="table table-striped">
<tr>
<th>
#Html.DisplayNameFor(model => model.Start)
</th>
<th>
#Html.DisplayNameFor(model => model.Week)
</th>
<th>
#Html.DisplayNameFor(model => model.Hours)
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Convert.ToDateTime(item.Start).ToString("MM-dd-yyyy")
</td>
<td>
#Html.DisplayFor(modelItem => item.Week)
</td>
<td>
#Html.DisplayFor(modelItem => item.Hours)
</td>
</tr>
}
</table>
</div>
</div>
And then call the action from the footer section of the _Layout view:
#{ Html.RenderAction("IncompleteDays", "Home");}

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>
}

All model and Formcollection values are null, blank or don't exist in Firefox or Chrome

During debugging, my MVC model and Formcollection are blank with no values in FireFox (15) or Chrome (latest version).
During debugging using IE (9), I can see these values just fine.
Do you know what the solution is for this? This is very serious for public facing web sites not being able to do any programming angainst these browsers.
Here is my View...
#model PDFConverterModel.ViewModels.ViewModelTemplate_Guarantors
#{
ViewBag.Title = "BHG :: PDF Generator";
}
<h2>#ViewBag.Message</h2>
<div>
<table style="width: 1000px">
<tr>
<td colspan="5">
<img alt="BHG Logo" src="~/Images/logo.gif" />
</td>
</tr>
#using (Html.BeginForm("ProcessForm", "Home", FormMethod.Post))
{
<tr>
<td>
#(Html.Kendo().IntegerTextBox()
.Name("LoanID")
.Placeholder("Enter Loan ID")
)
</tr>
<tr>
<td>#Html.LabelFor(model => model.LoanType)
#Html.DisplayFor(model => model.LoanType)
</td>
<td>
<label for="ddlDept">Department:</label>
#(Html.Kendo().DropDownList()
.Name("ddlDept")
.DataTextField("DepartmentName")
.DataValueField("DepartmentID")
.Events(e => e.Change("Refresh"))
.DataSource(source =>
{
source.Read(read =>
{
read.Action("GetDepartments", "Home");
});
})
)
</td>
</tr>
if (Model.ShowGeneratePDFBtn == true)
{
if (Model.ErrorT == string.Empty)
{
<tr>
<td colspan="5">
<u><b>#Html.Label("Templates:")</b></u>
</td>
</tr>
<tr>
#for (int i = 0; i < Model.Templates.Count; i++)
{
<td>
#Html.CheckBoxFor(model => Model.Templates[i].IsChecked)
#Html.DisplayFor(model => Model.Templates[i].TemplateId)
</td>
}
</tr>
}
else
{
<tr>
<td>
<b>#Html.DisplayFor(model => Model.ErrorT)</b>
</td>
</tr>
}
if (Model.ErrorG == string.Empty)
{
<tr>
<td colspan="5">
<u><b>#Html.Label("Guarantors:")</b></u>
</td>
</tr>
<tr>
#for (int i = 0; i < Model.Guarantors.Count; i++)
{
<td>
#Html.CheckBoxFor(model => Model.Guarantors[i].isChecked)
#Html.DisplayFor(model => Model.Guarantors[i].GuarantorFirstName) #Html.DisplayFor(model => Model.Guarantors[i].GuarantorLastName)
</td>
}
</tr>
}
else
{
<tr>
<td>
<b>#Html.DisplayFor(model => Model.ErrorG)</b>
</td>
</tr>
}
}
<tr>
<td colspan="3">
<input type="submit" name="submitbutton" id="btnRefresh" value='Refresh' />
</td>
#if (Model.ShowGeneratePDFBtn == true)
{
<td>
<input type="submit" name="submitbutton" id="btnGeneratePDF" value='Generate PDF' />
</td>
}
</tr>
<tr>
<td colspan="5">
#Model.Error
</td>
</tr>
}
</table>
</div>
<script type="text/javascript">
$('btnRefresh').on('click', '#btnRefresh', function () {
Refresh();
});
function Refresh() {
var LoanID = $("#LoanID").val();
if (LoanID != "") {
document.forms[0].submit();
}
else {
alert("Please enter a LoanId");
}
}
</script>
I know this is a very old question, but answering this might help people like who are struggling with this issue.
I had a similar issue. The problem lies here:
<table style="width: 1000px">
<tr>
<td colspan="5">
<img alt="BHG Logo" src="~/Images/logo.gif" />
</td>
</tr>
#using (Html.BeginForm("ProcessForm", "Home", FormMethod.Post))
{
<tr>
<td>
#(Html.Kendo().IntegerTextBox()
.Name("LoanID")
.Placeholder("Enter Loan ID")
)
</td>
</tr>
}
</table>
After begin form there are <tr> tags directly! Browsers like chrome and mozilla get confused in such cases. The <table> tag should be inside the form. If we look at your code, which was exactly what I had done, <table> tag was before #using Html.BeginForm.
Internet Explorer somehow understands this, but the other browsers don't.
When I did an inspect element I found that there was a form tag within each <tr> tag and it always returned FormCollection as null. Simply defining <table> within form solved my problem.
So here's how it should be:
<table style="width: 1000px">
<tr>
<td colspan="5">
<img alt="BHG Logo" src="~/Images/logo.gif" />
</td>
</tr>
<tr><td>
#using (Html.BeginForm("ProcessForm", "Home", FormMethod.Post))
{
<table>
<tr>
<td>
#(Html.Kendo().IntegerTextBox()
.Name("LoanID")
.Placeholder("Enter Loan ID")
)
</td>
</tr>
</table>
}
</td></tr>
</table>
I just found out what the issue is by experimneting.
The Telerik MVC widgets don't emit any FormCollection data!!!!
Only EditorFor and TextBoxFor emit these values, plus the input buttons.
What good are these widgets if I can't use the FormCollection values from them???? Especially the DropDownList where I can retrireve data and need the selected value to pass onto other methods.
(This would be better suited as comment, but I can't comment yet)
For future reference, here's a spec (W3C might have something different) for what gets submitted when a form is submitted:
http://www.whatwg.org/specs/web-apps/current-work/multipage/forms.html#category-submit
You can look at whatever HTML was generated to make sure it gets submitted. You could also use something like Fiddler to look at the Http request

Resources