BindingNested List Property to Send to MVC Controller - asp.net-mvc

I have a view where I need to be able to select an item from a dropdown list and add it cumulatively to a list to display. The only way I've been able to think to do this so far is to have a Property which binds to the Dropdownlist, send this back with the cumulative list and have the server add to the List and send it back for display. This works well for the first item because the list to be added to has a Count of 0. Any subsequent additions will cause the controller binding to wipe the List.
Here are the important parts of my code:
Model:
public class CaseAppealViewModel
{
//needs to accumulate records as I add them and retain between server calls
public List<CaseFile> SelectedCases
{
get { return _selectedCases; }
set { _selectedCases = value; }
}
private List<CaseFile> _selectedCases = new List<CaseFile>();
public Nullable<int> ChosenCase { get; set; }
}
View:
#model MySystem.Models.CaseAppealViewModel
#using (Html.BeginForm("AddCase", "AppealLogs", Model))
{
<div class="col-md-6">
#Html.DisplayName("Cases:")
#Html.DropDownListFor(model => model.ChosenCase, CaseAppealViewModel.CaseDropDownList, "", new {#class = "form-control"})
#Html.HiddenFor(model => model.SelectedCases)
#Html.HiddenFor(model => model.Appeals)
</div>
<div class="col-md-6">
<input type="submit" id="AddCase" value="Add"/>
</div>
}
Controller:
public ActionResult AddCase(CaseAppealViewModel cavm)
{
var tempCase = db.CaseFiles.Find(cavm.ChosenCase);
if (tempCase != null)
{
cavm.SelectedCases.Add(db.CaseFiles.Find(cavm.ChosenCase));
}
return View("Details", cavm);
}
Is there a way I can send the SelectedCases List back and forth from the view to the controller without the Count resetting to 0?

Related

Fetching and Adding Checkbox dynamically on selection of Dropdown boxes

I have a form as above. I am trying to work as when user selects Table Name & Permission, it goes back to server side, fetches the columns of the selected table & display all column names as check boxes. When use selects Save btn, HttpPost will execute and when user selects Cancel, to return back to home page.
I have created a ViewModel for this :
// Actual EF Model
public partial class TablePermission
{
public int Id { get; set; }
public int UserId { get; set; }
public int PermissionLevelId { get; set; }
public string TableName { get; set; }
public string RestrictViewFields { get; set; }
public string RestrictEditFields { get; set; }
public virtual PermissionLevel PermissionLevel { get; set; }
public virtual User User { get; set; }
}
// View Model for the View
public class TablePermissionsVM
{
public TablePermissionsVM()
{
TablePermission = new TablePermission();
RestrictViewFields = new List<FieldList>();
// Created for trial to see Checkboxes
RestrictViewFields.Add(new FieldList() { FieldName = "UserId", Selected = false });
RestrictViewFields.Add(new FieldList() { FieldName = "fName", Selected = false });
RestrictViewFields.Add(new FieldList() { FieldName = "lName", Selected = false });
RestrictEditFields = new List<FieldList>();
}
public TablePermission TablePermission { get; set; }
public List<FieldList> RestrictViewFields { get; set; }
public IEnumerable<FieldList> RestrictEditFields { get; set; }
}
// Model to save field names & it's selected status
public class FieldList
{
public string FieldName { get; set; }
public bool Selected { get; set; }
}
}
Controller UPDATED : ADDED THE NEW ACTION (FillFields() ) METHOD that has to called onChange event
[Authorize]
[HttpGet]
public ActionResult TablePermissions(TablePermissionsVM tablePermissionVm)
{
return View(tablePermissionVm);
}
// Action Method to Fill Column names for the List<>.
public ActionResult FillFields(string tableName, string tblPermLevel)
{
// WANT TO RETURN HERE ANOTHER LIST (2 LIST OBJECTS) IN JSON
// restrictView & restrictEdit
var restrictView = DbUtilities.GetColumnNames(tableName);
var restrictEdit = DbUtilities.GetColumnNames(tableName);
return Json(restrictView, JsonRequestBehavior.AllowGet);
}
View - UPDATED CODE : aDDED Bound fields for TableName & TableLevelPermission, Script that I use on the event of change of Table Selected.
UPDATED - aDDED FORM ID, SCRIPT METHOD
#model DataStudio.Models.TablePermissionsVM
using (Html.BeginForm("TablePermissions", "Admin", FormMethod.Post, new { id = "tblPermForm" }) ))
{
#Html.AntiForgeryToken()
<div class="form-group">
#Html.LabelFor(model => model.TablePermission.TableName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="editor-field">
#Html.DropDownListFor(model => model.TablePermission.TableName,
DbUtilities.GetTableNames(), "Select Table",
new { #class = "form-control", #onchange="FillFields()" })
#Html.ValidationMessageFor(model => model.TablePermission.TableName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.TablePermission.PermissionLevelId, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="editor-field">
#Html.DropDownListFor(model => model.TablePermission.PermissionLevelId, DbUtilities.GetPermissionLevelList(), "Select Permission Level", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.TablePermission.PermissionLevelId, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.RestrictViewFields, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="editor-field">
**// NEED TO ADD CHECK BOXES HER RECEIVED THRU SCRIPT**
</div>
</div>
}
<script>
function FillFields() {
var tblName = $('#TablePermission_TableName').val();
var tblPermLevel = $('#TablePermission_PermissionLevelId').val();
//($('tblPermForm').valid()) { ERROR - OBJECT DOESN'T HAVE valid()'
if (tblName != null && tblPermLevel != null) {
$.ajax({
url: '/Admin/FillFields',
type: 'GET',
dataType: "JSON",
data: { TableName: tblName, TablePermLevel: tblPermLevel },
success: function (restrictView) {
$("#RestrictViewFields").html(""); // Clear before appending new ones
$.each(restrictView, function (i, field) {
$("#RestrictViewFields").append(
$('<option></option>').val(field.FieldName).html(field.FieldName))
// WANT TO ADD AS 3 CHECKBOX IN A ROW
});
}
});
}
}
</script>
Their are couple of things that I am not able to figure out & get confused with it. Mainly, on making sure that both the drop down boxes has value, I need to perform again a "Get" and fetch column names for the table selected & display the columns as check boxes.
The way I have implemented Checkboxes, I will get proper selected Values in HttpPost, Right ! Are am I anywhere wrong ?
How to make the Get Request when both the drop down's are selected ??
Any help is highly appreciated. Thanks a lot in advance.
Update I started to try with only TableName selection (I want for both dropdown), but the event doesn't occur and go to FillFields() in script. Where am I going wrong ? I tried this logic from here . Can't get why it doesn't get fired only ???
Btw, this is a full form i mean, their is no partial form in it. I want to fill the check box controls in those 2 RestrictXFields on selection of TableName & Permssion check box & on Save btn, send all to Request & save to db.
UPDATE : THANKS a lot, Stephen & Chethan. With your support, I identified the cause for event not getting triggered. Event is triggered, I am able to retrieve the column names from db, the HTML part on success is not being updated. Stephen, I also added form Id & tried form.valid() as you instructed, but I get error script doesn't identify valid(). Both the fields in Model are marked as Required in MetaData class. Currently, testing both var != null works. But, I liked you valid() option.
Per my understanding, You should fetch the checkboxes using an ajax call.
Create an action method in your controller which accepts selected values of TableName and TableLevelPermisson dropdown. Use these values to fetch
List<FieldList> RestrictViewFields
IEnumerable<FieldList> RestrictEditFields.
and use as data/model to your partial view.
Call this action method using ajax, on change of the dropdown list value.
Get the HTML returned from partial view and use it in your DOM.
How to make the Get Request when both the drop down's are selected ??
If you are using jQuery: Just google for "dropdown change events in jquery" and ajax call examples.

ViewModel not binding when using in a new view

I am able to pass a view model initially on a form on my index.cshtml page to an editor template page. On the index page I have a submit button that post the form results (radio button groups in the editor template) back to the controller and within the HttpPost method its passing this model to a partial view which is displayed in a modal popup. All this does is show the form elements that were selected but it disables the radio buttons to the user. From here the user can either go back (close the window) or confirm the form results. When the user clicks the confirm button it should pass the viewmodel back to the controller to another HttpPost method which will then process the form results and return the final confirmation view. But when I try to pass the viewmodel back to the controller from the modal popup it does not keep the binding. I tried making sure all were binded through Hidden inputs but I must be missing something somewhere. Maybe I am going about this the wrong way. I just need to basically keep the viewmodel binding from the initial post and be able to process that after the user confirms the selection from the modal popup. What would be the best way to accomplish this without having to put a session hack in there?
Index
#using (Html.BeginForm("Index", "Home", FormMethod.Post, new { id = "ballotForm" }))
{
#Html.AntiForgeryToken()
#(Html.EditorFor(m => m.BallotViewModel, new ViewDataDictionary(ViewData)
{
TemplateInfo = new System.Web.Mvc.TemplateInfo
{
HtmlFieldPrefix = "BallotViewModel"
}
}))
<table class="col-sm-12">
<tr>
<td class="pull-right">
<button type="submit" class="btn btn-primary" data-target="#modal-container" data-toggle="modal">Vote Management Ballot</button>
</td>
</tr>
</table>
}
Controller - Initial Post to Modal Popup
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Index(HomeViewModel bModel)
{
if (ModelState.IsValid)
{
//set property to identity view
bModel.BallotViewModel[0].IsVoteConfirmationView = true;
return PartialView("ViewVoteConfirmation", bModel);
}
}
Controller - Post after Confirm submit from modal popup
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult ConfirmVote(HomeViewModel cModel)
{
//Process form results here but model is null
//Go to Thank You View
return View();
}
ViewVoteConfirmation:
#model Ballot.WebUI.Models.HomeViewModel
<div class="row">
#(Html.EditorFor(m => m.BallotViewModel, new ViewDataDictionary(ViewData) { TemplateInfo = new TemplateInfo { HtmlFieldPrefix = "BallotViewModel" } }))
</div>
#using (Html.BeginForm("ConfirmVote", "Home", FormMethod.Post, new { id = "ballotConfirmVoteForm" }))
{
#Html.AntiForgeryToken()
<div class="row">
#Html.EditorFor(m => m.BallotViewModel[0].Proposals, "Proposals", new ViewDataDictionary(ViewData)
{
TemplateInfo = new TemplateInfo
{
HtmlFieldPrefix = "Proposals"
}
})
</div>
<div class="row">
<div class="col-md-4 col-md-offset-4">
<button type="button" class="btn btn-default"
data-dismiss="modal">
Cancel
</button>
<button type="submit" id="approve-btn"
class="btn btn-danger">
Confirm
</button>
</div>
</div>
}
ProposalViewModel:
public class ProposalViewModel
{
public int ProposalItemID { get; set; }
public string ProposalItemTitle { get; set; }
public string Option0_Name { get; set; }
public string Option1_Name { get; set; }
public string Option2_Name { get; set; }
public string Option3_Name { get; set; }
public string PercOfShare { get { return "% of Share"; }}
public bool IsHeader { get; set; }
public int TagOrder { get; set; }
public int SelectedVoteOption { get; set; }
public bool IsVoteConfirmationView { get; set; }
public bool IsCumulative { get; set; }
public int SharePercentage { get; set; }
public List<VoteOptionViewModel> lVoteOptions { get; set; }
}
Proposals:
#model List<Ballot.WebUI.Models.ProposalViewModel>
#for (int i = 0; i < Model.Count; i++)
{
#Html.HiddenFor(m => m[i].ProposalItemID)
#Html.HiddenFor(m => m[i].ProposalItemTitle)
#Html.HiddenFor(m => m[i].Option0_Name)
#Html.HiddenFor(m => m[i].Option1_Name)
#Html.HiddenFor(m => m[i].Option2_Name)
#Html.HiddenFor(m => m[i].Option3_Name)
#Html.HiddenFor(m => m[i].PercOfShare)
#Html.HiddenFor(m => m[i].IsHeader)
#Html.HiddenFor(m => m[i].TagOrder)
#Html.HiddenFor(m => m[i].SelectedVoteOption)
#Html.HiddenFor(m => m[i].IsVoteConfirmationView)
#Html.HiddenFor(m => m[i].IsCumulative)
#Html.HiddenFor(m => m[i].lVoteOptions)
#Html.HiddenFor(m => m[i].SharePercentage)
}
jquery script to change the value of the SharePercentage label
$(function () {
//When 'For' is Selected
$('[class$=PercOfShareFor]').on('click', function (e) {
if ($(this).is(':checked')) {
var forMatches1 = 0;
$('[class$=PercOfShareFor]').each(function (i, val) {
if ($(this).is(':checked')) {
//check how many 'For' Vote Options are selected
forMatches1++;
//select the Share Percentage value label in the same row, and change the class to ForSelected (used as selector)
$(this).closest('td').next('td').next('td').find('.SharePercentage')
.removeClass("SharePercentage")
.addClass("SharePercentageForSelected");
//if the Share Percentage class (used as selector) was previously WithholdSelected then change to ForSelected
$(this).closest('td').next('td').next('td').find('.SharePercentageWithholdSelected')
.removeClass("SharePercentageWithholdSelected")
.addClass("SharePercentageForSelected");
}
});
//divide total 'For' Selections by number of Director Proposals
var forPercent1 = 100 / forMatches1;
//format the percentage to display 2 decimal places if not a whole number
var forPercent2 = Math.round(forPercent1 * 100) / 100;
//Update 'For' Percentages
$('[class$=SharePercentageForSelected]').text(forPercent2);
}
});
//When 'Withhold' is Selected after initially selecting 'For'
$('[class$=PercOfShareWithhold]').on('click', function (e) {
if ($(this).is(':checked')) {
var forMatches = 0;
$('[class$=PercOfShareFor]').each(function (i, val) {
if ($(this).is(':checked')) {
//check how many 'For' Vote Options are still selected
forMatches++;
}
});
var withholdMatches = 0;
$('[class$=PercOfShareWithhold]').each(function (i, val) {
if ($(this).is(':checked')) {
//check how many 'Withhold' Vote Options are still selected
withholdMatches++;
//set the class to WithholdSelected
$(this).closest('td').next('td').find('.SharePercentageForSelected')
.removeClass("SharePercentageForSelected")
.addClass("SharePercentageWithholdSelected")
.text("0"); //Set 'Withhold' Percentage back to 0
}
});
//divide total 'For' Selections by number of Director Proposals
var forPercent1 = 100 / forMatches;
//format the percentage to display 2 decimal places if not a whole number
var forPercent2 = Math.round(forPercent1 * 100) / 100;
//Update 'For' Percentages
$('[class$=SharePercentageForSelected]').text(forPercent2);
}
});
});
You can't do what you are trying to through form Posts. The browser sees the return from the Post as a full HTML page (even if you are saying it is a Partial server side). You will need to use some form of javascript to accomplish it or you will need to make your confirmation page an actual page instead of a modal popup.
The basic premise is that you need to trap the submit (or the button click) via javascript then display the modal. You can fill the modal with the results of the first action but you will need to submit the form via ajax instead of a standard form post. Then based on their selection in the modal you can submit the form or not.
There are a variety of resources available already that might help you. Here is one that show how to display a confirmation for a delete action. You could then alter that javascript to load the result of your first action via ajax as in this (admittedly older) article about loading MVC partial views using AJAX or maybe this one about using jQuery dialog for CRUD operations.
The model binding fix was to add a hidden field to the EditorTemplate for BallotViewModel so that when a radio button is selected, not only will the label change values but the hidden field would change values as well.
Editor Template
#Html.HiddenFor(m => Model.Proposals[i].SharePercentage, new { #class = "hdnSharePercentage" })
#Html.LabelFor(m => Model.Proposals[i].lVoteOptions[j].SharePercentage, Model.Proposals[i].lVoteOptions[j].SharePercentage, new { #class = "SharePercentage" })
jQuery
$(this).closest('td').next('td').next('td').find('.hdnSharePercentageWithholdSelected')
.removeClass("hdnSharePercentageWithholdSelected")
.addClass("hdnSharePercentageForSelected");

edit form not working, data is being passed to server but not the httpPost method

I had asked question yesterday, which can be found here and
based upon the answer I got from asp.net/mvc forum which can be found here, I was told to clear my modelstate, as by default my form tends to hold its default value, and not the value I just tried to update. So, I added Modelstate.Clear(), which still doesn't work. Can anyone tell me if i'm using the ModelState.Clear() in a wrong place or if I have to change something?
So, here is the problem, I have a edit form which shows its current values in textboxes, when user clicks edit button. If a user wants to edit some current value which is shown in textbox he edits the value in text box and clicks the save changes button. What currently is happening is in my HttpPost method when i check the values that are being passed, I don't get the new value user just provided, rather I get the value that was shown as current value in form.
But when I check in the developer tools in chrome, it shows the new value user just provided as the value that is being passed to server.
Here is my view
#using BootstrapSupport
#model AdminPortal.Areas.Hardware.Models.EditModule
#{
ViewBag.Title = "Edit";
Layout = "~/Views/shared/_BootstrapLayout.basic.cshtml";
}
<fieldset>
<legend>Module <small>Edit</small></legend>
#using (Html.BeginForm("Edit", "Module"))
{
#Html.ValidationSummary(true)
#Html.HiddenFor(m=>m.Id)
for(var i = 0; i < Model.Properties.Count(); i++)
{
#Html.HiddenFor(model=>model.HiddenProperties[i].Name)
#Html.HiddenFor(model=>model.HiddenProperties[i].Value)
<label class="label">#Model.Properties[i].Name</label>
<div class="input-block-level">#Html.TextBoxFor(model => model.Properties[i].Value)</div>
}
<div class="form-actions">
<button type="submit" class="btn btn-primary" id="Submit">Save changes</button>
#Html.ActionLink("Cancel", "ModuleList", null, new { #class = "btn " })
</div>
}
</fieldset>
<p>
#Html.ActionLink("Back to List", "ModuleList")
</p>
Here is the get and post method in controller
[HttpGet]
public ActionResult Edit(long id)
{
var module = _repository.GetModuleProperties(id);
ModelState.Clear();
return View(module);
}
[HttpPost]
public ActionResult Edit(EditModule module)
{
ModelState.Clear();
if (ModelState.IsValid)
{
_repository.SaveModuleEdits(module);
Information("Module was successfully edited!");
return RedirectToAction("ModuleList", "Module", new {area = "Hardware"});
}
Error("Edit was unsuccessful, if the problem persists please contact Merijn!");
return RedirectToAction("ModuleList", "Module", new { area = "Hardware" });
}
The problem is with your model:
public class EditModule
{
public long Id { get; set; }
public List<PropertyViewModel> Properties { get; set; }
public List<PropertyViewModel> HiddenProperties
{
get { return Properties; }
set { Properties = value; }
}
}
You're posting back both Properties and HiddenProperties, but only changing Properties. The modelbinder sets the new values in Properties and then sets the values for HiddenProperties which in turn sets Properties and you've just overwritten your changes.
I'm not sure what exactly you're trying to do with HiddenProperties, but it's completely broken as it's currently set up.
UPDATE: Suggested changes
Model
public class EditModule
{
public long Id { get; set; }
public List<PropertyViewModel> Properties { get; set; }
}
Removed HiddenProperties property
Controller Action
[HttpPost]
public ActionResult Edit(long id, EditModule module)
{
var originalModule = _repository.GetModuleProperties(id);
// do whatever comparisons you want here with originalModule.Properties / module.Properties
if (ModelState.IsValid)
{
_repository.SaveModuleEdits(module);
Information("Module was successfully edited!");
return RedirectToAction("ModuleList", "Module", new {area = "Hardware"});
}
Error("Edit was unsuccessful, if the problem persists please contact Merijn!");
return RedirectToAction("ModuleList", "Module", new { area = "Hardware" });
}
Edit POST version takes the id just like the GET version. You use this id to lookup the original version of the module from the database and then you can compare original and posted versions of Properties.
View
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
#Html.HiddenFor(m=>m.Id)
for(var i = 0; i < Model.Properties.Count(); i++)
{
<label class="label">#Model.Properties[i].Name</label>
<div class="input-block-level">#Html.TextBoxFor(model => model.Properties[i].Value)</div>
}
<div class="form-actions">
<button type="submit" class="btn btn-primary" id="Submit">Save changes</button>
#Html.ActionLink("Cancel", "ModuleList", null, new { #class = "btn " })
</div>
}
The Html.BeginForm() syntax tells Razor to just use the current page's URL as the action for the form. HiddenProperties form fields have been removed.

How to save data into DataTable in MVC3?

I have mvc3 application in this i have used two partial views 1.controls 2.webgrid
inside controls i'm populating dropdownlists from actual database tables. using EF
On index.cshtml i have one form in which need to select values from these dropdown lists and when press insert button these values should have to go to Temp "DataTable" and also show it in webgrid...I'm newbie to MVC3 and dont know how to do this.
Controls.cshtml
#model Mapping.Models.SecurityIdentifierMappingViewModel
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<fieldset>
<legend>Mapping</legend>
<div class="editor-label">
#Html.Label("Pricing SecurityID")
</div>
<div class="editor-field">
#Html.HiddenFor(model => model.MappingControls.Id)
#Html.DropDownListFor(model => model.MappingControls.PricingSecurityID,
new SelectList(Model.PricingSecurities, "Value", "Text"),
"Select SecurityID"
)
#Html.ValidationMessageFor(model => model.MappingControls.PricingSecurityID)
</div>
<div class="editor-label">
#Html.Label("CUSIP ID")
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.MappingControls.CUSIP,
new SelectList(Model.CUSIPs, "Value", "Text"),
"Select CUSIP"
)
#Html.ValidationMessageFor(model => model.MappingControls.CUSIP)
</div>
<div class="editor-label">
#Html.Label("Calculation")
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.MappingControls.Calculation)
#Html.ValidationMessageFor(model => model.MappingControls.Calculation)
</div>
<p>
<input id="btnsubmit" type="submit" value="Insert" />
</p>
</fieldset>
}
HomeController.cs
public class HomeController : Controller
{
//
// GET: /Home/
mydataEntities dbContext = new mydataEntities();
DataRepository objRepository = new DataRepository();
//GET
public ActionResult Index(string userAction , int uid = 0)
{
var mappingobj = new SecurityIdentifierMappingViewModel();
mappingobj.MappingWebGridList = dbContext.SecurityIdentifierMappings.ToList();
mappingobj.MappingControls = new SecurityIdentifierMapping();
mappingobj.MappingControls.PricingSecurityID = 0;
mappingobj.MappingControls.CUSIP = string.Empty;
mappingobj.PricingSecurities = objRepository.GetPricingSecurityID();
mappingobj.CUSIPs = objRepository.GetCUSIP();
return View(mappingobj);
}
//POST
[HttpPost]
public ActionResult Index(SecurityIdentifierMappingViewModel objModel)
{
if (objModel.MappingControls.Id > 0)
{
if (ModelState.IsValid)
{
dbContext.Entry(objModel.MappingControls).State = EntityState.Modified;
try
{
dbContext.SaveChanges();
//objModel = new SecurityIdentifierMappingViewModel();
//return RedirectToAction("Index", "Home");
}
catch (System.Data.Entity.Validation.DbEntityValidationException ex)
{
throw;
}
}
}
//insert code
else
{
if (ModelState.IsValid)
{
dbContext.SecurityIdentifierMappings.Add(objModel.MappingControls);
try
{
dbContext.SaveChanges();
}
catch (System.Data.Entity.Validation.DbEntityValidationException ex)
{
throw;
}
}
}
return RedirectToAction("Index");
}
}
public class SecurityIdentifierMappingViewModel
{
public IEnumerable<SecurityIdentifierMapping> MappingWebGridList { get; set; }
public SecurityIdentifierMapping MappingControls { get; set; }
public List<SelectListItem> PricingSecurities { get; set; }
public List<SelectListItem> CUSIPs { get; set; }
}
Currently using SecurityIdentifierMapping as a 3rd table from database in which inserting my form data ... but need to insert it into "DataTable"
You will have to create a DataTable object and assign appropriate DataColumn objects to it. After that map your SecurityIdentifierMapping properties to columns in your temporary data table. As for mapping DataTable to WebGrid, I am not going to say that it is not possible as I have never tried this thing personally, but you will have to map it back to a collection of SecurityIdentifierMapping.
But, why do you need DataTable? What possible advantages could DataTable have over IQueryable or IEnumerable? What is it that you actually want to achieve using this strategy?
UPDATE:
You are already using IEnumerable in your ViewModel class (SecurityIndentifierMappingViewModel). At the same time you are storing data in the database when POSTing to Index, and fetching again in GET version of Index.
What you are missing is to create a WebGrid object in your view. Your view could be defined like this:
#{
var columns = new List<string>();
columns.Add("Column 1");
columns.Add("Column 2");
var grid = new WebGrid(model: Model.MappingWebGridList, columnNames: columns);
}
#grid.GetHtml()
Place the above code somewhere in your Index view, and define your own columns. In addition, have a look at this article which I wrote in order to get more ideas what you can do with WebGrid http://apparch.wordpress.com/2012/01/04/webgrid-in-mvc3/.
I hope I managed to help you at least a bit.

Need help in Html.ListBox in ASP.NET MVC

I am presently working on a application in which I have a display a list of items in a list box in the view and then send back the selected items to the controller.
My model is as follows:
public class Items
{
[DisplayName("Items")]
public string[] Items { get; set; }
}
When the user first requests the page, the list of items has to be queried from a database and sent to the view.
I am able to figure out how to collect the items into ArrayList/string[] at the controller side but am not able to understand the syntax for binding the view with the model and displaying the list using Html.ListboxFor and sending back the model on form submit.
Can someone please help me.
Thanks.
View model:
public class MyViewModel
{
[DisplayName("Items")]
public string[] SelectedItemIds { get; set; }
public IEnumerable<SelectListItem> Items { get; set; }
}
Controller:
public class HomeController : Controller
{
public ActionResult Index()
{
var model = new MyViewModel
{
// preselect some items
// leave empty if you want none to be selected initially
SelectedItemIds = new[] { "1", "3" },
// Normally you would fetch those from your database
// hardcoded here for the purpose of the post
Items = Enumerable.Range(1, 10).Select(x => new SelectListItem
{
Value = x.ToString(),
Text = " item " + x
})
};
return View(model);
}
[HttpPost]
public ActionResult Index(string[] selectedItemIds)
{
// here you will get the list of selected item ids
// where you could process them
// If you need to redisplay the same view make sure that
// you refetch the model items once again from the database
...
}
}
View (Razor):
#model AppName.Models.MyViewModel
#using (Html.BeginForm())
{
#Html.LabelFor(x => x.SelectedItemIds)
#Html.ListBoxFor(
x => x.SelectedItemIds,
new SelectList(Model.Items, "Value", "Text")
)
<input type="submit" value="OK" />
}
View (WebForms):
<% using (Html.BeginForm()) { %>
<%= Html.LabelFor(x => x.SelectedItemIds) %>
<%= Html.ListBoxFor(
x => x.SelectedItemIds,
new SelectList(Model.Items, "Value", "Text")
) %>
<input type="submit" value="OK" />
<% } %>

Resources