ASP.NET MVC - Unable to bind form values to List<Model> - asp.net-mvc

I have this model
public class ItemClassification
{
public int ItemID {get; set;}
public string ItemName {get; set;}
}
and I have this form
<form method="POST" action="/Home/UpdateItemClassifications">
<table>
<tr>
<th>Item ID</th>
<th>Item Name</th>
</tr>
<tr>
<td>
<input name="ItemClassification[0].ItemID" value="1"/>
</td>
<td>
<input name="ItemClassification[0].ItemName" value="Item One"/>
</td>
</tr>
<tr>
<td>
<input name="ItemClassification[1].ItemID" value="2"/>
</td>
<td>
<input name="ItemClassification[1].ItemName" value="Item Two"/>
</td>
</tr>
<tr>
<td>
<input name="ItemClassification[2].ItemID" value="3"/>
</td>
<td>
<input name="ItemClassification[2].ItemName" value="Item Three"/>
</td>
</tr>
</table>
</form>
And I'm trying to bind these values to this controller action to loop through them and update them in the db.
[HttpPost]
public ActionResult UpdateItemClassifications(List<ItemClassification> UpdatedClassifications)
{
//save logic here..
}
For whatever reason I am not getting my posted form values bound to the ItemClassification model. Any help or direction would be appreciated. I have tried posting this form with only 1 set of values and removed the "List<>" from the controller and it mapped the values correctly.

Turns out I didn't need the "ItemClassification" before the [0].ItemID, thank you for the answer Sundeep. I may indeed need to look at the hacked article you referenced since I may be adding a JavaScript delete function to this and it will no doubt change my indexing.

Related

Pass table Object from view to controller using asp.net mvc

I am new to ASP.net MVC still in learning stage :) Thank you Advance
I have created the View Model to populate the table data based on the PName which I have selected.
Ex: for 1 project we have 10 related Items in , i am displaying all the rows on the screen, and making some updates to those rows to save it back to Database.
I am able to get the data but when I am trying to send the table object to controller to save, it always giving me null
Here is my ViewModel
namespace Application.ViewModel.Projects
{
public class PUpdates
{
public List<FItems> items{ get; set; }
}
}
CSHTML code
#using (Html.BeginForm("PFItems", "Projects", FormMethod.Post))
{
<table id="test">
<tr id="testtr">
<th id="testth"></th>
<th id="testth"></th>
</tr>
#foreach (var item in Model.FItems)
{
<tr id="testtr">
<td id="testtd">
#Html.Label(item.Ftype)
</td>
<td id="testtd">
#Html.TextBox("test", item.AC)
</td>
</tr>
}
<tr> <td><input type="submit" value="Submit" /></td></tr>
</table>
}
Controller Code
[HttpPost]
public PartialViewResult PFItems(PFUviewmodel)
{
return PartialView(viewmodel);
}
I am not able to get my table Object to make the update
Welcome to Stack overflow :)
For model binding to work you need to give you fields an index in the name property. Have a look at this question where I answered a very similar question and explained it.
In your case you need to do something like the following:
#model Application.ViewModel.Projects.ProjectfinanceUpdate
#using (Html.BeginForm("PartialprojectFinanceItem", "Projects", FormMethod.Post))
{
<table id="test">
<tr id="testtr">
<th id="testth">Financial Type</th>
<th id="testth">Actual Cost</th>
</tr>
#var i =0;
#foreach (var item in Model.tblFinanceItems)
{
<tr id="testtr">
<td id="testtd">
#Html.Label(item.FinancialType)
</td>
<td id="testtd">
<input name="ProjectfinanceUpdate.tblFinanceItems[#i].ActualCost" value="#item.ActualCost"/>
</td>
</tr>
#i++;
}
<tr> <td><input type="submit" value="Submit" /></td></tr>
</table>
}
The important part is that model binding works off of the name property, and because it's a list, it needs to have an index property.
Hope that helps.

Pass Table Value from View to Controller MVC

Can I pass table td values to controller?
View strongly typed:
#using (Html.BeginForm("PostClick", "Vendor", FormMethod.Post)) {
<table class="tblData">
<tr>
<th>
#Html.DisplayNameFor(model => model.First().SubmittedDate)
</th>
<th>
#Html.DisplayNameFor(model => model.First().StartDate)
</th>
</tr>
<tr>
<td>
#Html.DisplayFor(modelItem => item.SubmittedDate)
</td>
<td>
#Html.DisplayFor(modelItem => item.StartDate)
</td>
</tr>
</table>
<input type="submit" value="submit" />
}
Contoller code:
public void PostClick(FormCollection collection)
{
/*Some Code */
}
How to pass table value from view to controller?
Have used JasonData & Ajax call and able to send the table data to controller.
Want to know any other method can be done because FormCollection data not able to find table values
Your need to generate controls that post back (input, textarea or select) and generate those controls in a for loop (or use a custom EditorTemplate for type Vendor)
View
#model List<Vendor>
#using (Html.BeginForm())
{
<table class="tblData">
<thead>
....
</thead>
<tbody>
for(int i = 0; i < Model.Count; i++)
{
<tr>
<td>#Html.TextBoxFor(m => m[i].SubmittedDate)</td>
<td>#Html.TextBoxFor(m => m[i].StartDate)</td>
</tr>
}
</tbody>
</table>
<input type="submit" value="submit" />
}
Post method
public void PostClick(List<Vendor> model)
{
/*Some Code */
}

mvc form not posting table date

I am sure I am missing something very obvious, or I am not understanding what I have read so far. I have a from that contains a table of data, 2 fields of which need to be editable. The data received by the form is IEnumerable. However, when the controller function receiving the post data, instead of it receiving an IEnumerable, I get nothing. If I receive just the raw data type, I get the a single instance of the object with the correct id field and all other fields are empty. Could someone please point me oin the right direction?
MODEL: (Generated by EF Model first)
Partial Public Class QuoteBundlePackage_Result
Public Property id As Integer
Public Property employeeId As Nullable(Of Integer)
Public Property employeeName As String
Property bundleId As Nullable(Of Integer)
Public Property bundleDescription As String
Public Property packageId As Nullable(Of Integer)
Public Property packageContents As String
End Class
View:
#ModelType IEnumerable(Of gbip_new.QuoteBundlePackage_Result)
#Using Html.BeginForm()
#Html.ValidationSummary(True)
<fieldset>
<legend>Quote</legend>
<table>
<tr>
<th>
#Html.DisplayNameFor(Function(model) model.employeeId)
</th>
<th>
#Html.DisplayNameFor(Function(model) model.employeeName)
</th>
<th>
#Html.DisplayNameFor(Function(model) model.bundleId)
</th>
<th>
#Html.DisplayNameFor(Function(model) model.bundleDescription)
</th>
<th>
#Html.DisplayNameFor(Function(model) model.packageId)
</th>
<th>
#Html.DisplayNameFor(Function(model) model.packageContents)
</th>
<th></th>
</tr>
#For Each item In Model
Dim currentItem = item
Html.HiddenFor(Function(modelItem) currentItem.id)
#<tr>
<td>
#Html.DisplayFor(Function(modelItem) currentItem.employeeId)
</td>
<td>
#Html.DisplayFor(Function(modelItem) currentItem.employeeName)
</td>
<td>
#Html.EditorFor(Function(modelItem) currentItem.bundleId)
</td>
<td>
#Html.DisplayFor(Function(modelItem) currentItem.bundleDescription)
</td>
<td>
#Html.EditorFor(Function(modelItem) currentItem.packageId)
</td>
<td>
#Html.DisplayFor(Function(modelItem) currentItem.packageContents)
</td>
</tr>
Next
</table>
<p>
<input id="Submit1" type="submit" value="submit" />
</p>
</fieldset>
End Using
Controller
<HttpPost()> _
Function QuoteBundlePackage(ByVal eqDetails As IEnumerable(Of Global.gbip_new.QuoteBundlePackage_Result)) As ActionResult
If ModelState.IsValid Then
'Do stuff
Return RedirectToAction("Index")
End If
Return View(eqDetails)
End Function
Model binding to a collection works a little differently. You need to effectively number each item you are looping through if you want your collection to be bound correctly.
What you want to render is something like...
<input type="text" name="QuoteBundlePackage_Result[0].EmployeeID" value="" />
<input type="text" name="QuoteBundlePackage_Result[0].EmployeeName" value="" />
<input type="text" name="QuoteBundlePackage_Result[1].EmployeeID" value="" />
<input type="text" name="QuoteBundlePackage_Result[1].EmployeeName" value="" />
... which will allow the framework to distinguish between each item. To create this arrangement you should give each item an ID within your loop - (Sorry in advance for answer being in c# and not vb!)
#for (int i = 0; i < Model.Count(); i++)
{
#Html.EditorFor(e => e[i].EmployeeID)
#Html.EditorFor(e => e[i].EmployeeName)
}
See related articles from Scott Hansleman and Phil Haack.

How to Update Database on ButtonClick in ASP.NET MVC architecture

Hi i am looking to capture values from my view and update the entered values in to my database .
My view looks like following :
#using Kendo.Mvc.UI
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Facility</title>
</head>
<body>
<div>
<p>Create a new Facilty</p>
<table width="100px">
<tr>
<td>
<label for="TenantId">TenantID:</label>
</td>
<td>
<input id="TextTenantId" type="text" />
</td>
</tr>
<tr>
<td>
<label for="FacilityID">FacilityID:</label>
</td>
<td>
<input id="TextFacilityID" type="text" />
</td>
</tr>
<tr>
<td>
<label for="FacilityGroupID">FacilityGroupID:</label>
</td>
<td>
<input id="TextFacilityGroupID" type="text" />
</td>
</tr>
<tr>
<td>
<label for="FacilityName">FacilityName:</label>
</td>
<td>
<input id="TextFacilityName" type="text" />
</td>
</tr>
<tr>
<td>
<label for="FacilityAddressLine1">FacilityAddressLine1:</label>
</td>
<td>
<input id="TextFacilityAddressLine1" type="text" />
</td>
</tr>
<tr>
<td>
<label for="FacilityAddressLine2">FacilityAddressLine1:</label>
</td>
<td>
<input id="TextFacilityAddressLine2" type="text" />
</td>
</tr>
<tr>
<td>
<label for="FacilityAddressLine3">FacilityAddressLine1:</label>
</td>
<td>
<input id="TextFacilityAddressLine3" type="text" />
</td>
</tr>
<tr>
<td>
<label for="CityId">CityId:</label>
</td>
<td>
<input id="TextCityId" type="text" />
</td>
</tr>
<tr>
<td>
<label for="StateId">StateId:</label>
</td>
<td>
<input id="TextStateId" type="text" />
</td>
</tr>
<tr>
<td>
<label for="CountryId">CountryId:</label>
</td>
<td>
<input id="TextCountryId" type="text" />
</td>
</tr>
<tr>
<td>
<label for="Zipcode">Zipcode:</label>
</td>
<td>
<input id="TextZipcode" type="text" />
</td>
</tr>
<tr>
<td>
<label for="PhoneNo">PhoneNo:</label>
</td>
<td>
<input id="TextPhoneNo" type="text" />
</td>
</tr>
<tr>
<td>
<label for="Status">Status:</label>
</td>
<td>
<input id="TextStatus" type="text" />
</td>
</tr>
<tr>
<td>
<label for="EmailId">EmailId:</label>
</td>
<td>
<input id="TextEmailId" type="text" />
</td>
</tr>
<tr>
<td>
<label for="Website">Website:</label>
</td>
<td>
<input id="TextWebsite" type="text" />
</td>
</tr>
<tr>
<td>
<input id="Submit1" type="Submit" value="submit" />
</td>
</tr>
</table>
</div>
</body>
</html>
My model looks like :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace AmanoMockUp.Models
{
public class FacilityModels
{
public int TenantId { get; set; }
public int FacilityId { get; set; }
public int FacilityGroupId { get; set; }
public string FacilityName { get; set; }
public string FacilityAddressLine1 { get; set; }
public string FacilityAddressLine2 { get; set; }
public string FacilityAddressLine3 { get; set; }
public int CityId { get; set; }
public int StateId { get; set; }
public int CountryId { get; set; }
public string Zipcode { get; set; }
public int PhoneNo { get; set; }
public bool status { get; set; }
public string EmailId { get; set; }
public string Website { get; set; }
public DateTime CreationDate { get; set; }
}
}
now i need to update the values entered in the view in the various textfields onto my database on the submission of my button
<input id="Submit1" type="Submit" value="submit" />
Where should i write the buttonclick event should it be on the controller or the model or should i create a whole new controller for the same .Please help !!
I have searched but i couldnt find anything related to my issue .
Thanx in advance !!
How about having your view strongly typed against your model and having the form submit the values to an action method that does the work? do some searching on Html.BeginForm for pointers on having a form call a specific action on submission and just about any basic MVC tutorial for strongly typing a view to a model.
database calls should be in the controller.
in the controller create another action with the [HttpPost] attribute but with the same name. it will take the model as its parameter. then complete the database logic and save changes and return the view.
look at the example here
http://www.c-sharpcorner.com/UploadFile/krishnasarala/select-insert-update-and-delete-with-Asp-Net-mvc/

MVC update list items

Hi I have a view which displays Invoices and InvoiceLines.
#model VectorCheck.ViewModels.InvoiceViewModel
#{
ViewBag.Title = "Invoice Details";
}
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery-ui-1.8.11.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/EditorHookup.js")" type="text/javascript"></script>
#using (Html.BeginForm())
{
#Html.ValidationSummary()
<fieldset>
<legend>Invoice</legend>
<table>
<tr>
<th>
Activity ID
</th>
<th>
Invoice Line Amount
</th>
<th>
Payment Type
</th>
<th>
Note
</th>
<th>
</th>
<th>
</th>
<th>
</th>
</tr>
#foreach (var item in Model.InvoiceLines) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Activity.Descriptor)
</td>
<td>
#Html.DisplayFor(modelItem => item.Amount)
</td>
<td>
#Html.DisplayFor(modelItem => item.PaymentType.Name)
</td>
<td>
<span>Person:</span>
#Html.DropDownListFor(modelItem => item.PersonrId, Model.People as IDictionary<string, IEnumerable<SelectListItem>>, "--- Select ---")
</td>
<td>
<input type="submit" value="Update" />
</td>
</tr>
}
}
</table>
</fieldset>
}
What I'm wanting is for each InvoiceLine without going to another screen to be able to change the value in the dropdown list for Person, click update and get this updated InvoiceLine in the controller where I can save it.
However when I get to the controller the InvoiceLine does not contain the values.
Controller method:
[HttpPost]
public ActionResult EditInvoiceLine(InvoiceLine invoiceLine, int id)
{
return View(invoiceLine);
}
Has anyone achieve anything like this on the same page or knows how to do it?
No, I do not want to use jqgrid. I have other functionality which jqgrid isn't suitable for.
InvoiceLine is empty because the controller doesn't know where it's coming from. Also, where is the 'id' coming from? Shouldn't it be 'Personid'? Easiest technique in my opinion would be just to use ajax on the button click and send values using GET through querystrings.
I would use a form per line approach (with or without AJAX). Note this will be easier if you use a non-table-based layout. At a minimum, your submit button will need to share the same table element with the input that you want to post back. Further, you could probably get by with just the line id and the person id, instead of the whole model. Use the line id to fetch the entity from the db, then update the person id and save it. Remove the surrounding form and put a form inside each table element with the dropdown list (moving the submit button as well). Modify the signature of your action to match.
#foreach (var item in Model.InvoiceLines) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Activity.Descriptor)
</td>
<td>
#Html.DisplayFor(modelItem => item.Amount)
</td>
<td>
#Html.DisplayFor(modelItem => item.PaymentType.Name)
</td>
<td>
#using (Html.BeginForm("EditInvoiceLine", new { id => modelItem.InvoiceId } ))
{
<span>Person:</span>
#Html.DropDownListFor(modelItem => item.PersonrId, Model.People as IDictionary<string, IEnumerable<SelectListItem>>, "--- Select ---")
<input type="submit" value="Update" />
}
</td>
</tr>
}
[HttpPost]
public ActionResult EditInvoiceLine( int id, int personId )
{
var line = db.InvoiceLines.SingleOrDefault( id );
line.PersonId = personId;
db.SaveChanges();
return View( line ); // more more likely a model based on the line...
}

Resources