Cannot get the value of #Html.DropDownList - c#

I have a Create cshtml Page as follows :-
#model MvcCommons.ViewModels.CompositeViewModel
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")"></script>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Article</legend>
<div class="editor-label">
#Html.LabelFor(model => model.ArticleViewModel.Article.ArticleTitle)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ArticleViewModel.Article.ArticleTitle)
#Html.ValidationMessageFor(model => model.ArticleViewModel.Article.ArticleTitle)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ArticleViewModel.Article.ArticleDate)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ArticleViewModel.Article.ArticleDate)
#Html.ValidationMessageFor(model => model.ArticleViewModel.Article.ArticleDate)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ArticleViewModel.Article.ArticleText)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ArticleViewModel.Article.ArticleText)
#Html.ValidationMessageFor(model => model.ArticleViewModel.Article.ArticleText)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ArticleViewModel.Article.ArticleSource)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ArticleViewModel.Article.ArticleSource)
#Html.ValidationMessageFor(model => model.ArticleViewModel.Article.ArticleSource)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ArticleViewModel.Article.CategoryID, "Category")
</div>
<div class="editor-field">
#Html.DropDownList("CategoryID", String.Empty)
#Html.ValidationMessageFor(model => model.ArticleViewModel.Article.CategoryID)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
and then I am getting the viewModel inside the Create Action as follows :-
[HttpPost]
public ActionResult Create(CompositeViewModel viewModel)
{
if (ModelState.IsValid)
{
unitOfWork.ArticleRepository.Insert(viewModel.ArticleViewModel.Article);
unitOfWork.Save();
return RedirectToAction("Index");
}
PopulateDropDownList(viewModel.ArticleViewModel.Article.CategoryID);
return View(viewModel);
}
The PopulateDropDownList code is as follows :-
private void PopulateDropDownList(object selectedCategory = null)
{
var categoryQuery = unitOfWork.CategoryRepository.Get(
orderBy: q => q.OrderBy(d => d.CategoryTitle));
ViewBag.CategoryID = new SelectList(unitOfWork.CategoryRepository.Get(), "CategoryID", "CategoryTitle", selectedCategory);
}
My problem is that the CategoryID inside the CompositeViewModel viewModel is always 0 no matter what values I choose in the dropdown list! The other data entered in the Create cshtml is filled correctly inside the viewModel.
I cannot spot what I am doing wrong.
Thanks for your help and time

Shouldn't you be using DropDownListFor:
#Html.DropDownListFor(model => model.ArticleViewModel.Article.CategoryID, (SelectList)ViewBag.CategoryID)

You should write
#Html.DropDownList("ArticleViewModel.Article.CategoryID", ViewBag.CategoryID, null)
so ModelBinding works correctly or even use DropDownListFor<>().

Related

Getting Database Error while Customising CRUD in MVC4

The INSERT statement conflicted with the FOREIGN KEY constraint
"FK_tblCompInfo_tblOSVersion". The conflict occurred in database
"Sample", table "dbo.tblOSVersion", column 'VerID'. The statement has
been terminated.
{
db.CompInfoes.Add(compinfo);
db.SaveChanges();
return RedirectToAction("Index");
}
Tried to customize Create.cshtml with the following code:
#model MvcApplication1.Models.CompInfo
#{
ViewBag.Title = "Create";
}
<script src="~/Scripts/angular.min.js"></script>
<script src="~/Scripts/MyApp.js"></script>
<script src="~/Scripts/DropDownController.js"></script>
<h2>Create</h2>
<div style="font-family:Arial">
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>CompInfo</legend>
<div class="editor-label">
#Html.LabelFor(model => model.EmpName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.EmpName)
#Html.ValidationMessageFor(model => model.EmpName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ComputerName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ComputerName)
#Html.ValidationMessageFor(model => model.ComputerName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ServiceTag)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ServiceTag)
#Html.ValidationMessageFor(model => model.ServiceTag)
</div>
<div class="editor-label">
<div ng-app="MyApp" ng-controller="DropDownController">
Country : <select ng-model="OSID" ng-options="I.OSID as I.OSName for I in OSList" ng-change="GetVersion()">
<option value="">Select OS</option>
</select><br />
State : <select ng-model="VerID" ng-options="I.VerID as I.VerName for I in VersionList">
<option value="">{{VersionTextToShow}}</option>
</select>
</div>
</div>
#*<div class="editor-label">
#Html.LabelFor(model => model.OSID, "OperatingSystem")
</div>
<div class="editor-field">
#Html.DropDownList("OSID", String.Empty)
#Html.ValidationMessageFor(model => model.OSID)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.VerID, "OSVersion")
</div>
<div class="editor-field">
#Html.DropDownList("VerID", String.Empty)
#Html.ValidationMessageFor(model => model.VerID)
</div>*#
<div class="editor-label">
#Html.LabelFor(model => model.IP)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.IP)
#Html.ValidationMessageFor(model => model.IP)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.EmailID)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.EmailID)
#Html.ValidationMessageFor(model => model.EmailID)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.SysTypeID, "SystemType")
</div>
<div class="editor-field">
#Html.DropDownList("SysTypeID", String.Empty)
#Html.ValidationMessageFor(model => model.SysTypeID)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.CStatusID, "StatusComputer")
</div>
<div class="editor-field">
#Html.DropDownList("CStatusID", String.Empty)
#Html.ValidationMessageFor(model => model.CStatusID)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
</div>
As of the error saying the data is not feeded to foreign key column or data is not supported to the mapping table.
There can be two options
1.if the data for foreign key should be null. The foreign key column should be alterted to allow null.
2.if the one to many mapping is correct only the mapping table data will be feeded correctly with " db.CompInfoes.Add(compinfo); "

InvalidOperationException in editing role

I get this problem whenever I save the changes I made when changing the roles of a user:
"An exception of type 'System.InvalidOperationException' occurred in
System.Web.Mvc.dll but was not handled in user code. Additional
information: The ViewData item that has the key 'URole' is of type
'System.Int32' but must be of type 'IEnumerable'"
These are the codes of my
GET and POST Edit ` //
// GET: /AccountAdmin/Edit/5
public ActionResult Edit(int id)
{
Account account = db.Accounts.Find(id);
if (account == null)
{
return HttpNotFound();
}
RoleDropDownList(account.URole);
return View(account);
}
//
// POST: /AccountAdmin/Edit/5
[HttpPost]
public ActionResult Edit(Account account)
{
try
{
if (ModelState.IsValid)
{
db.Entry(account).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
RoleDropDownList(account.URole);
return View(account);
}
catch (Exception ex)
{
return View(account);
}
}`
And this is the Edit View
#model MvcApplication3.Models.Account
#ViewBag.Title = "Edit";
<h2>Edit</h2>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Account</legend>
<div class="editor-label">
#Html.LabelFor(model => model.AccID)
</div>
<div class="editor-field">
#Html.DisplayFor(model => model.AccID)
#Html.ValidationMessageFor(model => model.AccID)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.UName)
</div>
<div class="editor-field">
#Html.DisplayFor(model => model.UName)
#Html.ValidationMessageFor(model => model.UName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Pword)
</div>
<div class="editor-field">
#Html.DisplayFor(model => model.Pword)
#Html.ValidationMessageFor(model => model.Pword)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.FName)
</div>
<div class="editor-field">
#Html.DisplayFor(model => model.FName)
#Html.ValidationMessageFor(model => model.FName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.LName)
</div>
<div class="editor-field">
#Html.DisplayFor(model => model.LName)
#Html.ValidationMessageFor(model => model.LName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.URole, "Role")
</div>
<div class="editor-field">
#Html.DropDownList("URole", String.Empty)
#Html.ValidationMessageFor(model => model.URole)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts{
<script src="#System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/bundles/jqueryval")"></script>
}
What could be the problem? Thanks in advance!

Update object with new relationships before post changes

I have a model named "Professional" that have as attribute a list of other objects named "Skill".
At my edit page I'm trying to do something that will list all skills persisted at database and the user will choice someone and create a link with that skill.
But I have no idea how can i achieve this:
My Edit View:
#model TCCApplication.Models.ProfessionalModel
#{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>ProfessionalModel</legend>
#Html.HiddenFor(model => model.Id)
#Html.HiddenFor(model => model.UserAccount.Id)
#Html.HiddenFor(model => model.UserAddress.Id)
<div class="editor-label">
#Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.BirthDate)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.BirthDate)
#Html.ValidationMessageFor(model => model.BirthDate)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.PhoneNumber)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.PhoneNumber)
#Html.ValidationMessageFor(model => model.PhoneNumber)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Profession)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Profession)
#Html.ValidationMessageFor(model => model.Profession)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.UserAccount.Username)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.UserAccount.Username)
#Html.ValidationMessageFor(model => model.UserAccount.Username)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.UserAccount.Password)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.UserAccount.Password)
#Html.ValidationMessageFor(model => model.UserAccount.Password)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.UserAddress.Street)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.UserAddress.Street)
#Html.ValidationMessageFor(model => model.UserAddress.Street)
</div>
<fieldset class="row">
<legend>Habilidades</legend>
#foreach (var skill in Model.Skills)
{
#Html.HiddenFor(sk => skill.Id)
<div class="col-md-10">
<div class="display-label">
#Html.Label("Nome da habilidade: ")
#Html.DisplayFor(sk => skill.Name)
</div>
<div class="display-label">
#Html.Label("Descrição")
#Html.DisplayFor(sk => skill.Description)
</div>
<div class="display-label">
#Html.Label("Categoria: ")
#Html.DisplayFor(sk => skill.Category.Name)
</div>
</div>
<div class="col-md-2">
#Html.ActionLink("Deletar Skill", "DeleteSkill", new { skillId = skill.Id, professionalId = Model.Id })
</div>
}
<p>
<div>
#Html.DropDownList("Skills", (IEnumerable<SelectListItem>)ViewBag.skills)
</div>
</p>
<div>
#Html.ActionLink("Adicionar habilidade não presente na lista", "AddNewSkill", new { professionalId = Model.Id})
</div>
</fieldset>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
This will get a list of distinct strings from the database.
Controller:
ViewBag.Skills = db.Skills.OrderBy(c=>c.Name).Select(c => c.Name).Distinct().ToList();
This will put the strings gathered previously into a multi-select list.
View:
#Html.DropDownListFor(model => model.Skills, ((List<int>)ViewBag.Skills).Select(m=> new SelectListItem{Value = m.ToString(CultureInfo.InvariantCulture), Text = m.ToString(CultureInfo.InvariantCulture)}), new {multiple = "multiple"})
You can approach this a bit more intelligently by creating a list of SelectListItems from the result of your db result by putting the value to the ID and the text to the name. That'll make it easier to save changes later.

Asp.Net MVC4 Display CheckboxList

I have searched a lot and spend 3 days only for searching and trying different technique (on stackoverflow etc) but I find no solution for implementing checkboxlist in asp.net mvc. And at last I am posting my problem to stackoverflow;
So, my model looks like this;
Many to Many relationship of my model(1 category may contain many projects and a project may belongs to many categories)
My controller;
[HttpGet]
[Authorize(Roles = "Admin")]
public ActionResult ProjectAdd()
{
return View();
}
My view;
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<fieldset>
<legend>Add New Project</legend>
<div class="editor-label">
#Html.LabelFor(model => model.ProjectHeading)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ProjectHeading)
#Html.ValidationMessageFor(model => model.ProjectHeading)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ProjecctUrl)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ProjecctUrl)
#Html.ValidationMessageFor(model => model.ProjecctUrl)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ProjectLongDescription)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ProjectLongDescription)
#Html.ValidationMessageFor(model => model.ProjectLongDescription)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.PromoFront)
</div>
#Html.EditorFor(model => model.PromoFront)
#Html.ValidationMessageFor(model => model.PromoFront)
<div class="editor-label">
#Html.LabelFor(model => model.ProjectThubmnail)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ProjectThubmnail)
#Html.ValidationMessageFor(model => model.ProjectThubmnail)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ProjectImage)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ProjectImage)
#Html.ValidationMessageFor(model => model.ProjectImage)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.CategoryId)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.CategoryId)
#Html.ValidationMessageFor(model => model.CategoryId)
</div>
<p>
<input type="submit" value="Create" class="submit" />
</p>
So, my question is How do I display checkboxlist for categories in my view?
How do I get selected values from that checkboxlist?
You need to have an object that will have a list of all categories, for example, you could do this:
[HttpGet]
[Authorize(Roles = "Admin")]
public ActionResult ProjectAdd()
{
// Get all categories and pass it into the View
ViewBag.Categories = db.ListAllCategories();
return View();
}
in the top of your View
#model Database.Project
#{
// retrieve the list of Categories
List<Database.Category> categories = ViewBag.Categories;
}
and then replace this
<div class="editor-label">
#Html.LabelFor(model => model.CategoryId)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.CategoryId)
#Html.ValidationMessageFor(model => model.CategoryId)
</div>
for this
<div class="editor-label">
<label for="categories">Categories</label>
</div>
<div class="editor-field">
#foreach(var c in categories) {
<label class="checkbox">
<input type="checkbox" name="categories" value="#c.CategoryId"> #c.CategoryName
</label>
}
</div>
back in your Controller
[HttpPost]
[Authorize(Roles = "Admin")]
public ActionResult ProjectAdd(Database.Project model, int[] categories)
{
if(ModelState.IsValid) {
// fill up categories
db.InsertAndSaveProject(model, categories);
}
...
return redirectToView("ProjectAdd");
}
Answer suggested by #balexandre above works great. However, I used following HTML Extension for CheckBoxList.
1. CheckboxList in ASP.net MVC4
2. Source Code:HTML Extension Helper method (Github)
The Major advantage of using this helper method is clean code and better readability. E.g.
#Html.CheckBoxListFor(model => model.SelectedItems, Model.AllItems)

How can I validate if a user has written in the same two passwords correctly in my view?

Here is my table schema:
Here is my controller:
public ActionResult Register()
{
return View();
}
[HttpPost]
public ActionResult Register(FormCollection formValues)
{
return View();
}
And here is my Register view:
#model LocalizationWebsite.Models.SiteUser
#{
ViewBag.Title = "Localization | Create Account";
}
<h2>Create Your Account</h2>
<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)
<div class="editor-label">
#Html.LabelFor(model => model.Username)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Username)
#Html.ValidationMessageFor(model => model.Username)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Password)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Password)
#Html.ValidationMessageFor(model => model.Password)
</div>
<div class="editor-label">
#Html.EditorFor(model => model.Password)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Password)
#Html.ValidationMessageFor(model => model.Password)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Email)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Email)
#Html.ValidationMessageFor(model => model.Email)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.AvatarPath)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.AvatarPath)
#Html.ValidationMessageFor(model => model.AvatarPath)
</div>
<p>
<input type="submit" value="Create" />
</p>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
How do you suggest I check if the same password was written in both fields? If possible, I'd like to do this automatically as the user is typing in.
Thank you for the help.
You could decorate your view model properties with the [Compare] validation attribute to ensure that two propery values are matching.
If you want to do it from scratch, I would suggest using a little JQuery or javascript. This will give you control over how to do it "automatically."
But, if you can use the [Compare] attribute on the ViewModel, then this post from Scott Gu will allow you to use client-side validation via the DataAnnotations.
Use the CompareAttribute. Good article: http://davidhayden.com/blog/dave/archive/2011/01/01/CompareAttributeASPNETMVC3.aspx

Categories

Resources