Pass table Object from view to controller using asp.net mvc - 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.

Related

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

C# MVC4 Partial View with other ActionResult in Controller

i have a problem.
I have my Controller "DashboardNB2Controller", my View "index.cshtml" and i want to integrate a partial view called "_PartialView.cshtml" in my "index.cshtml". Both Views are in the same folder. In my controller, i have the "ActionResult _PartialView" for a databaseoperation in my partial view.
But if I integrate my partial view in my index view, the action result "_PartialView" didn't work. I get no results. The query for my database is correct. I checked this.
Here are my codes
My Controller with the ActionResult for the Partial View
public ActionResult _PartialView()
{
var lastMessages= (from t in db.view_tbl_message
orderby t.Date descending
select t).Take(10);
ViewModelDashboard model = new ViewModelDashboard();
model.view_tbl_message = lastMessages.ToList();
return PartialView("_PartialView", model);
}
My index.cshtml
#model AisWebController.Areas.Statistics.Models.ViewModelDashboard
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<br />
#{Html.Action("_PartialView", "DashboardNB2");}
<br />
And my _PartialView.cshtml
#model WebApplication.Areas.Stats.Models.ViewModelDashboard
<table class="table table-bordered">
<tr>
<th>
Date
</th>
<th>
User
</th>
<th>
Message
</th>
</tr>
#foreach (var item in Model.view_tbl_message)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Date
</td>
<td>
#Html.DisplayFor(modelItem => item.User)
</td>
<td>
#Html.DisplayFor(modelItem => item.Message)
</td>
</tr>
}
</table>
If someone can help - that would be aweseome!
Change
#{Html.Action("_PartialView", "DashboardNB2");}
to
#Html.Action("_PartialView", "DashboardNB2")
You don't need {} brackets after you have # in view for Html extension methods
Look your #Html.DisplayFor it doesn't have any {} brackets.
Same applies for #Html.ActionLink

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

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.

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.

Reuse MVC View for both Display of Data and Editing of Data

I have two MVC views... one for displaying details and one for editing the values. They use almost identical templates with the exception that the DisplayFor is changed to the EditorFor when switching to the editor view. How can I reuse the my base layout structure in the view so that if I need to change the basic layout, I only have to do it in one location and not multiple views?
Here's a sample of the table used in the display view:
<table>
<tr>
<td class="label">First Name:</td>
<td class="field">#Html.DisplayFor(x => Model.FirstName)</td>
</tr>
<tr>
<td class="label">Last Name:</td>
<td class="field">#Html.DisplayFor(x => Model.LastName)</td>
</tr>
<tr>
<td class="label">Email:</td>
<td class="field">#Html.DisplayFor(x => Model.Email)</td>
</tr>
</table>
You could add a Mode property to your view model:
public bool IsInEditMode { get; set; }
Then, your controller can use the same view & model, just setting this property accordingly. Your view would end up like:
<table>
<tr>
<td class="label">First Name:</td>
<td class="field">
#if (!Model.IsInEditMode)
{
#Html.DisplayFor(x => Model.FirstName)
}
else
{
(render EditorFor plus any validation helpers)
}
</td>
</tr>
...etc...
</table>
Or you can use something cleaner for this job like Razor helper
public bool IsInEditMode { get; set; }
#helper EditorFor(System.Linq.Expressions.Expression<Func<ViewModel, string>> exp)
{
#((Model.IsInEditMode ) ? #Html.EditorFor(exp) : #Html.DisplayFor(exp))
}
Have a dynamic view that checks the ID of your entity. Razor is awesome ! if 0 or null it's a new entity, otherwise your in edit mode.
Razor Conditional!

Resources