MVC, Normal partial view and List partial view. not working together!!! S.O.S. xD - asp.net-mvc

I have a view that contains 2 partial views.
#model ListViewModel
....
#{
Html.RenderPartial("EditCartItemsPartical");
Html.RenderPartial("ShowProductINFO", Model.Products);
}
and I just want to create a from with the first partial, and a list with the second.
The partial views
EditCartItemsPartical.cshtml
#model TestNewATM3._0.Models.CartItem
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<div class="form-group">
#Html.LabelFor(model => model.CartId, "CartId", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.CartId, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.CartId, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ProductId, "ProductId", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.ProductId, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.ProductId, "", new { #class = "text-danger" })
</div>
</div>
.... // more control for CartItem
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
ShowProductINFO.cshtml
#model IEnumerable<TestNewATM3._0.Models.AllProduct2>
<p>#Html.ActionLink("Create New", "Create")</p>
<table class="table">
<tr>
<th>ID</th>
<th>#Html.DisplayNameFor(model => model.Title)</th>
</tr>
#foreach (var item in Model) {
<tr>
<td>#Html.DisplayFor(model => item.Id)</td>
<td>#Html.DisplayFor(modelItem => item.Title)</td>
</tr>
}
</table>
And in my controller I got this.
public ActionResult Edit()
{
var db = ApplicationDbContext.Create();
var list = new ListViewModel
{
Products = db.AllProduct2s.ToList(),
Users = db.Users.ToList(),
Cart = db.Carts.ToList(),
CartItem = db.CartItems.ToList()
};
return View(list);
}
But the problem is that I cant show both partial at the same time because if I send the list in my view, then my first partial gets a problem cause it want a #model TestNewATM3.0.Models.CartItem. but if I don't sent the list My list wont show because I don't send it.
So how do i show a normal partial form view and a List partial view at the same time?

I'm having a little difficulty understanding your examples (i.e you have an edit view with create buttons), it looks like your trying to create a view to edit the cart.
Note: I would suggest renaming the CartItem property of your model to CartItems for clarity, but I'll use the current property names for the examples below.
You could render the partial view for each of the items in the list like so,
but this approach more is more than a little messy:
foreach(var cartItem in Models.CartItem){
Html.RenderPartial("EditCartItemsPartical", cartItem);
}
A simpler and more performant approach would be to edit the first view so it takes a collection of cart items
Like so
#model IEnumerable<TestNewATM3._0.Models.CartItem>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#foreach(var modelItem in Model.CartItem){
<h4>CartItem</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => modelItem.CartId, "CartId", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => modelItem.CartId, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => modelItem.CartId, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ProductId, "ProductId", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => modelItem.ProductId, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => modelItem.ProductId, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Aantal, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => modelItem.Aantal, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => modelItem.Aantal, "", new { #class = "text-danger" })
</div>
</div>
}
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
Of course this will require you to change the server side code to receive a collection of cart items, but from the user's perspective not having to post a form back multiple times, to complete your changes is going to result in a better experience.
disclaimer: I changed the above view in notepad, might need to adjust a bit before it works perfectly
I hope this helps.

Related

Creating an edit modal in ASP.NET - MVC

I have Index.cshtml with the code below
#model IEnumerable<Demo.Models.RequestList>
....
#foreach (var item in Model)
{
<td>#Html.DisplayFor(modelItem => item.Name)</td>
...
<a class="dropdown-item" onclick="edit(#item.ID)" href="#Url.Action("Edit", "Home", new { id = item.ID })">Edit</a>
}
It mean, I get data from DB and show on the table. Each row of the table I create a button for edit.
When I click Edit button, it will href="#Url.Action("Edit", "Home", new { id = item.ID })
But now, I want create Edit modal or a #html.partial on the Modal instead of href to a new page. How can I do that?
It is my Edit code.
#model Demo.Models.RequestList
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>RequestList</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.ID)
<div class="form-group">
#Html.LabelFor(model => model.Code, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Code, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Code, "", new { #class = "text-danger" })
</div>
</div>
....
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>

ASP.Net MVC: Partial view not rendering

i am bit new in asp.net mvc. i am facing problem for very basic things that my Partial view not rendering. here is the details
i have a main page and one partial view
main page action look like
public ActionResult Index()
{
return View();
}
main index view look like
#model Testing.Models.Employee
#{
ViewBag.Title = "Home Page";
}
<div class="row">
</div>
<div class="row">
<div id="formsIndex">
#{
Html.Partial("_TestForm");
}
</div>
</div>
#section scripts {
<script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
}
here i am showing a partial view like this way Html.Partial("_TestForm"); but no UI comes for partial view.
partial view code look like
#model Testing.Models.Employee
#using (Ajax.BeginForm("Index", "Home", new AjaxOptions { HttpMethod = "POST", UpdateTargetId = "formsIndex" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Name, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Name, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Name, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.City, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.City, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.City, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Address, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Address, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Address, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</div>
</div>
}
when i pass model to partial view this way Html.Partial("_TestForm", Model); then also no UI comes.
please tell me where i made the mistake ?
use in method return PartialView() and try this
#Html.Partial("_TestForm");
Using Html.Partial inside a #{ ... } block will just call the method and throw the result away.
You should call it outside of a #{ ... } block, prefixed with #, and remember to pass in the model:
<div id="formsIndex">
#Html.Partial("_TestForm", Model);
</div>
Render like this
#Html.Action("_Partialview", "controllerName")
also create action methode of partial view
public ActionResult _Partialview
{
Employee _objModel= new Employee ()
return PartialView(_objModel);
}

Model is invalid despite values are correct, strange behaviour [duplicate]

I cannot figure out why my view only passes back a NULL for a model to my controller.
This is for an Edit Post method. I checked other controllers with Edit Post methods that are structured the same way as this one and they work fine. It seems to be just this view and controller.
Here is my view:
#model Non_P21_Quote_System_v1._0.Models.gl_code
#{
ViewBag.Title = "Edit";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Edit</h2>
#if (TempData["Message"] != null)
{
<div style="color:green">
#TempData["Message"]
</div><br />
}
#if (ViewBag.error != null)
{
<div style="color:red">
<h3>#ViewBag.error</h3>
</div><br />
}
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>gl_code</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.ID)
<div class="form-group">
#Html.LabelFor(model => model.GL_code, "GL Code", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.GL_code, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.GL_code, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.GL_description, "Gl Description", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.GL_description, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.GL_description, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.expense_type_ID, "Expense", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("expense_type_ID", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.expense_type_ID, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.eag, "Employee Account Group", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("eag", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.eag, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "gl_Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
Here is my controller method:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit([Bind(Include = "ID,GL_code,GL_description,expense_type_ID,eag")] gl_code gl_code)
{
if (ModelState.IsValid)
{
db.Entry(gl_code).State = EntityState.Modified;
await db.SaveChangesAsync();
return RedirectToAction("gl_Index");
}
ViewBag.eag = new SelectList(db.employee_account_group, "ID", "eag_name");
ViewBag.expense_type_ID = new SelectList(db.expense_type, "ID", "type", gl_code.expense_type_ID);
return View(gl_code);
}
When I debug it, I see the model being passed in is of value NULL. I am seeing this on the controller side at the the parameters part of the Edit method.
Its null because your model contains a property named gl_code and you have also named the parameter for your model gl_code in the POST method.
Change the name of one or the other and the model will bind correctly.
What is happening internally is that the form submits a name/value pair for each successful form control, in your case gl_code=someValue. The DefaultModelBinder first initializes a new instance of your model. It then reads the form values and finds a match for the property in your model and sets it to someValue. But it also finds a match in the method parameters and tries set the value of the parameter to someValue, which fails (because you cannot do gl_code gl_code = "someValue";) and the model becomes null.
It appears you have a property on your view model called gl_code. In your controller, you also refer to the view model as gl_code.
Try changing this.
public async Task<ActionResult> Edit(gl_code gl_code)
To
public async Task<ActionResult> Edit(gl_code model)

Asp.Net MVC: Why is my view passing NULL models back to my controller?

I cannot figure out why my view only passes back a NULL for a model to my controller.
This is for an Edit Post method. I checked other controllers with Edit Post methods that are structured the same way as this one and they work fine. It seems to be just this view and controller.
Here is my view:
#model Non_P21_Quote_System_v1._0.Models.gl_code
#{
ViewBag.Title = "Edit";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Edit</h2>
#if (TempData["Message"] != null)
{
<div style="color:green">
#TempData["Message"]
</div><br />
}
#if (ViewBag.error != null)
{
<div style="color:red">
<h3>#ViewBag.error</h3>
</div><br />
}
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>gl_code</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.ID)
<div class="form-group">
#Html.LabelFor(model => model.GL_code, "GL Code", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.GL_code, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.GL_code, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.GL_description, "Gl Description", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.GL_description, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.GL_description, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.expense_type_ID, "Expense", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("expense_type_ID", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.expense_type_ID, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.eag, "Employee Account Group", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("eag", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.eag, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "gl_Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
Here is my controller method:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit([Bind(Include = "ID,GL_code,GL_description,expense_type_ID,eag")] gl_code gl_code)
{
if (ModelState.IsValid)
{
db.Entry(gl_code).State = EntityState.Modified;
await db.SaveChangesAsync();
return RedirectToAction("gl_Index");
}
ViewBag.eag = new SelectList(db.employee_account_group, "ID", "eag_name");
ViewBag.expense_type_ID = new SelectList(db.expense_type, "ID", "type", gl_code.expense_type_ID);
return View(gl_code);
}
When I debug it, I see the model being passed in is of value NULL. I am seeing this on the controller side at the the parameters part of the Edit method.
Its null because your model contains a property named gl_code and you have also named the parameter for your model gl_code in the POST method.
Change the name of one or the other and the model will bind correctly.
What is happening internally is that the form submits a name/value pair for each successful form control, in your case gl_code=someValue. The DefaultModelBinder first initializes a new instance of your model. It then reads the form values and finds a match for the property in your model and sets it to someValue. But it also finds a match in the method parameters and tries set the value of the parameter to someValue, which fails (because you cannot do gl_code gl_code = "someValue";) and the model becomes null.
It appears you have a property on your view model called gl_code. In your controller, you also refer to the view model as gl_code.
Try changing this.
public async Task<ActionResult> Edit(gl_code gl_code)
To
public async Task<ActionResult> Edit(gl_code model)

How to reference multiple models in same MVC view [duplicate]

This question already has answers here:
how to create a view with multiple models mvc 4?
(2 answers)
Closed 7 years ago.
I've been trying to dissect an automated MVC view & controller, and modify it so that i can insert information from a form in the view, on to two separate database tables (Entity framework database first).
here's what i have so far. it works if i reference either of the namespaces at the top on their own, but not together?
#model manage.mysite.DataModels.Property_Type
#model manage.mysite.DataModels.Room_Type
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
#using (Html.BeginForm())
{
<div class="form-horizontal">
<h4>Property_Type</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.PropertyType, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.PropertyType, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.PropertyType, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.RoomType, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.RoomType, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.RoomType, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
It is not possible to reference several models in a View.
However, you can create composite model, which has the two other models as properties.
As such:
using manage.mysite.DataModels;
namespace manage.mysite.ViewModels
{
public class FooViewModel
{
public Property_Type PropertyType { get; set; }
public Room_Type RoomType { get; set; }
}
}
And then serve this model instead.
#model manage.mysite.ViewModels.FooViewModel
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
#using (Html.BeginForm())
{
<div class="form-horizontal">
<h4>Property_Type</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.PropertyType.PropertyType, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.PropertyType.PropertyType, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.PropertyType.PropertyType, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.RoomType.RoomType, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.RoomType.RoomType, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.RoomType.RoomType, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
See also:
MVC Multiple Models in One View
how to create a view with multiple models mvc 4?
Which is the best way to use multiple models with sames properties and using a unique view?

Resources