Asp.net MVC , CheckBoxs not binding in case of list - asp.net-mvc-4

Though it seems like it has been discussed earlier also , but I could not find the solution -:
I have a VM like this-:
public class RoomsVm
{
public RoomsVm()
{
Rooms.Add(new Room()
{
IsVip = true,Id = "1"
}
);
Rooms.Add(new Room()
{
IsVip = false,
Id = "2"
}
);
}
public List<Room> Rooms=new List<Room>();
}
public class Room
{
public bool IsVip { get; set; }
public string Id { get; set; }
}
My controller has 2 simple actions- 1- for get and 2 for post-:
public ActionResult IndexView2()
{
var roomVM = new RoomsVm();
return View(roomVM);
}
[HttpPost]
public ActionResult IndexView2(RoomsVm roomsVm)
{
return View(roomsVm);
}
In my view - I simply display my rooms with check boxes like this-:
#model MVCApplication.Models.RoomsVm
<h2>IndexView2</h2>
#using (Html.BeginForm())
{
for (int i = 0; i < Model.Rooms.Count(); i++)
{
#Html.CheckBoxFor(modelItem=>modelItem.Rooms[i].IsVip,new{value=Model.Rooms[i].Id})
}
<input type="submit" value="Submit"/>
}
Problem- When I click Submit button, I don't get updated values of rooms checkboxes in input value of Post action ..
What wrong am I doing ?

You don't have accessors on your Rooms property
public class RoomsVm
{
public RoomsVm()
{
Rooms = new List<Room>(); // Initialize rooms
Rooms.Add(new Room() {.... //Add rooms
}
public List<Room> Rooms { get; set; } // Add get/set
}

Related

Retrieve values from SQL database - EF

I'm trying to figure out how to pull values from a SQL database and display this in a razor view.
I have the following class using Entity Framework (I believe)
public class EventLog
{
[Key]
public int Id { get; set; }
public int EventId { get; set; }
public int MaxDelegates { get; set; }
public string Code { get; set; }
public DateTime End { get; set; }
public string Title { get; set; }
}
And I want to map title to DBTitle in the following model:
public class CourseDetailVM : CourseDetailSummaryVM
{
public EventLog DBTitle { get; set; }
}
I then want to see this in the following view:
#using TSW.Web.Helpers
#model TSW.Web.ViewModels.CourseDetailVM
#{
Layout = "~/Views/_Master.cshtml";
}
#Model.DBTitle.Title;
I have the following controller already in place (sorry for the length I plan to reduce this down):
public class CourseDetailController : BaseRenderController<CourseDetailPageDT>
{
private readonly ISitePageFactory _pageFactory = null;
private readonly IEventService _eventService = null;
public CourseDetailController(IEventService eventService, ISitePageFactory pageFactory)
{
_pageFactory = pageFactory;
_eventService = eventService;
}
public async Task<ActionResult> CourseDetail()
{
var homepage = _pageFactory.GetCurrentHomepage();
var model = Mapper.Map<CourseDetailVM>(CurrentContent);
model.Email = homepage.ContactEmail;
model.PhoneNumber = homepage.HeaderPhoneNumber;
model.InnerPageHeader.ShowHeading = true;
model.InnerPageHeader.Title = model.PageTitle;
if (model.Categories.Count == 1)
{
var categoryTagId = model.Categories.First().Id;
var contentTypeAlias = DocumentTypeHelper.GetDocumentTypeAlias<CourseListingPageDT>();
var courseCategoryPage = Umbraco.TypedContentAtXPath($"//{contentTypeAlias}")
.FirstOrDefault(x => x.GetPropertyValue<int>(Constants.DocumentTypes.CourseListingPage.Category) == categoryTagId);
if (courseCategoryPage != null)
{
model.InnerPageHeader.BackLink = Mapper.Map<LinkItem>(courseCategoryPage.Id);
}
}
try
{
model.Events = await _eventService.GetEventsForCourse(CurrentContent.AdministrateId);
}
catch (Exception ex)
{
model.Events = new StaticPagedList<Event>(Enumerable.Empty<Event>(), 1, 1, 0);
Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
}
if (CurrentContent.Graphic != 0)
{
model.InnerPageHeader.Graphic = Mapper.Map<CtaItem>(CurrentContent.Graphic);
}
return View(model);
}
}
I've tried every suggestion I can google to add the mapping in the controlling but can't get my head around this simple function of pulling the value from a SQL database into the razor view.
Could anyone help me out?

Passing List from View to Controller - MVC4

I am now kind of stuck here.
I have my Models here
namespace DSS.Models
{
public class SupplierItems
{
public string GroupID { get; set; }
public string GroupName { get; set; }
public List<SupplierLineItems> LineItems { get; set; }
}
}
and have Properties of Supplier Items are defined in Model as
namespace DSS.Models
{
public class SupplierLineItems
{
public string Frequency { get; set; }
public string UnitPrice { get; set; }
public int Index { get; set; }
}
}
My Controller is just hardcoding the Supplier Items and line items
namespace DSS.Controllers
{
public class HomeController : Controller
{
[HttpPost]
public ActionResult GetLineItems(SupplierItems SupplierItems)
{
return View();
}
public ActionResult Index()
{
List<SupplierLineItems> ListOfLineItems = new List<SupplierLineItems>();
SupplierLineItems LineItems = new SupplierLineItems();
LineItems.Frequency = "Regulate";
LineItems.UnitPrice = "20";
LineItems.Index = 1;
ListOfLineItems.Add(LineItems);
SupplierLineItems LineItems1 = new SupplierLineItems();
LineItems1.Frequency = "Regulate";
LineItems1.UnitPrice = "20";
LineItems.Index = 2;
ListOfLineItems.Add(LineItems1);
SupplierItems Items = new SupplierItems();
Items.GroupID = "1";
Items.GroupName = "Core Group";
Items.LineItems = ListOfLineItems;
return View(Items);
}
}
}
Here is my View
#model DSS.Models.SupplierItems
#using DSS.Models
#{
ViewBag.Title = "Home Page";
{
<a type="submit" href="#Url.Action("GetLineItems", "Home", Model)">#Model.GroupName</a>
<br />
foreach (var item in Model.LineItems)
{
#item.Frequency<br />
#item.UnitPrice<br />
#item.Index<br />
}
}
}
When I click on Anchor tag of my view and pass the Model to "GetLineItems" of Home Controller, My Supplier items get passed successfully but List of Line items always comes as null. I am not sure what is going wrong . Anyone, please help
enter code here
You should use ajax post to the controller or simply use form submission to achieve this
instead of using url.action which is an url form of submission

MVC 4 model values not passed to controller action

I have view and want to display content from the object stored in session one by one when user clicks on NEXT button. View uses WorldModel object to display the data. Id is hidden field and Content should be displayed on page.
View:
#model MvcApplication4.Models.WorldModel
#{
ViewBag.Title = "View1";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>View1</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.ValidationSummary()
<fieldset>
#Html.HiddenFor(model => model.Id)
#Html.DisplayFor(model => model.Content)
<input type="submit" value="Next" />
</fieldset>
}
Model: This class contains two properties id and content. Basically id is mapped to candidate id and Content is mapped to candidate name.
namespace MvcApplication4.Models
{
public class WorldModel
{
public int Id { get; set; }
public string Content { get; set; }
}
}
Controller: Class has two action methods one doesn’t take any parameter and other takes WorldModel as parameter.
namespace MvcApplication4.Controllers
{
public class WorldController : Controller
{
//
// GET: /World/
public ActionResult View1()
{
List<Candidate> obj = new List<Candidate>();
obj.Add(new Candidate() { Id = 1, Name = "ABCD", IsNameDispalyed = false});
obj.Add(new Candidate() { Id = 2, Name = "PQR", IsNameDispalyed = false });
obj.Add(new Candidate() { Id = 3, Name = "XYZ", IsNameDispalyed = false });
CandidateSession cs = new CandidateSession(){Candidates=obj};
Session["Can"] = cs;
return View();
}
[HttpPost]
public ActionResult View1(WorldModel worldModel)
{
CandidateSession cs = (CandidateSession)Session["Can"];
var can1 = cs.Candidates.Where(x => x.IsNameDispalyed == false).First();
can1.IsNameDispalyed = true;
return View(new WorldModel() {Id=can1.Id, Content=can1.Name });
}
}
public class Candidate
{
public int Id { get; set; }
public string Name { get; set; }
public bool IsNameDispalyed { get; set; }
}
public class CandidateSession
{
public List<Candidate> Candidates { get; set; }
}
}
When I access URL as “../World/View1” it fills data to session object and click on NEXT button calls the action public ActionResult View1(WorldModel worldModel). In the method I get the object whose info is not displayed return the view with WorldModel object with id and Content. Now first time the Content is displayed but when the I click on NEXT button it call action public ActionResult View1(WorldModel worldModel). But the id and Content values of worldModel object are null. Why data is null, I set the values in the previous call?

Can't get ASP.Net MVC Edit Action to worth with my ViewModel

I am trying to use the following ViewModel
public class ProjectViewModel
{
public Project Project { get; set; } //bulk of the information
public int SelectedGovernmentClientId { get; set; } //selected ID for the dropdown
public IEnumerable<SelectListItem> GovernmentClients { get; set; } //dropdown values
}
Here's my project class
public class Project
{
public int ID { get; set; }
public string Title { get; set; }
//omitting extra fields
public virtual GovernmentClient GovernmentClient { get; set; }
}
Here's the action that I have
[HttpPost]
public ActionResult Edit(ProjectViewModel projectViewModel)
{
if (ModelState.IsValid)
{
//i am getting the following from debugging
//projectViewModel.Project.GovernmentClient.Name is NULL
//projectViewModel.Project.GovernmentClient.ID is the correct ID from the dropdown
db.Entry(projectViewModel.Project).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(projectViewModel);
}
All the values are getting updated EXCEPT the government client. Why is this happening?
projectViewModel.Project.GovernmentClient =
db.GovernmentClients.Find(projectViewModel.SelectedGovernmentClientId);
You are retrieving the value from database and setting its state to modified. However, there is no modification at all.
After a whole day of playing around with this, I think I might've solved it
I added the following to my Project model
[ForeignKey("GovernmentClient")]
public int GovernmentClient_ID { get; set; }
To render the dropdown, I used this
#Html.DropDownListFor(model => model.Project.GovernmentClient_ID, Model.GovernmentClients)
To generate the GovernmentClients list, I used the following method
private IEnumerable<SelectListItem> GetGovernmentClientsList(int selectedItem = -1)
{
var defaultItem = Enumerable.Repeat(new SelectListItem
{
Value = "-1",
Text = " - Select a government client - ",
Selected = (selectedItem == -1)
}, count: 1);
var clients = db.GovernmentClients.ToList().Select(x => new SelectListItem
{
Value = x.ID.ToString(),
Text = x.ClientName,
Selected = (selectedItem == -1) ? false : (x.ID == selectedItem)
});
return defaultItem.Concat(clients);
}
Overall, I am happy with this, because I am not hardcoding any property names, which I know would come back and bite me.

DropDownList with possible nested DropDownList in MVC4

I have a set of questions the user can choose from and some of those questions have a secondary list of options to choose from. My goal is to have a drop down list and if you pick one of the options that has items in its SecondaryChoiceList then a second list would appear below the initial dropdown and all of this would be strongly typed and bound to the model upon submission.
I can get the initial list to appear by saying:
#Html.DropDownListFor( x => x.SelectedChoiceId, new SelectList(Model.Choices, "Id", "Name"))
But that has no hooks to the secondary list and I am completely lost as to how I would tie that secondary list back to the model that is returned when I submit the form.
Here's my view model:
public class ExampleViewModel
{
public List<Choice> ChoiceList { get; set; }
public int SelectedChoiceId { get; set; }
public int SelectedAffiliateId { get; set; }
}
Here is what a Choice looks like:
public class Choice
{
public int Id { get; set; }
public string Name { get; set; }
public IEnumerable<SecondaryChoice> SecondaryChoiceList { get; set; }
public Choice()
{
SecondaryChoiceList = new List<SecondaryChoice>();
}
}
And here is my SecondaryChoice object:
public class EligibleAffiliate
{
public int Id { get; set; }
public int EligibilityChoiceId { get; set; }
public string Name { get; set; }
}
If there is anything that I can clear up let me know.
I have tried to keep it as simple as possible.
So, a sample model is given below:
namespace StackOverflow.Models
{
public class Choice
{
public int Id { get; set; }
public string Name { get; set; }
public Choice()
{
Id = 0;
}
public Choice(int id, string name)
{
Id = id;
Name = name;
}
}
}
namespace StackOverflow.Models
{
public class ExampleViewModel
{
public List<Choice> PrimaryChoiceList { get; set; }
public List<Choice> SecondaryChoiceList { get; set; }
public int SelectedChoiceId { get; set; }
public int SelectedAffiliateId { get; set; }
public ExampleViewModel()
{
SelectedChoiceId = 0;
SelectedAffiliateId = 0;
PrimaryChoiceList = new List<Choice>()
{
new Choice(1, "How are you?"),
new Choice(2, "How is the weahter?"),
new Choice(3, "What have you been doing so far?"),
new Choice(4, "What's up man?"),
new Choice(5, "Any news?"),
new Choice(5, "Bla bla bla")
};
SecondaryChoiceList = new List<Choice>()
{
new Choice(1, "How are you dear?"),
new Choice(2, "How is the weahter?"),
new Choice(3, "What have you been doing so far dear?"),
new Choice(4, "What's up man?"),
new Choice(5, "Any romantic news?")
};
}
}
}
Sample controller:
namespace StackOverFlow.Controllers
{
public class SOController : Controller
{
public static ExampleViewModel evm = new ExampleViewModel();
public ActionResult Index()
{
return View(evm);
}
public ActionResult SetSelection(int id)
{
evm.SelectedChoiceId = id;
if (evm.PrimaryChoiceList.Count() > 0)
{
Choice selection = evm.PrimaryChoiceList.ElementAt(id-1);
Choice affiliate = (Choice)evm.SecondaryChoiceList.FirstOrDefault(x => x.Name == selection.Name);
if (affiliate != null)
{
return Content("show");
}
else
{
return Content("hide");
}
}
else
{
return Content("hide");
}
}
}
}
And the web page:
#using StackOverflow2.Models;
#model ExampleViewModel
<script src="#Url.Content("~/Scripts/jquery-1.7.1.min.js")" type="text/javascript"></script>
#{
ViewBag.Title = "Stackoverflow Sample";
}
<h2>Index</h2>
<script type="text/javascript">
// Get the selection and make Ajax Request to the controller, action: SetSelection,
// which in turn may decide whetger you must show or hide the control
function updateSeconadryQuestion(id) {
var xmlhttp;
if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
}
else {// code for IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
if (xmlhttp.responseText == 'show')
$('#SecondaryQuestionDropBoxId').show();
else
$('#SecondaryQuestionDropBoxId').hide();
}
}
xmlhttp.open("GET", "/SO/SetSelection?id=" + id, true);
xmlhttp.send();
}
</script>
#Html.DropDownListFor(x => x.SelectedChoiceId, new SelectList(Model.PrimaryChoiceList, "Id", "Name", "Value"), new { id = "PrimaryQuestionDropBoxId", onchange = "updateSeconadryQuestion(value);" })
<div id="SeconadryQuestionDivId">
#Html.DropDownListFor(x => x.SelectedAffiliateId, new SelectList(Model.SecondaryChoiceList, "Id", "Name"), new { id = "SecondaryQuestionDropBoxId" })
</div>