Firstly, my point is to create a project. Users will be able to choose a parent project of this project from dropdownlist. When users choose a parent project of the project, this should be saved to the database(db) as a parent project property.
My error Message is below.
[System.InvalidOperationException] = {"The parameter conversion from type 'System.String' to type 'ProjectName.Models.Project' failed because no type converter can convert between these types."}
my ProjectsController Actions:
//GET
public ActionResult Create()
{
var projectList = db.Projects.ToList().Select(
c => new SelectListItem
{
Selected = false,
Text = c.projectName,
Value = c.projectID.ToString()
}
).ToList();
ViewData["ProjectList"] = projectList;
return View();
}
//
// POST: /Project/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Project project)
{
var projectList = db.Projects.ToList().Select(
c => new SelectListItem
{
Selected = false,
Text = c.projectName,
Value = c.projectID.ToString()
}
).ToList();
ViewData["ProjectList"] = projectList;
if (ModelState.IsValid)
{
db.Projects.Add(project);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(project);
}
my Project class :
public class Project{
public int projectID { get; set; }
public string projectName { get; set; }
public string descriptionProject { get; set; }
public Project parentProject { get; set; }
}
my Context class:
public class DBContext : DbContext
{
public DbSet<User> Users { get; set; }
public DbSet<Project> Projects { get; set; }
public DbSet<Issue> Issues { get; set; }
}
and finally my view :
@model ProjectName.Models.Project
....
<div class="form-group">
@Html.LabelFor(model => model.parentProject, new { @class = "col-lg-2 control-label" })
<div class="col-lg-10">
<p>@Html.DropDownListFor(model => model.projectID, (IEnumerable<SelectListItem>)ViewData["ProjectList"], " --Select Parent Project--")</p>
@Html.ValidationMessageFor(model => model.parentProject)
</div>
</div>
I am waiting your responses. Thanks in advance. By the way, I am using mvc 5.2, visual studio 2013 update 2.
In your controller: add the list of select items to your view model instead of viewBag or view data since they are not strongly typed.It's a good practice to do so. do not convert in the HtmlHelper.
By the way, here is a generic method I created to populate dropdown lists in one of my projects.You can even append static values like All or Nothing.
public IEnumerable<SelectListItem> GetSelection<T>(IEnumerable<T> data,
Func<T, string> name = null,
Func<T, string> key = null,
string defaultValue = "0",
bool showAllValue = true,
bool showNothing = false)
{
var selectItemList = new List<SelectListItem>();
if (showAllValue)
{
selectItemList.Add(new SelectListItem { Text = "Choose All", Value = 0 });
}
if (showNothing)
{
selectItemList.Add(new SelectListItem { Text = "Nothing Selected", Value = -1 });
}
selectItemList.AddRange(data.Select(item => key != null ? (name != null ? new SelectListItem
{
Text = name(item),
Value = key(item)
} : null) : null));
//default selection
var defaultItem = selectItemList.FirstOrDefault(x => x.Value == defaultValue);
if (defaultItem != null)
{
defaultItem.Selected = true;
}
else
{
var firstItem = selectItemList.FirstOrDefault();
if (firstItem != null) firstItem.Selected = true;
}
return selectItemList;
}
You can call it like this:
public IEnumerable<SelectListItem> GetClientSelectionList(string defaultClient = "0", bool showAllValue = false)
{
return this.GetSelection(data: _clientsManager.GetClients(),
name: s => s.Client_Name,
key: s => s.Client_ID.ToString(CultureInfo.InvariantCulture),
defaultValue: defaultClient,
showAllValue: showAllValue
);
}