SelectListItem not Returning Results - MVC5 - c#

I have tried a multitude of different posts and tags and mixtures and not getting a return of data on my select lists. I have even ready that some people have to use jquery to highlight the lists before sending them; This is incredibly doable IF selecting the item actually passed the item! I am willing to use Jquery, I am willing to update the model, I am willing to do whatever it takes to get the model data BACK, but it seems all of those return count=0 or null.
I am using 2 list boxes with some movement inside of them and want to return the contents of both listboxes upon completion.
(If there is another way to be doing this, please share!)
Model:
public class RoleAddRemoveListBoxViewModel
{
public List<System.Web.Mvc.SelectListItem> CurrentRoles { get; set; }
public List<System.Web.Mvc.SelectListItem> NonMemberRoles { get; set; }
}
Controller:
[HttpPost]
public ActionResult ManageUserRoles(string userList)
{
List<SelectListItem> lbMemberRoles = new List<SelectListItem>();
List<SelectListItem> lbNonMemberRoles = new List<SelectListItem>();
var user = (from u in db.Users
where u.UserName == userList
select u).SingleOrDefault();
// prepopulate roles for the view dropdown
var roleList = db.Roles.OrderBy(r => r.Name).ToList().Select(rr =>
new SelectListItem { Value = rr.Name.ToString(), Text = rr.Name }).ToList();
var userRoles = UserManager.GetRoles(user.Id);
foreach (var role in roleList)
{
if (userRoles.Contains(role.Value.ToString()))
{
lbMemberRoles.Add(role);
}
else
{
lbNonMemberRoles.Add(role);
}
}
RoleAddRemoveListBoxViewModel lbvm = new RoleAddRemoveListBoxViewModel
{
CurrentRoles = lbMemberRoles,
NonMemberRoles = lbNonMemberRoles
};
return View(lbvm);
}
[HttpPost]
public ActionResult UpdateUserRoles(RoleAddRemoveListBoxViewModel model)
{
TempData["updateState"] = "User Role Updated Successfully!";
return RedirectToAction("Index");
}
View:
#model WebDocEditor.Models.RoleAddRemoveListBoxViewModel
#{
using (Html.BeginForm("UpdateUserRoles", "Roles", FormMethod.Post))
{
<body>
<fieldset>
<form>
<div class="row">
<div class="col-xs-2">
#Html.LabelFor(model => model.CurrentRoles)
<div>
#Html.ListBoxFor(model => model.CurrentRoles, Model.CurrentRoles)
</div>
</div>
<div class="btn-group-vertical col-xs-1">
<div id="moveRightbtn" class="btn glyphicon glyphicon-arrow-right"></div>
<div id="moveLeftbtn" class="btn glyphicon glyphicon-arrow-left"></div>
</div>
<div class="col-xs-2">
#Html.LabelFor(model => model.NonMemberRoles)
<div>
#Html.ListBoxFor(model => model.NonMemberRoles, Model.NonMemberRoles)
</div>
</div>
</div>
<input type="submit" value="Save" />
</form>
</fieldset>
</body>
}
}
After action edit: I Wanted to throw in the JQuery I used for the highlighting since I see so many threads on how THEY got it to work and wanted to show what worked with my combination/setup:
JS on View:
#section Scripts
{
<script type="text/javascript">
$(document).ready(function () {
$('#moveRightbtn').on('click', function () {
var selectedCurrent = $('#CurrentRoles option:selected');
$('#NonMemberRoles').append($(selectedCurrent).clone());
$(selectedCurrent).remove()
//alert(selectedCurrent);
})
$('#moveLeftbtn').on('click', function () {
var selectedNonMember = $('#NonMemberRoles option:selected');
$('#CurrentRoles').append($(selectedNonMember).clone());
$(selectedNonMember).remove()
//alert(selectedNonMember);
})
$("#submitBtn").on('click', function (e) {
$("#CurrentRoles option").prop('selected', 'selected');
$("#NonMemberRoles option").prop('selected', 'selected');
});
});
</script>
}

Your lists needs to be separate from what you're returning.. you should set your model up like this.
public class RoleAddRemoveListBoxViewModel
{
public List<System.Web.Mvc.SelectListItem> CurrentRolesList { get; set; }
public List<System.Web.Mvc.SelectListItem> NonMemberRolesList { get; set; }
public string[] CurrentRoles {get;set;}
public string[] NonMemberRoles {get;set;}
}
List boxes will return an array of whatever is selected.. In this case you can just set the properties to string[]
In your view, use the new properties as the expression and the List properties as the selectList
#using (Html.BeginForm())
{
<div class="row">
<div class="col-xs-2">
#Html.LabelFor(model => model.CurrentRoles)
<div>
#Html.ListBoxFor(model => model.CurrentRoles, Model.CurrentRolesList)
</div>
</div>
<div class="btn-group-vertical col-xs-1">
<div id="moveRightbtn" class="btn glyphicon glyphicon-arrow-right"></div>
<div id="moveLeftbtn" class="btn glyphicon glyphicon-arrow-left"></div>
</div>
<div class="col-xs-2">
#Html.LabelFor(model => model.NonMemberRoles)
<div>
#Html.ListBoxFor(model => model.NonMemberRoles, Model.NonMemberRolesList)
</div>
</div>
</div>
<input type="submit" value="Save" />
}
in your controller.. make sure you set the right properties to your lists
public ActionResult ManageUserRoles(string userList)
{
List<SelectListItem> lbMemberRoles = new List<SelectListItem>();
List<SelectListItem> lbNonMemberRoles = new List<SelectListItem>();
var user = (from u in db.Users
where u.UserName == userList
select u).SingleOrDefault();
// prepopulate roles for the view dropdown
var roleList = db.Roles.OrderBy(r => r.Name).ToList().Select(rr =>
new SelectListItem { Value = rr.Name.ToString(), Text = rr.Name }).ToList();
var userRoles = UserManager.GetRoles(user.Id);
foreach (var role in roleList)
{
if (userRoles.Contains(role.Value.ToString()))
{
lbMemberRoles.Add(role);
}
else
{
lbNonMemberRoles.Add(role);
}
}
RoleAddRemoveListBoxViewModel lbvm = new RoleAddRemoveListBoxViewModel
{
CurrentRolesList = lbMemberRoles,
NonMemberRolesList = lbNonMemberRoles
};
return View(lbvm);
}
not sure why you had this actionresult as a [HttpPost] but you might want to remove that attribute..
the way list boxes work, it will only post back what is actually selected.. so you might have to select all of the items in each list if you want to return all of the values in them

Add string[] for your return properties.
public List<System.Web.Mvc.SelectListItem> CurrentRoles { get; set; }
public List<System.Web.Mvc.SelectListItem> NonMemberRoles { get; set; }
public string[] SelectedCurrentRoles{ get; set; }
public string[] SelectedNonMemberRoles{ get; set; }
and use MultiSelectList in your ListBoxFor. I would use a different model to pass in but you could use your existing List<SelectListItem>
#Html.ListBoxFor(model => model.SelectedCurrentRoles, new MultiSelectList(Model.CurrentRoles, "Value", "Text"))
#Html.ListBoxFor(model => model.SelectedNonMemberRoles, new MultiSelectList(Model.NonMemberRoles , "Value", "Text"))

Related

return to partial view as json?

i had 2 views the "index" and "_Track". i need to return my datalist to "_Track"-this is partial view. can someone help me becoz i got this error. i need to return the data list into partial view.
Error
"for each statement cannot operate on variable type does not contain a public instance definition for getenumerator"
see the reference code below.
Parent model.
public class TrackingFormModel : BaseModel
{
public string TrackingNumber { get; set; }
public TrackingListModel TrackingList { get; set; }
}
Child model
public class TrackingListModel : BaseModel
{
public string Name { get; set; }
public string Departure { get; set; }
}
Index.cshtml
#using ChenvelMobile.Web.Models.Tracking
#model TrackingFormModel
#{
ViewBag.Title = "index";
Layout = null;
}
#using (Html.BeginForm("index", "tracking", FormMethod.Post))
{
#Html.HiddenFor(x => x.Id)
<div class="MainContainer">
<div class="row">
<div class="form-group">
<div class="col-md-12">
<h4>Track an Item</h4>
<p>Hint: Enter the correct tracking number (Example. AU0002004)</p>
<div class="input-group">
#Html.TextBoxFor(x => x.TrackingNumber, new { #class = "form-control", #id = "testSize", #placeholder = "Enter your box number..." })
<div class="input-group-btn">
<button class="btn btn-primary" type="submit" id="show">
<span class="glyphicon glyphicon-search btnSize" style="font-size: 20px"></span>
</button>
</div>
</div>
<br />
#Html.Partial("_Track", Model)
</div>
</div>
</div>
</div>
}
_Track.cshtml(Partial View)
#using ChenvelMobile.Web.Models.Tracking
#model TrackingListModel
#foreach (var item in Model)
{
<div>#item.Id</div>
<div>#item.Name</div>
<div>#item.Departure</div>
}
Controller
public JsonResult Index(TrackingFormModel model)
{
string date = String.Format("{0:MM/dd/yyyy}", DateTime.Now);
DateTime startdate = DateTime.Parse(date);
DateTime prevoiusdate = startdate.AddDays(-90);
var tracking = _cSI_DataService.Find(x => x.reciept_id == model.TrackingNumber).Where(x => Convert.ToDateTime(x.date_pl) > prevoiusdate).ToList();
var list = (from t in tracking
join d in _departureItemsTableService.GetAll() on t.box_id.Trim() equals d.BoxNo.Trim() into departitem from departitems in departitem.DefaultIfEmpty()
join dt in _departureTableService.GetAll() on departitems?.DepartureId equals dt.DepartureId into dep from depart in dep.DefaultIfEmpty()
select new TrackingListModel
{
Id = t.Id,
Name = t.firstname_s + " " + t.lastname_s,
Departure = depart?.DepartureDate ?? String.Empty,
});
return Json(new { data = list.ToList() }, JsonRequestBehavior.AllowGet);
}
Try passing the tracking list to your partial view. Currently you are passing a TrackingFormModel, not the expected TrackingListModel.
#Html.Partial("_Track", Model.TrackingList)

DropDownList - How to add SelectListItem ASP.NET MVC

I have an DropDownList ,which is showing list of Status,but when i Select an item from DropDownlist and than i Checked HTML Markup i can see there isnt Selected attr and than i researched and find out I need SelectListItem in my Controller and than i tried to implement it in my Controller,but i got some errors :) as usually i implement DropDown in my Razor View (static) , but this time which is first time :) i want implement in my Controller so it becomes dynamic.
Can anyone point me in right direction :)
Thanks in advance :)
Controller:
//DropDown
public List<VMRMA.NameStatusDropDown> GetStatusForDropDown()
{
List<VMRMA.NameStatusDropDown> result = new List<VMRMA.NameStatusDropDown>();
var obj = db.RMAStatus.Select(u => u).ToList();
if (obj != null && obj.Count() > 0)
{
foreach (var data in obj)
{
VMRMA.NameStatusDropDown model = new VMRMA.NameStatusDropDown();
model.Status = data.Status;
model.ID = data.ID;
result.Add(model);
}
}
return result;
}
//Dropdown runs in this Action
public ActionResult RMA ()
{
VMRMA model = new VMRMA();
model.NameStatusDropDowns = GetStatusForDropDown();
//RMA query and some an other stuff
return View(model);
}
ViewModel:
public class VMRMA
{
public List<NameStatusDropDown> NameStatusDropDowns { get; set; }
//DropDown
public class NameStatusDropDown
{
public NameStatusDropDown()
{
}
public NameStatusDropDown(int ID, string Status)
{
this.ID = ID;
this.Status = Status;
}
public int ID { get; set; }
public string Status { get; set; }
}
}
View:
#using ModelNamespace.Models
#model VMRMA
<form>
<div class="form-group">
<label class="form-control-label">Select a status</label>
<br />
<select>
<option>Select</option>
#foreach (var item in Model.NameStatusDropDowns)
{
<option value="#item.ID">#item.Status</option>
}
</select>
</div>
<div class="form-group">
<input type="submit" value="Send data" class="btn btn-primary">
</div>
</form>
HTML Markup:
<div class="form-group">
<label class="form-control-label">Select a status</label>
<br>
<select>
<option>Select</option>
<option value="1">Sendt</option>
<option value="2">Under behandling</option>
<option value="3">Blive behandlet</option>
<option value="4">Modtaget</option>
</select>
</div>
This two Post helped me out to solve the problem and Thanks to #Stephen Muecke with his good post, Which is wroted Here and Thanks to this post with great explanation, which is wroted Here.
Here is what i did , maybe it helped someone one day :) :
Add To Property to my View Model :
public class VMRMA
{
public List<SelectListItem> Status { set; get; }
public int? SelectedStatus { set; get; }
}
Change my ActionResult to :
public ActionResult RMA (int Id)
{
VMRMA model = new VMRMA();
model.Status = new SelectList(DatabaseNameSpace.RMAStatus, "ID",
"Status").ToList();
//some an other stuff
return View(model);
}
and than change my View to :
#Html.DropDownListFor(s => s.SelectedStatus, Model.Status, "- Select -", new { #class = "form-control" })
Controller:
ViewBag.Statuses= new SelectList(_context.RMAStatus
.Select(item => new { value = item.Id, text = item.Status}), "value", "text", selectedId);
View:
#Html.DropDownListFor(x => x.StatusId, ViewBag.Statuses as SelectList, "- please select -")
Create a partial view as this:
#model MyApp.Models.MyClass
#{
Layout = null;
}
#*#Html.Partial("ActionMethod", "Controller", new ViewDataDictionary { { "Name", "TestName" } })*#
#Html.DropDownList((String)TempData["Name"], new SelectList( ViewBag.Specialities,"Value","Text"),
new { #class = "form-control", #multiple="multiple" });
Then in your controller
List<MyClass> lstSpecialities =
ViewBag.Specialities = lstSpecialities; // Now it is available for the view
Last step, load your view using #Html.RenderAction()

Pass Selected values of ListBox to Controller

i have many to many relationship between faxes and employees
I wanna have a fax form which has a listBox to select employees but i don't know how get the selected employees
FaxForm.cshtml:
#using (Html.BeginForm("CreateFax", "Fax"))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Fax.Courier_Num, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Fax.Courier_Num, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Fax.Courier_Num)
</div>
</div>
<div class="form-group">
<div class="col-md-10">
#Html.ListBox("Employees", ViewBag.Employees as MultiSelectList,
new { #class = "chzn-select", data_placeholder = "Choose Employee..." })
</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>
FaxController.cs:
public ActionResult New()
{
var Employees = Db.Employees;
ViewBag.Employees = new MultiSelectList(Employees, "Id", "Name");
return View("FaxForm");
}
public ActionResult CreateFax(Fax fax)
{
if (!ModelState.IsValid)
{
//some Code
return View("FaxForm"/*, viewModel*/);
}
if (fax.Id == 0)
{
Db.Faxes.Add(fax);
Db.SaveChanges();
}
return RedirectToAction("Index", "Employees");
}
i create viewmodel class to make relation between employees and faxes
MenuViewModel.cs:
public IEnumerable<SelectListItem> Employees { set; get; }
public Fax Fax { set; get; }
i need to save the selected employees in fax table..........................
You should use a view model specific to your view. Do not mix your entity model with that.
public class SendFaxVm
{
public List<SelectListItem> Employees { set; get; }
public int[] SelectedEmployees { set; get; }
public string CompanyName { set; get; }
public string CompanyAddress { set; get; }
// To do : Add other properties needed in the VIEW
}
Now in your GET action, create an object of this, load the Employees property and send it to the view
public ActionResult New()
{
var vm= new SendFaxVm();
vm.Employees = db.Employees
.Select(a => new SelectListItem() {Value = a.Id.ToString(),
Text = a.Name})
.ToList();
return View(vm);
}
Now in your view, which is strongly typed to our SendFaxVm, use the helper methods to generate your textbox's and multi select dropdown
#model SendFaxVm
#using (Html.BeginForm("CreateFax", "Fax"))
{
#Html.TextBoxFor(a => a.CompanyName)
#Html.TextBoxFor(a => a.CompanyAddress)
#Html.ListBoxFor(a => a.SelectedEmployees, Model.Employees)
<input type="submit" />
}
And use the same view model as the parameter of your HttpPost action method. When the form is submitted the properties will be populated by the data sent from the form. The SelectedEmployees property will be an array of UserId's which was selected. You can read these property values and save it to your entity tables.
[HttpPost]
public ActionResult CreateFax(SendFaxVm model)
{
// check model.SelectedEmployees and other properties
// and use that to save data to your tables
Fax f=new Fax();
f.CompanyName = model.CompanyName;
f.CompanyAddress = model.CompanyAddress;
// to do : Assign other property values for the Fax table
db.Fax.Add(f);
db.SaveChanges();
//Now loop through the SelectedEmployees and save record for FaxData table
foreach(var userId in model.SelectedEmployees)
{
var fd=new FaxData { EmpId = userId, FaxId=f.Id };
//to do : Save fd
}
return RedirectToAction("Index");
}

MVC4 DropDownList from DB

I'm trying to make very simple forum, but I have problem with DropDownList. I have two models:
ForumThread.cs
public partial class ForumThread
{
public ForumThread()
{
this.ForumCategory = new HashSet<ForumCategory>();
}
public int TH_ID { get; set; }
public System.DateTime DATE { get; set; }
public string TOPIC { get; set; }
public string USER { get; set; }
public virtual ICollection<ForumCategory> ForumCategory { get; set; }
}
ForumCategory.cs
public partial class ForumCategory
{
public ForumCategory()
{
this.ForumThread = new HashSet<ForumThread>();
}
public int CA_ID { get; set; }
public string CATEGORY { get; set; }
public bool isSelected { get; set; }
public virtual ICollection<ForumThread> ForumThread { get; set; }
}
I tried to make "Create" function with view:
Create
#model AnimeWeb.Models.ForumThread
#{
ViewBag.Title = "Create";
}
<h2>New Thread</h2>
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<div class="editor-field">
#Html.HiddenFor(model => model.TH_ID)
</div>
<div class="editor-label">
TOPIC
</div>
<div class="editor-field">
#Html.EditorFor(model => model.TOPIC)
#Html.ValidationMessageFor(model => model.TOPIC)
</div>
<div class="editor-label">
CATEGORY
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ForumCategory)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
And PartialView for ForumCategory:
ForumCategory
#model AnimeWeb.Models.FORUMCATEGORY
#Html.HiddenFor(model => model.CA_ID)
#Html.HiddenFor(model => model.CATEGORY)
<div>
#Html.DropDownListFor(item => Model.CA_ID, ViewBag.CA_ID as SelectList, "-- Select --")
</div>
ForumController
public ActionResult Create()
{
var db = new MainDatabaseEntities();
var viewModel = new ForumThread
{
ForumCategory = db.ForumCategory.Select(c => new { CA_ID = c.CA_ID, CATEGORY = c.CATEGORY, isSelected = false }).ToList().Select(g => new ForumCategory
{
CA_ID = g.CA_ID,
CATEGORY = g.CATEGORY,
isSelected = false
}).ToList(),
};
return View(viewModel);
}
//
// POST: /Forum/Create
[HttpPost]
public ActionResult Create(ForumThread forumthread, String user, int id)
{
var db = new MainDatabaseEntities();
var newthread = new ForumThread
{
TH_ID = forumthread.TH_ID,
DATE = DateTime.Now,
TOPIC = forumthread.TOPIC,
USER = forumthread.USER,
ForumCategory = new List<ForumCategory>()
};
foreach (var selectedCategory in forumthread.FORUMCATEGORY.Where(c => c.isSelected))
{
var category = new ForumCategory { CA_ID = selectedCategory.CA_ID };
db.ForumCategory.Attach(category);
newthread.ForumCategory.Add(category);
}
db.ForumThread.Add(newthread);
db.SaveChanges();
return RedirectToAction("Index");
}
And it obviously doesn't work. I tried to use other threads on this forum but nothing helped. Could someone explain me how to make this work?
The error is in partial view of ForumCategory:
The ViewData item that has the key 'CA_ID' is of type 'System.Int32' but must be of type 'IEnumerable<SelectListItem>'.
In your PartialView for ForumCategory, your cast is not correct:
#Html.DropDownListFor(item => Model.CA_ID, ViewBag.CA_ID as SelectList, "-- Select --")
You have to use a SelectList (List of SelectListItem) that you can implement for example in a method in your model:
public List<SelectListItem> GetCategories()
{
var db = new MainDatabaseEntities();
List<SelectListItem> list = new List<SelectListItem>();
// Add empty item if needed
SelectListItem commonItem = new SelectListItem();
commonItem.Text = "--- Select ---";
commonItem.Value = "-1";
commonItem.Selected = true;
list.Add(commonItem);
// Add items from Database
foreach (ForumCategory fc in db.ForumCategory)
{
SelectListItem i = new SelectListItem();
i.Text = fc.CATEGORY;
i.Value = fc.CA_ID.ToString();
list.Add(i);
}
return list;
}
And then you can have you dropdown like that:
#Html.DropDownList("DropName", Model.GetCategories())
There may be other errors in some parts of your code, I just answered to the one you quoted
In your editortemplate, you have:
ViewBag.CA_ID as SelectList
But you don't show where you fill the ViewBag. Instead you might want to do something like this:
#Html.DropDownListFor(m => m.CA_ID,
new SelectList(Model.ForumCategory,
"CA_ID", "CATEGORY", Model.CA_ID))
As also explained in MVC3 DropDownListFor - a simple example?.

Retrieving dynamic checkbox values and label from strongly typed view in MVC3

EDIT: whoever fixed my question so the code displayed right, thank you! :)
I have a silly problem I really need som help with, after a whole day of googling I'm close to loosing my head!
I am working with the asp.net membership, and I want to be able to set roles on user once the web app is upp and running.
To implement this I am sending a model to a strongly typed view with a list of checkboxes, if the user is in one of the roles in the list the checkbox is checked. (this part works)
But I cant figure out how to return the checkbox values in the Edit method, as the model returns 'null' on the List-property.
I am sure I've missed something obvious here, and would be very happy for any help...
And how can I add code to this question? I cant get the formatting right...
View
#model Mvc4m.Models.UserRoles
#{
ViewBag.Title = "Edit";
}
<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>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>UserRoles</legend>
<div class="editor-label">
<h2> #Html.DisplayFor(model => model.Name)</h2>
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Roles)
</div>
<div class="editor-field" id="testar">
#foreach (var model in Model.AllRolles)
{
#Html.CheckBoxFor(item => model.IsActive, model.Role)
#Html.Label(model.Role)
}
</div>
<div class="editor-label">
#Html.LabelFor(model => model.IsApproved)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.IsApproved)
#Html.ValidationMessageFor(model => model.IsApproved)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
Controller
public List<AllRolles> UserActiveRoles(string name)
{
var list = new List<AllRolles>();
foreach(var role in Roles.GetAllRoles())
{
var hej = new AllRolles()
{
Role = role,
IsActive = Roles.IsUserInRole(name,role)
};
list.Add(hej);
}
return list;
}
public ActionResult Index()
{
var roles = Roles.GetAllRoles();
var users = from MembershipUser u in Membership.GetAllUsers()
select new UserRoles()
{
Name = u.UserName,
AllRolles = UserActiveRoles(u.UserName)
};
return View(users);
}
public ActionResult Edit(string name)
{
var user = Membership.GetUser(name);
var model = new UserRoles()
{
Name = user.UserName,
AllRolles = UserActiveRoles(name)
};
return View(model);
}
//
// POST: /Admin/ManageUsers/Edit/5
[HttpPost]
public ActionResult Edit(UserRoles user)
{
var name = user.Name;
foreach (var role in user.AllRolles)
{
if (role.IsActive == true)
Roles.AddUserToRole(name,role.Role);
else
Roles.RemoveUserFromRole(name,role.Role);
}
return RedirectToAction("Index");
}
Models
public class UserRoles
{
public string Name { get; set; }
public List<string> Roles { get; set; }
public bool IsApproved { get; set; }
public List<AllRolles> AllRolles { get; set; }
}
namespace Mvc4m.Areas.Admin.Models
{
public class AllRolles
{
public string Role { get; set; }
public bool IsActive { get; set; }
}
}
At UserRoles.cs
Change
public List<AllRolles> AllRolles { get; set; }
to
public AllRolles[] AllRolles { get; set; }
At Edit.cshtml
Change
#foreach (var model in Model.AllRolles)
{
#Html.CheckBoxFor(item => model.IsActive, model.Role)
#Html.Label(model.Role)
}
to
#for (int i = 0; i < Model.AllRolles.Length; i++)
{
#Html.CheckBoxFor(item => Model.AllRolles[i].IsActive)
#Html.HiddenFor(item => Model.AllRolles[i].Role)
#Html.Label(Model.AllRolles[i].Role)
}
At your controller
Add .ToArray() after UserActiveRoles(u.UserName)
public ActionResult Index()
{
var roles = Roles.GetAllRoles();
var users = from MembershipUser u in Membership.GetAllUsers()
select new UserRoles()
{
Name = u.UserName,
AllRolles = UserActiveRoles(u.UserName).ToArray()
};
return View(users);
}
The problem
You must show to the ModelBinder that you're sending a collection, instead of a bunch of parameters.
What's sent to the server?
AllRolles[0].IsActive:false
AllRolles[0].Role:Admin
AllRolles[1].IsActive:false
AllRolles[1].Role:User
Hope it helps
It's really simple. You must give your checkboxes a name let's say myCheckboxes and you pass a int[] myCheckboxes to POST action. I've provided you a code sample:
In your view let's say you have
#foreach (var role in Model.AllRoles)
{
<input type="checkbox" name="UserNotInRoles" value="#role.RoleId" checked/>#role.RoleName
<br />
}
#foreach (var role in Model.UserRole)
{
<input type="checkbox" name="UserInRoles" value="#role.RoleId" checked/>#role.RoleName
<br />
}
Now to post what user has checked/unchecked you use the following:
[HttpPost]
public ActionResult Edit(UserRoleSaveVM saveRoles)
{
if (saveRoles.UserNotInRoles != null)
{
foreach (int roleID in saveRoles.UserNotInRoles)
{
//DO SOMETHING
}
}
where UserRoleSaveVM is
public class UserRoleSaveVM
{
public int UserID { get; set; }
public int[] UserInRoles { get; set; } //note that property name is the same as checkbox name
public int[] UserNotInRoles{ get; set; } //note that property name is the same as checkbox name
}

Categories