ASP.NET MVC 5 Set values for dropdownlist - c#

I want to make a DropDownList with a numeric rating from 1-5. I have a rating model and I want to apply these dropdown values to WaitTime, Attentive and Outcome.
Can I just set these values in the view and use the model? If so how would i go about doing this?
My Model Class:
public class Ratings
{
//Rating Id (PK)
public int Id { get; set; }
public string UserId { get; set; }
//Medical Practice (FK)
public int MpId { get; set; }
public MP MP { get; set; }
//User ratings (non-key values)
[Required] //Adding Validation Rule
public int WaitTime { get; set; }
[Required] //Adding Validation Rule
public int Attentive { get; set; }
[Required] //Adding Validation Rule
public int Outcome { get; set; }
}
My View:
<div class="form-group">
#Html.LabelFor(model => model.WaitTime, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.WaitTime, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.WaitTime, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Attentive, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Attentive, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Attentive, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Outcome, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Outcome, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Outcome, "", new { #class = "text-danger" })
</div>
</div>

Use this instead of EditorFor for each field:
#Html.DropDownListFor(model => model.Outcome, new SelectList(Enumerable.Range(1, 5)))

Here is the working fiddle - https://dotnetfiddle.net/daB2DI
In short, lets say your model is -
public class SampleViewModel
{
[Required] //Adding Validation Rule
public int WaitTime { get; set; }
[Required] //Adding Validation Rule
public int Attentive { get; set; }
[Required] //Adding Validation Rule
public int Outcome { get; set; }
}
And your controller actions are -
[HttpGet]
public ActionResult Index()
{
return View(new SampleViewModel());
}
[HttpPost]
public JsonResult PostData(SampleViewModel model)
{
return Json(model);
}
Your Get CSHTML should be -
#model HelloWorldMvcApp.SampleViewModel
#{
ViewBag.Title = "GetData";
}
<h2>GetData</h2>
#{
var items = new List<SelectListItem>();
for (int i = 1; i < 6; i++)
{
var selectlistItem = new SelectListItem();
var code = 0;
selectlistItem.Text = (code + i).ToString();
selectlistItem.Value = (code + i).ToString();
items.Add(selectlistItem);
}
}
#using (Html.BeginForm("PostData","Home"))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>SampleViewModel</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.WaitTime, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.WaitTime, items, "--Select--", new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.WaitTime, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Attentive, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.Attentive, items, "--Select--", new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Attentive, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Outcome, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.Outcome, items, "--Select--", new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Outcome, "", new { #class = "text-danger" })
</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>
}
When you run the code, you should see page like below -
And when you select some values and click on create, you should get those values in PostData action.

try to adapt this to your project
in your controller:
ViewBag.ParentID = new SelectList(departmentsQuery, "NewsMID", "Title", selectedDepartment);
return View(model);
in your view put this
#Html.DropDownList("ParentID")

Related

when clicking on create new hole Would like to be able to select a courseId

I am trying to create a golf score app. I have created the database that has the following tables Round, Course and Hole.
The hole table has a foreign key to the courseId as when I create each hole I want to link it to a course.
When clicking on the create new I would like to have a dropdown list to select the courseId from when inputting all the hole details.
But when I click on the create new I get the following error in the Hole view model.
System.ArguementNullException: Value can not be Null. Parameter name items. in my Create action code within the HoleViewModelController.
This is my HoleViewModel code
public class HoleViewModel
{
[Key]
public int HoleId { get; set; }
public int HoleNumber { get; set; }
public int Par { get; set; }
public int Length { get; set; }
public int StrokeIndex { get; set; }
[ForeignKey("Course")]
public int? CourseId { get; set; }
public IEnumerable<SelectListItem> CourseNamesDropdownList { get; set; }
public virtual CourseViewModel Course { get; set; }
}
}
This is my CourseViewModel code
public class CourseViewModel
{
[Key]
public int CourseId { get; set; }
public string CourseName { get; set; }
This is my HoleViewModelController Create action
public ActionResult Create()
{
ViewBag.CourseId = new SelectList(db.CourseViewModels, "CourseId", "CourseName");
return View();
}
This is my MVC Create view
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>HoleViewModel</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.HoleNumber, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.HoleNumber, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.HoleNumber, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Par, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Par, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Par, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Length, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Length, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Length, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.StrokeIndex, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.StrokeIndex, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.StrokeIndex, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.CourseId, "CourseId", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.Course.CourseId, Model.CourseNamesDropdownList, "Please select from List", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.CourseId, "", new { #class = "text-danger" })
</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>
Ok so i resolved this issue by ammending the ActionResult Create code from
public ActionResult Create()
{
ViewBag.CourseId = new SelectList(db.CourseViewModels, "CourseId", "CourseName");
return View();
}
To
public ActionResult Create()
{
var dbcourse = db.Course.ToList();
//Make selectlist, which is IEnumerable<SelectListItem>
var courseNameDropdownList = new SelectList(db.Course.Select(item => new SelectListItem()
{
Text = item.CourseName.ToString(),
Value = item.CourseId.ToString()
}).ToList(), "Value", "Text");
// Assign the Selectlist to the View Model
var viewCourse = new HoleViewModel()
{
Course = dbcourse.FirstOrDefault(),
// The Dropdownlist values
CourseNamesDropdownList = courseNameDropdownList,
};
//ViewBag.CourseId = new SelectList(db.CourseViewModels, "CourseId", "CourseName");
return View(viewCourse);
}
This has allowed the dropdown to be populated and be added to the view.

How to do a model binding of an entity that contains a list of another entity?

I want make a form using a model that contains a list of another entity, but I don't know how to do it. Note: without Entity Framework.
I have use only a model that contains only its fields, but not another entity.
My code is:
Tarea.cs
public class Tarea
{
public int ID { get; set; }
public string NombreTarea { get; set; }
public int TiempoTarea { get; set; }
}
Employee.cs
public class Employee
{
public int ID { get; set; }
public string Name { get; set; }
public DateTime JoiningDate { get; set; }
public int Age { get; set; }
public List<Tarea> Tareas { get; set; }
}
And my view is:
Create.cshtml
#model MVCSimpleApp.Models.Employee
....
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Employee</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Name, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Name, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Name, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.JoiningDate, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.JoiningDate, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.JoiningDate, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Age, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Age, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Age, "", new { #class = "text-danger" })
</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>
}
I don't know how to put the List<Tarea> in the form. Thanks in advance.
For Example, if we want to collect two sets of Tareas model,
View Code:
#for (var item = 0; item < 2; item++)
{
#Html.HiddenFor(model => model.Tareas[item].ID)
#Html.TextBoxFor(model => model.Tareas[item].NombreTarea, new { #class = "form-control" })
#Html.TextBoxFor(model => model.Tareas[item].TiempoTarea, new { #class = "form-control" })
}
And in the Post Create Action Method..
[HttpPost]
public ActionResult Create(Employee model)
{
// here we we get the all values given from the view ...
string example = model.Name;
List<Tarea> list = model.Tareas; // and iterate through model.Tareas to get List model values
}

Can't bind dropdownlist in a partial view in Code First Entity Framework

I'm new to MVC, so apologies for the noob question!
I have the following model (TimeEntry), used for entering timesheet details:
namespace MVCLogin.Models
{
public class TimeEntry
{
public int TimeEntryID { get; set; }
public int TaskTypeID { get; set; }
[ForeignKey("TaskTypeID")]
public virtual TaskType TaskType { get; set; }
public double MonHours { get; set; }
public double TueHours { get; set; }
public double WedHours { get; set; }
public double ThuHours { get; set; }
public double FriHours { get; set; }
}
}
Task type is based on the following model:
namespace MVCLogin.Models
{
public class TaskType
{
public int TaskTypeID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
}
I use the following partial view which is used for entering the timesheet details:
<div class="col-md-1">
#Html.EditorFor(model => model.TaskType)
#Html.ValidationMessageFor(model => model.TaskType)
</div>
<div class="col-sm-1">
#Html.TextBoxFor(model => model.MonHours , new { style = "width:100%", #class = "hours mon" })
#Html.ValidationMessageFor(model => model.MonHours)
</div>
<div class="col-sm-1">
#Html.TextBoxFor(model => model.TueHours, new { style = "width:100%", #class = "hours tue" })
#Html.ValidationMessageFor(model => model.TueHours)
</div>
<div class="col-sm-1">
#Html.TextBoxFor(model => model.WedHours, new { style = "width:100%", #class = "hours wed" })
#Html.ValidationMessageFor(model => model.WedHours)
</div>
<div class="col-sm-1">
#Html.TextBoxFor(model => model.ThuHours, new { style = "width:100%", #class = "hours thu" })
#Html.ValidationMessageFor(model => model.ThuHours)
</div>
<div class="col-sm-1">
#Html.TextBoxFor(model => model.FriHours, new { style = "width:100%", #class = "hours fri" })
#Html.ValidationMessageFor(model => model.FriHours)
</div>
I want the task type field to be a drop down, but I can't figure out how to wire it up. The classes and data are right, as if I scaffold a controller (using Visual Studio's Add Controller tool) for the TimeEntry class it works fine:
<div class="form-group">
#Html.LabelFor(model => model.TaskTypeID, "TaskTypeID", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("TaskTypeID", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.TaskTypeID, "", new { #class = "text-danger" })
</div>
</div>
How can I get the dropdownlist to work in the partial view?
The null parameter in your Html.DropDownList is the data of the Dropdown and it's a Ienumerable<SelectList>.
In order to pass the data. You need to transform your TaskType List into SelectListItem List (You can do this in the controller or somewhere else just before sending Model from Controller to View) and put it in your Model like this
namespace MVCLogin.Models
{
public class TimeEntry
{
public int TimeEntryID { get; set; }
public int TaskTypeID { get; set; }
[ForeignKey("TaskTypeID")]
public virtual TaskType TaskType { get; set; }
public IEnumerable<SelectListItem> TaskTypeSelectListItems { get; set; }
public double MonHours { get; set; }
public double TueHours { get; set; }
public double WedHours { get; set; }
public double ThuHours { get; set; }
public double FriHours { get; set; }
}
}
And the dropdown code will changed to
<div class="form-group">
#Html.LabelFor(model => model.TaskTypeID, "TaskTypeID", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("TaskTypeID", model => model.TaskTypeSelectListItems, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.TaskTypeID, "", new { #class = "text-danger" })
</div>
</div>
Notice that the selected value will bind to "TaskTypeID" on your model when you post/get to the server.
Per your request: So the ViewBag is a property that enables you to dynamically share values from your controller to the view. Since it is dynamic, keep in mind that you will need to explicitly cast objects so the razor engine knows what they are at runtime. Note that upon reading about it (further reading at bottom), ViewBag is short lived and only lives within the current request so in the event that you have a model state error in your controller, you will need to reload the data into your viewbag.
This will help keep your models/view models very clean.
So on to the code, Test setup: I have my main page (Index)and I have a partial view (AddSomething) that is loaded in my main Index page. Given your models, here is what my controller looks like. Please Note that I am loading up the viewbag in my parent page initially but if an error occurs on my submit then I need to reload my viewbag since the dynamic object is short lived.
DALHelper dalHelp = new DALHelper();
public ActionResult Index()
{
//Get a list of task types from the data access layer
//Cast them into a SelectItemList and pass them into viewBag
ViewBag.TaskDD = dalHelp.GetTaskTypes().Select(a => new SelectListItem { Text = a.Name, Value = a.TaskTypeID.ToString() }).ToList();
return View();
}
public ActionResult AddSomething()
{
TimeEntry te = new TimeEntry();
return View(te);
}
[HttpPost]
public ActionResult AddSomething(TimeEntry te)
{
if (ModelState.IsValid)
{
//call my Data Access Layer to add new entry and redirect to wherver on success
if (dalHelp.CreateTimeEntry(te))
{
return RedirectToAction("Index");
}
else
{
//something happened during adding entry into DB, write whatever code to handle it gracefully
//I need to reload my viewbag since it has since been cleared (short lived)
ViewBag.TaskDD = dalHelp.GetTaskTypes().Select(a => new SelectListItem { Text = a.Name, Value = a.TaskTypeID.ToString() }).ToList();
ModelState.AddModelError("TimeEntryID", "An Error was encountered...");
return View(te);
}
}
else
{
//I need to reload my viewbag since it has since been cleared (short lived)
ViewBag.TaskDD = dalHelp.GetTaskTypes().Select(a => new SelectListItem { Text = a.Name, Value = a.TaskTypeID.ToString() }).ToList();
return View(te);
}
}
In my partial View I need to cast my viewbag item since it is a dynamic type so the razor engine can process: Also not that I am using Dropdownlistfor unstead of just dropdownlist:
#model deletemeweb2.Models.TimeEntry
#using (Html.BeginForm("AddSomething", "Home"))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>TimeEntry</h4>
#Html.ValidationMessageFor(model => model.TimeEntryID, "", new { #class = "text-danger" })
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.TaskTypeID, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.TaskTypeID, (IEnumerable<SelectListItem>)ViewBag.TaskDD, new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.TaskTypeID, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.MonHours, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.MonHours, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.MonHours, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.TueHours, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.TueHours, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.TueHours, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.WedHours, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.WedHours, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.WedHours, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ThuHours, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.ThuHours, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.ThuHours, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.FriHours, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.FriHours, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.FriHours, "", new { #class = "text-danger" })
</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>
}
Further reading about ViewBag and like properties when dealing with different controller needs: http://www.c-sharpcorner.com/blogs/viewdata-vs-viewbag-vs-tempdata-in-mvc1

ASP.NET MVC date not saving when posting

Having an issue with some dates on a form not posting back. I am entering a date into the fields, but the app seems to be posting a blank DateTime back - "01/01/0001 00:00:00"
This is the form:
This is what is being posted:
This is the controller:
public ActionResult Add()
{
var skillsetIDs = db.SkillSets.Select(x => x.IDSkillset).Distinct();
List<SelectListItem> items = new List<SelectListItem>();
foreach (var t in skillsetIDs)
{
SelectListItem s = new SelectListItem();
int catID = db.SkillSets.Where(c => c.IDSkillset == t).Select(x => x.IDCategory).Single();
string product = db.SkillSets.Where(c => c.IDSkillset == t).Select(x => x.Product + " V. " + x.P_Version).Single();
string category = db.Categories.Where(c => c.IDCategory == catID).Select(x => x.Category + ": " + x.C_Role + " - ").Single();
s.Text = category + product;
s.Value = t.ToString();
items.Add(s);
}
ViewBag.Campaign = items;
var personIDs = db.Personnel.Select(x => x.IDPerson).Distinct();
List<SelectListItem> items2 = new List<SelectListItem>();
foreach (var t in personIDs)
{
SelectListItem s = new SelectListItem();
s.Text = db.Personnel.Where(c => c.IDPerson == t).Select(x => x.Fornames + " " + x.Surname).Single();
s.Value = t.ToString();
items2.Add(s);
}
ViewBag.Person = items2;
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Add(Models.PersonSkillsModel model)
{
try
{
if (ModelState.IsValid)
{
db.PersonSkills.Add(model);
db.SaveChanges();
return RedirectToAction("Index");
}
return RedirectToAction("Index");
}
catch
{
return View();
}
}
The view:
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>PersonSkillsModel</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.IDSkillSet, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(m => m.IDPerson, (IEnumerable<SelectListItem>)ViewBag.Person)
#Html.ValidationMessageFor(model => model.IDSkillSet, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.IDSkillSet, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(m => m.IDSkillSet, (IEnumerable<SelectListItem>)ViewBag.Campaign)
#Html.ValidationMessageFor(model => model.IDSkillSet, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Score, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Score, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Score, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ScoreDate, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.ScoreDate, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.ScoreDate, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.TargetScore, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.TargetScore, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.TargetScore, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.TargetDate, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.TargetDate, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.TargetDate, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.RefresherDate, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.RefresherDate, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.RefresherDate, "", new { #class = "text-danger" })
</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>
}
The model:
[Table("PersonSkills")]
public class PersonSkillsModel
{
[Key]
public int PersonSkillsID { get; set; }
public int IDPerson { get; set; }
public int IDSkillSet { get; set; }
public int Score { get; set; }
public DateTime ScoreDate { get; set; }
public int TargetScore { get; set; }
public DateTime TargetDate { get; set; }
public DateTime RefresherDate { get; set; }
}
Could you add Data Annotation and debug again?
[DataType(DataType.Date)]
public DateTime ScoreDate { get; set; }
I was facing similar issue few days back.. see if below one works..
decorate datetime properties with following attibute
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:yyyy-MMMMM-dd}")]

Slightly more complex "create" form in ASP.NET w/Entity Framework and MVC

Here is a sample of my models. There is a Supply Receipt that holds custom models for Block, Grower, and a collection of SupplyReceiptLine:
public class SupplyReceipt
{
[Key]
public int Id { get; set; }
[Required]
public string LoadNumber { get; set; }
[Required]
public DateTime Date { get; set; }
public string Notes { get; set; }
[Required]
public Block Block { get; set; }
[Required]
public Contact Grower { get; set; }
[Required]
public ICollection<SupplyReceiptLine> SupplyReceiptLines { get; set; }
}
And I don't think it's necessary for my question but here is an example for my Contact model (used for Grower):
public class Contact
{
[Key]
public int Id { get; set; }
[Required]
public string Title { get; set; }
public string Note { get; set; }
[Display(Name="Billing Address")]
public virtual Address BillingAddress { get; set; }
[Display(Name = "Shipping Address")]
public virtual Address ShippingAddress { get; set; }
[Display(Name = "Show as Supplier")]
public bool IsSupplier { get; set; }
[Display(Name = "Show as Customer")]
public bool IsCustomer { get; set; }
[Display(Name = "Show as Grower")]
public bool IsGrower { get; set; }
[Display(Name = "Show as Bin Owner")]
public bool IsBinOwner { get; set; }
}
Now I'm having multiple problems:
Regular MVC Scaffolding (Entity Framework Model) doesn't like Grower, Block, or Supply Receipt Lines. I understand Supply Receipt Lines needs logic behind it, but I don't understand why I had to work so hard to create a drop down select box for Grower and Block. These types are well defined (with Ids and Key attributes) and there is data in the database for these items.
Could anyone explain what I'm missing in my model above that MVC / EF Scaffolding doesn't understand? A lot of tutorials online show this automatically being done. I had to resort to manually placing an Html.DropDownListFor in my view, passing it a new SelectList built from my database context. I also had to update the controller post method to include an integer for Grower and integer for Block, and manually lookup the Grower & Block by id, assign them back to the model, before adding my Supply Receipt to the database.
I couldn't figure this out. Supply Receipt Lines is an ICollection, it should hold multiple Supply Receipt Line. How do I update my create view, and my controller, so that I can add multiple supply receipt lines within this same form?
Here is an example screenshot to go along with number 2:
Here is some of the other code associated with this "create" method, including the editors. Thanks for your time.
(Controller Post Method)
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(SupplyReceipt supplyReceipt, int Grower, int Block, ICollection<SupplyReceiptLine> supplyReceiptLines)
{
// supplyReceiptLines turns up null! So does supplyReceipt.SupplyReceiptLines
// Need Grower and Block For Some reason
supplyReceipt.Grower = db.Contacts.Where(model => model.Id.Equals(Grower)).First();
supplyReceipt.Block = db.Blocks.Where(model => model.Id.Equals(Block)).First();
if (ModelState.IsValid)
{
db.SupplyReceipts.Add(supplyReceipt);
if (supplyReceiptLines != null && supplyReceiptLines.Any())
{
db.SupplyReceiptLines.AddRange(supplyReceiptLines);
}
db.SaveChanges();
return RedirectToAction("Index");
}
return View(supplyReceipt);
}
(Create Form)
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>SupplyReceipt</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.LoadNumber, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.LoadNumber, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.LoadNumber, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Date, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Date, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Date, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Grower, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.Grower, new SelectList(Db.Contacts, "Id", "Title"), "Select a Grower", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.Grower, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Block, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.Block, new SelectList(Db.Blocks, "Id", "Title"), "Select a Block", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.Block, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Notes, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Notes, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Notes, "", new { #class = "text-danger" })
</div>
</div>
<hr />
<div id="supplyReceiptLines">
#Html.EditorFor(model => model.SupplyReceiptLines, "SupplyReceiptLines")
</div>
<div class="form-group text-right">
Add a row
</div>
<hr />
<div class="form-group">
<div class="text-right">
<button type="submit" value="Create" class="btn btn-default btn-success">Create Supply Receipt</button>
</div>
</div>
</div>
}
(Editor Template)
#model SupplyReceiptLine
#{
ModelContext Db = new ModelContext();
}
<div class="form-group form-inline">
#Html.HiddenFor(model => model.Id)
<div class="col-sm-1">
#Html.LabelFor(model => model.Qty, htmlAttributes: new { #class = "" })
#Html.EditorFor(model => model.Qty, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Qty, "", new { #class = "text-danger" })
</div>
<div class="col-sm-1">
#Html.LabelFor(model => model.Pack, htmlAttributes: new { #class = "" })
#Html.DropDownListFor(model => model.Pack, new SelectList(Db.Packs, "Id", "Title"), "", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.Pack, "", new { #class = "text-danger" })
</div>
<div class="col-sm-1">
#Html.LabelFor(model => model.Size, htmlAttributes: new { #class = "" })
#Html.DropDownListFor(model => model.Size, new SelectList(Db.Sizes, "Id", "Title"), "", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.Size, "", new { #class = "text-danger" })
</div>
<div class="col-sm-3">
#Html.LabelFor(model => model.Variety, htmlAttributes: new { #class = "" })
#Html.DropDownListFor(model => model.Variety, new SelectList(Db.Varieties, "Id", "Title"), "", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.Variety, "", new { #class = "text-danger" })
</div>
<div class="col-sm-3">
#Html.LabelFor(model => model.Grade, htmlAttributes: new { #class = "" })
#Html.DropDownListFor(model => model.Grade, new SelectList(Db.Grades, "Id", "Title"), "", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.Grade, "", new { #class = "text-danger" })
</div>
<div class="col-sm-3">
#Html.LabelFor(model => model.BinOwner, htmlAttributes: new { #class = "" })
#Html.DropDownListFor(model => model.BinOwner, new SelectList(Db.Contacts, "Id", "Title"), "", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.BinOwner, "", new { #class = "text-danger" })
</div>
</div>

Categories

Resources