Passing Value from controller to controller via View - c#

I have two classes where one is a parent class for the other. The basic CRUD functions was created in the controller. In the design of my table I have the parent id in my child class as the foreign key. In the view for Create function of the child, I am asked to enter the parent ID. I have changed the Create to accept the ID of the parent. But when I remove the code for selecting the parent id in the view I get exception in my Create. Is there a way I can set the parent ID in both my create functions(Over loaded functions).
public ActionResult Create(int? id)
{
ViewBag.LsystemID = new SelectList(db.Lsystem, "LsystemID", "LsystemName",id);
ViewBag.TCID = new SelectList(db.TC, "TCID", "TCName");
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "OptionID,OptionName,TCID,LsystemID")] Option option)
{
if (ModelState.IsValid)
{
db.Option.Add(option);
db.SaveChanges();
return RedirectToAction("Index");
}
// ViewBag.LsystemID = new SelectList(db.Lsystem, "LsystemID", "LsystemName", op);
ViewBag.TCID = new SelectList(db.TC, "TCID", "TCName", option.TCID);
return View(option);
}
View
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.LabelFor(model => model.OptionName, htmlAttributes: new { #class = "control-label col-md-2" })
#Html.EditorFor(model => model.OptionName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.OptionName, "", new { #class = "text-danger" })
#Html.LabelFor(model => model.TCID, "TCID", htmlAttributes: new { #class = "control-label col-md-2" })
#Html.DropDownList("TCID", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.TCID, "", new { #class = "text-danger" })
#Html.LabelFor(model => model.LsystemID, "LsystemID", htmlAttributes: new { #class = "control-label col-md-2" })
#Html.DropDownList("LsystemID", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.LsystemID, "", new { #class = "text-danger" })
<input type="submit" value="Create" class="btn btn-default" />
}
How can I pass the value LsystemID without being shown in the View?
EDIT 1 : Adding Model class
public class Lsystem
{
public int LsystemID { get; set; }
public string LsystemName { get; set; }
public virtual ICollection<Option> Options { get; set; }
// public int OptionId { get; set; }
}
public class Option
{
public int OptionID { get; set; }
public string OptionName { get; set; }
public int TCID { get; set; }
public virtual TC tc { get; set; }
public virtual Lsystem Lsystem { get; set; }
public int LsystemID { get; set; }
public virtual ICollection<OptionValue> OptionValues { get; set; }
}

Start by creating a view model representing what you need in the view (add validation and display attributes as required
public class OptionVM
{
public int Lsystem { get; set; }
public string Name { get; set; }
public int TC { get; set; }
public SelectList TCList { get; set; }
}
and in the controller
public ActionResult Create(int? id)
{
OptionVM model = new OptionVM
{
Lsystem = id // set the parent
};
ConfigureViewModel(model);
return View(model);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(OptionVM model)
{
if (!ModelState.IsValid)
{
ConfigureViewModel(model);
return View(model);
}
Option option = new Option
{
OptionName = model.Name,
TCID = model.TC,
LsystemID= model.Lsystem
};
db.Option.Add(option);
db.SaveChanges();
return RedirectToAction("Index");
}
private void ConfigureViewModel(OptionVM model)
{
model.TCList = new SelectList(db.TC, "TCID", "TCName");
}
and in the view
#model OptionVM
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.HiddenFor(m => m.Lsystem)
#Html.LabelFor(m => m.Name)
#Html.TextBoxFor(m => m.Name)
#Html.ValidationMesageFor(m => m.Name)
#Html.LabelFor(m => m.TC)
#Html.DropDownListFor(m => m.TC, Model.TCList, "Please select")
#Html.ValidationMesageFor(m => m.TC)
<input type="submit" ... />
}

Related

How to populate a dropdownlist based on Id from a SQL Database

I am trying to create a drop down list in one of my CRUD screens that are based on a different model in my program. Right now it inputs the values based on ID but I want it to be able to populate the names of instructors in a drop-down list.
I've tried a few different things using the select list but it didn't seem to work.
This is my model:
[Table("Section")]
public class Section
{
[Key]
public int Id { get; set; }
[DisplayName("Section")]
public int? section { get; set; }
public Nullable <int> instructor_id { get; set; }
public int location_id { get; set; }
public int modality_id { get; set; }
public int DOW_id { get; set; }
public int course_id { get; set; }
public virtual DOW DOW { get; set; }
public virtual Instructor Instructor { get; set; }
public virtual Location Location { get; set; }
public virtual Modality Modality { get; set; }
public virtual Course Course { get; set; }
This is my controller:
// GET: Sections/Create
public ActionResult Create()
{
return View();
}
// POST: Sections/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see https://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Id,section,startTime,endTime,startDate,endDate,isTap,isActive,instructor_id,location_id,modality_id,DOW_id,course_id")] Section section)
{
if (ModelState.IsValid)
{
db.Sections.Add(section);
db.SaveChanges();
return RedirectToAction("Index");
}
//ViewBag.instruct = new SelectList(db.Instructors, "Id", "lname", section.instructor_id);
return View(section);
}
And this is my view
<div class="form-group">
#Html.LabelFor(model => model.instructor_id, "instructor_id" , htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.instructor_id, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.instructor_id, "", new { #class = "text-danger" })
</div>
</div>
You need to change the Get Method in Controller as follows:
// GET: Sections/Create
public ActionResult Create()
{
ViewBag.Instructors = db.Instructors.ToList();
return View();
}
Your HTML need to be changed as follows:
<div class="form-group">
#Html.LabelFor(model => model.instructor_id, "instructor_id" , htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.instructor_id, new SelectList(ViewBag.Instructors, "Id", "Name"), new { #class = "form-control" } )
#Html.ValidationMessageFor(model => model.instructor_id, "", new { #class = "text-danger" })
</div>
</div>
Make sure field names are correct.
Taken form John Peters answers, kindly take a look
Create a data layer that retrieves a list of what you want. Then use EF to get all the states.
//assuming you have a table of states..
var states = db.States();
The states table should be a Unique list of states.
var selectList = new List<SelectListItem>();
foreach(var thing in states){
//if you got everything, thus the ID field for the value...
selectList.Add(new SelectListItem {Text =thing.State, Selected = false, Value = thing.ID);
}
Make sure in your Viewmodel class that selectlist is a public property.....and set to what you did above. You also need to provided a string for the view selection post back.
StatesSelectList = selectList;
public IEnumerable<SelectListItem> StatesSelectList {get;set;}
public string SelectedState {get;set;}
In your view, do this:
#Html.DropDownListFor(p => Model.SelectedState, Model.StatesSelectList)

Populating DropDownList in ASP.NET MVC

Following code is to create users. I have a user class, I need to create users here. But I have department id's on a person and that department id refers to another table in the database whose name is Department.
public ActionResult Create()
{
// disable lazy because of error it creates
_db.Configuration.LazyLoadingEnabled = false;
var data = _db.Departments.OrderBy(a => a.DepartmentId).ToList();
ViewData["DepartmentList"] = data;
return View();
}
Here is View:
#{
var departmentLists = ViewData["DepartmentList"]; // Cast the list
}
<div class="form-group">
#Html.LabelFor(model => model.Department, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EnumDropDownListFor(model => model.Department, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.Department, "", new { #class = "text-danger" })
</div>
</div>
This model.department part is the where i lost. I need to list my department in order of the list, when user select, i want to select the id of the department.
Like this;
So I want the user to see
Department Name + SubDepartment name
and when they choose from the list, the chosen thing is
departmentid
so I can add in the database like that.
Here is my Create Post method:
public ActionResult Create([Bind(Include = "ID,LastName,FirstMidName,EnrollmentDate,Email,Department,Position,Active")] User user)
{
if (ModelState.IsValid)
{
_db.Users.Add(user);
_db.SaveChanges();
return RedirectToAction("Index");
}
return View(user);
}
Her is my User class;
public class User
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public int DepartmentId { get; set; }
// Other fields removed for brevity
}
Here is Department class;
public class Department
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int DepartmentId { get; set; }
public string DepartmentName { get; set; }
public string SubDepartmentName { get; set; }
}
Write your Create GET method as follows:
public ActionResult Create()
{
// disable lazy because of error it creates
_db.Configuration.LazyLoadingEnabled = false;
var departmentList = _db.Departments.Select(d => new
{
d.DepartmentId,
DepartmentName = d.DepartmentName + " " + d.SubDepartmentName
}).OrderBy(a => a.DepartmentId).ToList();
ViewBag.DepartmentList = new SelectList(departmentList,"DepartmentId","DepartmentName");
return View();
}
Then in the view:
<div class="form-group">
#Html.LabelFor(model => model.DepartmentId, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("DepartmentId", ViewBag.DepartmentList as SelectList, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.DepartmentId, "", new { #class = "text-danger" })
</div>
</div>
Another problem is in your Create POST method. You are not allowing you DepartmentId to pass in your Bind include list. Please update you Create POST method as follows:
public ActionResult Create([Bind(Include = "ID,LastName,FirstMidName,EnrollmentDate,Email,DepartmentId,Position,Active")] User user)
{
if (ModelState.IsValid)
{
_db.Users.Add(user);
_db.SaveChanges();
return RedirectToAction("Index");
}
return View(user);
}

Editing/Creating a foreign key with a drop down list validation error

I'm creating a web app, and I can't seem to either create or edit entries with a foreign key. I'm creating a dropdown list to edit the records, and it's being populated correctly. But anytime I edit or create a new record with that foreign key I get "The value '2' is invalid."
My Controller
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "chimeTimeID,ScheduleID,ChimeTimeStamp")] ChimeTime chimeTime)
{
ViewData["scheduleID"] = new SelectList(db.Schedules, "scheduleID", "ScheduleName", "Select a Schedule");
ViewBag.defaultModem = new SelectList(db.Schedules, "scheduleID", "ScheduleName", "Select a Schedule");
if (ModelState.IsValid)
{
db.Entry(chimeTime).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(chimeTime);
}
My View
<div class="form-group">
#Html.LabelFor(model => model.ScheduleID.ScheduleName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="dropdown">
#Html.DropDownListFor(model => model.ScheduleID, (SelectList)ViewBag.ScheduleName, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.ScheduleID, "", new { #class = "text-danger" })
</div>
</div>
My Model
[Table("P_ChimeTime")]
public class ChimeTime
{
[Key]
public int chimeTimeID { get; set; }
public Schedule ScheduleID { get; set; }
[DataType(DataType.Time)]
[DisplayFormat(DataFormatString = "{0:T}", ApplyFormatInEditMode = true)]
public DateTime ChimeTimeStamp { get; set; }
}
So what am I doing wrong? It appears to me that MVC isn't parsing my result from the form to an int like it should.
So apparently this is how it should have been:
My Controller:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "chimeTimeID,schedule,ChimeTimeStamp")] ChimeTime chimeTime)
{
ViewData["schedule"] = new SelectList(db.Schedules, "scheduleID", "ScheduleName", "Select a Schedule");
ViewBag.schedule = new SelectList(db.Schedules, "scheduleID", "ScheduleName", "Select a Schedule");
if (ModelState.IsValid)
{
chimeTime.ScheduleID = db.Schedules.Find (Int32.Parse (Request ["schedule"]));
db.ChimeTimes.Add(chimeTime);
db.SaveChanges();
return RedirectToAction("Index");
}
buildChimeJob(chimeTime);
return View(chimeTime);
}
My View:
<div class="form-group">
#Html.LabelFor(model => model.schedule, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="dropdown">
#Html.DropDownListFor(model => model.schedule, (SelectList)ViewBag.schedule, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.schedule, "", new { #class = "text-danger" })
</div>
</div>
My Model:
[Table("P_ChimeTime")]
public class ChimeTime
{
[Key]
public int chimeTimeID { get; set; }
public virtual Schedule ScheduleID { get; set; }
[DataType(DataType.Time)]
[DisplayFormat(DataFormatString = "{0:T}", ApplyFormatInEditMode = true)]
public DateTime ChimeTimeStamp { get; set; }
[ForiegnKey("ScheduleID")]
public int schedule {get; set;}
}

Update ViewModel after dynamically updating the view

I am trying to define ViewModels that faithfully represent the view (to make strict use of that concept).
Some of the elements of the ViewModel are updated dynamically. The problem I have, is that when I do the Post, the ViewModel returns without the elements that were updated dynamically.
The update is done through jQuery, when an event is performed. An action is invoked through Url.Action, and a Div is updated.
I made an example to clarify the scenario. An application that only stores a location (state and city). For this I have three ViewModels: one to represent the States in a SelectList, one to represent the Cities in a SelectList, and finally one to represent the Location (formed by the two ViewModel that I mentioned first).
Models:
public class State
{
public int Id { get; set; }
[Required]
public string Name { get; set; }
}
public class City
{
public int Id { get; set; }
[Required]
public string Name { get; set; }
[Required]
public int StateId { get; set; }
public virtual State State { get; set; }
}
ViewModels:
public class CitySelectListViewModel
{
public CitySelectListViewModel() { }
public CitySelectListViewModel(IEnumerable<Models.City> cities)
{
this.Cities = cities;
}
[Display(Name = "Cities")]
[Required]
public int? SelectedCityId { get; set; }
public IEnumerable<City> Cities { get; }
}
public class StateSelectListViewModel
{
public StateSelectListViewModel() { }
public StateSelectListViewModel(IEnumerable<State> states)
{
this.States = states;
}
[Display(Name = "States")]
[Required]
public int? SelectedStateId { get; set; }
public IEnumerable<State> States { get; }
}
public class LocationCreateViewModel
{
public LocationCreateViewModel() { }
public LocationCreateViewModel(ICollection<State> states)
{
this.StateSelectListViewModels = new StateSelectListViewModel(states);
this.CitySelectListViewModel = new CitySelectListViewModel();
}
public StateSelectListViewModel StateSelectListViewModels { set; get; }
public CitySelectListViewModel CitySelectListViewModel { set; get; }
}
Location [Controller]:
public class LocationController : Controller
{
private DALDbContext db = new DALDbContext();
// GET: Location/Create
public ActionResult Create()
{
LocationCreateViewModel locationCreateViewModel = new LocationCreateViewModel(db.States.ToList());
return View(locationCreateViewModel);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(LocationCreateViewModel pLocationCreateViewModel)
{
if (ModelState.IsValid)
{
//db.States.Add(state);
//db.SaveChanges();
return RedirectToAction("Index", "Home");
}
LocationCreateViewModel locationCreateViewModel = new LocationCreateViewModel(db.States.ToList());
return View(locationCreateViewModel);
}
public ActionResult CitySelectList(int? stateId)
{
CitySelectListViewModel citySelectListViewModel = new CitySelectListViewModel(db.Cities.Where(c => c.StateId == stateId).ToList());
return View(citySelectListViewModel);
}
}
Create [View]:
#model ViewModelExample.ViewModels.LocationCreateViewModel
....
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>State</h4>
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.StateSelectListViewModels.SelectedStateId, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.StateSelectListViewModels.SelectedStateId, new SelectList(Model.StateSelectListViewModels.States, "Id", "Name"), "Select a State", htmlAttributes: new { #class = "form-control", #id = "StateSelectList" })
#Html.ValidationMessageFor(model => model.StateSelectListViewModels.SelectedStateId, "", new { #class = "text-danger" })
</div>
</div>
<div id="CityContainer">
#Html.Action("CitySelectList")
</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>
}
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
<script type="text/javascript">
$(function () {
// Fill City DropDownList
$('#StateSelectList').change(function () {
var selectedStateId = this.value;
$('#CityContainer').load('#Url.Action("CitySelectList")?stateId=' + selectedStateId);
});
});
</script>
}
CitySelectList [View]:
#model ViewModelExample.ViewModels.CitySelectListViewModel
....
<div class="form-group">
#Html.LabelFor(model => model.SelectedCityId, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.SelectedCityId, new SelectList(Model.Cities, "Id", "Name"), "Select a City", htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.SelectedCityId, "", new { #class = "text-danger" })
</div>
</div>
I will show the execution of my example, and I will show the problem through the inspection of the ViewModel that I receive after the Post:
I select a State and a City, and I press Create.
I inspect the ViewModel received after the Post. We can see how CitySelectListViewModel is null, and what I want is to bring the last ViewModel that was updated through jQuery.
I admit that I have provided a long example, but it is the only way I found to explain what I need. Thanks in advance.
VS-Project of the example
I'ts because you are preventing the modelBinder to accurately bind to LocationCreateViewModel in your Create action when replacing the inner HTML of <div id="CityContainer"> (thats what you do with $('#CityContainer').load(...). You instruct the model binder to bind to
#model ViewModelExample.ViewModels.CitySelectListViewModel and as a result you get this HTML for the city select list:
One way of solving this is modifying CitySelectList.cshtml to:
#model ViewModelExample.ViewModels.LocationCreateViewModel
#{
Layout = null;
}
<div class="form-group">
#Html.LabelFor(model => model.CitySelectListViewModel.SelectedCityId,
htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model =>
model.CitySelectListViewModel.SelectedCityId, new
SelectList(Model.CitySelectListViewModel.Cities, "Id", "Name"), "Select a City", htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.CitySelectListViewModel.SelectedCityId, "", new { #class = "text-danger" })
</div>
</div>
and your CitySelectList action to:
public ActionResult CitySelectList(int? stateId)
{
LocationCreateViewModel locationCreateViewModel = new LocationCreateViewModel();
locationCreateViewModel.CitySelectListViewModel = new CitySelectListViewModel(db.Cities.Where(c => c.StateId == stateId).ToList());
return View(locationCreateViewModel);
}
But I would recommend custom model binding as well.

ASP.NET MVC 5 - How to Add [Required] Data Annotation in ViewModel

I'm calling three Models (Unit, Site, Work_Type) in my view model called UnitAdminViewModel. I need to set one field as required from the Unit Model. Since I'm using Database First approach, I cannot modify the Unit Model directly since this gets autogenerated. How can I successfully add:
[Required(ErrorMessage = "Group is required")]
public string GroupName { get; set; }
to my view model UnitAdminViewModel?
public class UnitAdminViewModel
{
public Unit Unit { get; set; }
public List<Site> Site { get; set; }
public IEnumerable<Work_Type> Work_Type { get; set; }
}
In the Unit Model, I want to set the field GroupName as [Required]
public partial class Unit
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Unit()
{
this.Staffs = new HashSet<Staff>();
}
public int UnitID { get; set; }
public string UnitCode { get; set; }
public string UnitName { get; set; }
public string GroupName { get; set; }
public byte IncentiveUnit { get; set; }
public bool CallCenter { get; set; }
public bool CDWUnit { get; set; }
public string CDWSite { get; set; }
public Nullable<int> SiteID { get; set; }
public Nullable<int> DivisionID { get; set; }
public bool WFCUnit { get; set; }
public bool QAMonitored { get; set; }
public bool NICEMonitored { get; set; }
public string ListPrefix { get; set; }
public string TSHSource { get; set; }
public string StatsSource { get; set; }
public string DialerSource { get; set; }
public Nullable<int> CostCenterID { get; set; }
public int WaterfallView { get; set; }
public bool Locked { get; set; }
public string Platform { get; set; }
public Nullable<int> Supplier { get; set; }
public string Work_Type { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Staff> Staffs { get; set; }
}
Update
I tried going off #Izzy example. I feel like i'm closer, but the [Required] still doesn't seem to trigger a validation error when I submit a form without populating that field. #Izzy, is there something I might be missing?
View Model
public class UnitAdminViewModel
{
public Unit Unit { get; set; }
public List<Site> Site { get; set; }
public IEnumerable<Work_Type> Work_Type { get; set; }
}
UnitMetaData class
[MetadataType(typeof(UnitMetaData))]
public partial class Unit
{
}
public class UnitMetaData {
[Required(ErrorMessage = "Group is required")]
public string GroupName { get; set; }
[Required(ErrorMessage = "UnitName is required")]
public string UnitName { get; set; }
public string CDWSite { get; set; }
public string Platform { get; set; }
public Nullable<int> Supplier { get; set; }
public string Work_Type { get; set; }
}
VIEW
#model WebReportingToolDAL.Models.ViewModels.UnitAdminViewModel
#{
ViewBag.Title = "Create";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Create</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Unit</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Unit.UnitName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Unit.UnitName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Unit.UnitName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Unit.GroupName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Unit.GroupName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Unit.GroupName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Unit.CDWSite, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.Unit.CDWSite, new SelectList(Model.Site, "SiteName", "SiteName"), new { #class = "form-control" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Unit.Platform, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.Unit.Platform, new List<SelectListItem> { new SelectListItem { Text = "PSCC", Value = "PSCC" }, new SelectListItem { Text = "RC", Value = "RC" } }, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Unit.Supplier, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.Unit.Supplier, new List<SelectListItem> { new SelectListItem { Text = "0", Value = "0" }, new SelectListItem { Text = "1", Value = "1" } }, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Unit.Work_Type, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.Unit.Work_Type,new SelectList(Model.Work_Type, "Name", "Name"),new { #class = "form-control" })
</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>
}
Controller
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "UnitID,UnitCode,UnitName,GroupName,IncentiveUnit,CallCenter,CDWUnit,CDWSite,SiteID,DivisionID,WFCUnit,QAMonitored,NICEMonitored,ListPrefix,TSHSource,StatsSource,DialerSource,CostCenterID,WaterfallView,Locked,Platform,Supplier,Work_Type")] Unit unit)
{
if (ModelState.IsValid)
{
unit.UnitCode = "XX";
unit.IncentiveUnit = 1;
unit.CallCenter = true;
unit.CDWUnit = true;
unit.DivisionID = 2;
unit.WFCUnit = false;
unit.QAMonitored = false;
unit.NICEMonitored = true;
unit.ListPrefix = null;
unit.TSHSource = null;
unit.StatsSource = null;
unit.DialerSource = null;
unit.CostCenterID = 3;
unit.WaterfallView = 1;
unit.Locked = false;
var siteId = (from s in db.Sites
where s.SiteName.ToLower().Equals(unit.CDWSite.ToLower())
select s.SiteID).First();
unit.SiteID = siteId;
db.Units.Add(unit);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(unit);
}
When using Database first approach you'll realise that the class is marked as partial So what you can do is make use of MetadataType attribute to achieve what you're after.
So go ahead and create a file and name it e.g. UnitMetaData. Your code should look something like:
public class UnitMetaData
{
[Required(ErrorMessage = "Group is required")]
public string GroupName { get; set; }
//more properties
}
Your Unit class is partial so you can create it another file and use MetadataType as:
[MetadataType(typeof(UnitMetaData))]
public partial class Unit
{
}
More about MetadataType here
partial definition:
It is possible to split the definition of a class or a struct, an interface or a method over two or more source files. Each source file contains a section of the type or method definition, and all parts are combined when the application is compiled.
source
Please Note: Ensure the namespace is same as the generated Unit class, otherwise it will not work
You can use a real view model, for one. Simply wrapping a bunch of entities in a class is missing the point of what view models are for. Your view models should only contain the properties that should be displayed/edited and it should hold the business logic for your view, such as the fact that GroupName is required (when it apparently isn't at the database level).
That means creating something like:
public class UnitViewModel
{
// other properties you want to edit
[Required]
public string GroupName { get; set; }
}
Then, you use this rather than Unit in your view, and map the posted properties from UnitViewModel onto your Unit instance.

Categories

Resources