I've made a Profile Model that stores certain property values. Such as firstName, lastName... etc... Among others state is one of them.
Now problem occurred when I've replaced TextBox with DropDownList for State property.
This is the way I've made my Edit method in ProfileController.
When opened app will populate if any existing values. First issue, how to get selected value from the dropdown, so i can pass it into Profile property like I did in this method.
public ActionResult Edit(string username)
{
ViewBag.StateID = new SelectList(db.States, "StateID", "StateName");
ProfileBase _userProfile = ProfileBase.Create(username);
ProfileModel _profile = new ProfileModel();
System.Web.HttpContext.Current.Session["_userName"] = username;
if (_userProfile.LastUpdatedDate > DateTime.MinValue)
{
_profile.FirstName = Convert.ToString(_userProfile.GetPropertyValue("FirstName"));
_profile.LastName = Convert.ToString(_userProfile.GetPropertyValue("LastName"));
_profile.Address = Convert.ToString(_userProfile.GetPropertyValue("Address"));
_profile.City = Convert.ToString(_userProfile.GetPropertyValue("City"));
_profile.State = Convert.ToString(_userProfile.GetPropertyValue("State"));
_profile.Zip = Convert.ToString(_userProfile.GetPropertyValue("Zip"));
}
return View(_profile);
}
This worked fine when State was a string passed in TextBox, and then saved with Edit post method.
[HttpPost]
public ActionResult Edit(ProfileModel model)
{
if (ModelState.IsValid)
{
ProfileBase profile = ProfileBase.Create(System.Web.HttpContext.Current.Session["_userName"].ToString(), true);
if (profile != null)
{
profile.SetPropertyValue("FirstName", model.FirstName);
profile.SetPropertyValue("LastName", model.LastName);
profile.SetPropertyValue("Address", model.Address);
profile.SetPropertyValue("City", model.City);
profile.SetPropertyValue("State", model.State);
profile.SetPropertyValue("Zip", model.Zip);
profile.Save();
}
else
{
ModelState.AddModelError("", "Error writing to Profile");
}
}
return RedirectToAction("Index");
}
This is how I created dropdown for State.
Model:
public class State
{
public int StateID { get; set; }
public string StateName { get; set; }
public IEnumerable<RegisterModel> RegModel { get; set; }
public IEnumerable<ProfileModel> Profiles { get; set; }
}
Controller:
ViewBag.StateID = new SelectList(db.States, "StateID", "StateName");
View:
#Html.DropDownList("StateID", (SelectList)ViewBag.StateID, new { #class = "dropdown" })
I've tried several things. No luck so far. What am I missing?!
Related
I'm create a drop down list using this code
<div class="btn-group-vertical">
<select asp-for="Client.ClientCode"
asp-items="#(new SelectList(Model.Clients,"ClientCode","Client"))"
class="form-control" style="width:auto" id="client">
</select>
</div>
Then i edit the model value. But when i returning this model, don't happen anything. The drop down list value not changed.
I have try use ModelState.Clear()
ModelState.Clear();
return View(model);
It does not work. i have try to reload the page using
window.location.reload(true);
It does not work too. i have try to open page using
window.open(url, "_self");
It does not work too.
Is there any solution to refresh dropdownlist value ?
Update:
This is the code in view
[HttpGet]
public async Task<IActionResult> Setup(string id)
{
var model = HttpContext.Session.GetComplexData<SetupViewModel>("SetupModel");
if (model == null || !string.IsNullOrEmpty(id))
{
if (model == null || model.Client.ClientCode != id)
{
string clientCode = string.IsNullOrEmpty(id) ? "POI" : id;
var client = await projectRepository.GetClient(clientCode);
var ClientList = await projectRepository.GetAllClients();
var ProjectList = await projectRepository.GetAllProjects(client.ClientCode);
model = new SetupViewModel()
{
Clients = ClientList.ToList(),
Client = client,
Projects = ProjectList.ToList(),
};
HttpContext.Session.SetComplexData("SetupModel", model);
}
}
ModelState.Clear();
return View(model);
}
This is the model
public class SetupViewModel
{
public Projects Client { get; set; }
public List<Projects> Clients { get; set; }
public Projects Project { get; set; }
public List<Projects> Projects { get; set; }
public bool ProjectActive { get; set; }
public string ErrorMessage { get; set; }
}
here is the post code in controller
try
{
Employee employee = await employeeRepository.GetEmployeeByPhoneNumber(((ClaimsIdentity)User.Identity).FindFirst(AccountConstant.PhoneNumber).Value);
var model = HttpContext.Session.GetComplexData<SetupViewModel>("SetupModel");
foreach (var project in model.Projects)
{
project.ClientCode = newModel.Client.ClientCode;
project.Client = newModel.Client.Client;
await projectRepository.Update(project, employee);
}
model.Client.Client = newModel.Client.Client;
model.Client.ClientCode = newModel.Client.ClientCode;
TempData["Messages"] = "Edit client information has been successful.";
HttpContext.Session.SetComplexData("SetupModel", model);
return RedirectToAction("Setup", "Home");
}
catch (Exception exc)
{
HttpContext.Session.SetComplexData("Error", new ErrorViewModel() { ErrorMessage = exc.ToString() });
return RedirectToAction("Error", "Home");
}
Hope this update useful.
I'm saving properties in my database with the CreateAMeeting method. When I check the database I can see all properties saved except my list, I can't see my list properties in my database. I have been googling but I can't find if it's possible to see them or if I'm just not saving them properly. If I use a breakpoint I can see that the meeting(db.Meetings.Add(meeting);) model have the times i added in the Times list.
When I later try to retrieve my list in the ChooseTimes method, it's null. I don't know if the problem is that I'm saving it wrong or its something else. What am I doing wrong and is it possible to see saved lists in the database?
I'm not done with the fooreachloop, pay no attention to it.
public class MeetingController : BaseController
{
private ApplicationSignInManager _signInManager;
private ApplicationUserManager _userManager;
public static Meeting NewMeeting;
public static List<DateTime> TempTimes = new List<DateTime>();
public ActionResult CreateMeeting()
{
return View();
}
public ActionResult CreateAMeeting(Meeting meeting)
{
var userName = User.Identity.Name;
var user = db.Users.Where(u => u.UserName == userName).SingleOrDefault();
var model = new MeetingPeopleViewModel();
meeting.Creator = user;
meeting.Invited.Add(user);
meeting.Times = TempTimes;
meeting.Start = DateTime.Now;
meeting.End = meeting.Start.AddMinutes(meeting.Minutes);
db.Meetings.Add(meeting);
db.SaveChanges();
return View("AddToMeeting", model);
}
public ActionResult AddTempTime(DateTime Start, Meeting meeting)
{
TempTimes.Add(Start);
meeting.Times = TempTimes;
return View("CreateMeeting", meeting);
}
public ActionResult ChooseTimes()
{
var userName = User.Identity.Name;
var user = db.Users.Where(u => u.UserName == userName).SingleOrDefault();
Meeting meeting = new Meeting();
foreach(var item in db.Meetings)
{
if(item.Invited.Contains(user))
{
meeting = item;
}
}
return View(meeting);
}
This is my Meeting model.
public class Meeting
{
public int Id { get; set; }
public string Title { get; set; }
public ApplicationUser Creator { get; set; }
public ICollection<ApplicationUser> Invited { get; set; }
public double Minutes { get; set; }
public DateTime Start { get; set; }
public DateTime End { get; set; }
public ICollection<DateTime> Times { get; set; }
public bool AllDay { get; set; }
public ICollection<ApplicationUser> User { get; set; }
public ApplicationUser UserNotis { get; set; }
}
As far as Im aware you can not save a literal list to a database, you can save all the items in a list to a database, by iterating through the list and saving each unique record.
public class MeetingController : BaseController
{
private ApplicationSignInManager _signInManager;
private ApplicationUserManager _userManager;
public static Meeting NewMeeting;
public static List<DateTime> TempTimes = new List<DateTime>();
public ActionResult CreateMeeting()
{
return View();
}
public ActionResult CreateAMeeting(Meeting meeting)
{
var userName = User.Identity.Name;
var user = db.Users.FirstOrDefault(u => u.UserName == userName);
var model = new MeetingPeopleViewModel();
meeting.Creator = user;
meeting.Invited.Add(user);
meeting.Times = TempTimes;
meeting.Start = DateTime.Now;
meeting.End = meeting.Start.AddMinutes(meeting.Minutes);
db.Meetings.Add(meeting);
db.SaveChanges();
return View("AddToMeeting", model);
}
public ActionResult AddTempTime(DateTime Start, Meeting meeting)
{
TempTimes.Add(Start);
meeting.Times = TempTimes;
return View("CreateMeeting", meeting);
}
public ActionResult ChooseTimes()
{
var userName = User.Identity.Name;
var user = db.Users.FirstOrDefault(u => u.UserName == userName);
Meeting meeting = new Meeting();
List<Meeting> Meetings = db.Meetings.ToList();
foreach (var item in Meetings)
{
if (item.Invited.Contains(user))
{
meeting = item;
}
}
return View(meeting);
}
There are better ways to do multiple things you are trying to do, but this will solve your issue.
You have to create a list of the meetings populated from the database so it is an Enumerable at the time you iterate rather than an query able,
I tried to save my entire list in one field, wich obviusly isn't possible. So i had to create a new model with a database to save evrything in my list. Here is my save method if anyone else is having problems saving items in a list.
public void SaveTimes(Meeting meeting)
{
foreach (var time in TempStart)
{
var mt = new MeetingTimes
{
MeetingId = meeting.Id,
Meeting = meeting,
Time = time
};
db.MeetingTimes.Add(mt);
db.SaveChanges();
}
}
I wish to utilize the ASP.NET MVC convention to parse POSTed form submission to a model by ActionResult MyAction(MyModel submitted). MyModel includes a property of the type that I defined -UsState-.
submitted.UsState as the result of the action returns null.
Is there any way to get the submitted to be set to proper value?
I have the following view with a form in a MyForm.cshtml
...
#using (Html.BeginForm("MyAction", "MyController", FormMethod.Post, ...))
{
#Html.DropDownList("States",
null,
new { #id = "state", #class = "form-control", #placeholder = "State"})
}
...
with the controller
public class MyController : Controller
{
public ActionResult MyForm()
{
ViewBag.States = GetStatesList();
}
public ActionResult MyAction(MyModel info) //info.State is set to null on POST
{
return View();
}
private static List<SelectListItem> GetStatesList()
{
var states = new List<SelectListItem>();
states.Add(new SelectListItem { Value = "", Selected = true, Text = "State" });
foreach (var s in UsStates.ToList())
{
var state = new SelectListItem { Value = s.Abbreviation, Text = s.Name, Disabled = !s.Available };
states.Add(state);
}
return states;
}
}
with the model
public class MyModel
{
public UsState States { get; set; } //Do I need proper setter for it to work?
}
public static class UsStates //Should I get the UsStates in a different way?
{
private static List<UsState> states = new List<UsState> {
new UsState("AL", "Alabama"),
//...
}
public static List<UsState> ToList()
{ return states; }
}
public class UsState
{
public UsState(string ab, string name, bool available = true)
{
Name = name;
Abbreviation = ab;
Available = available;
}
}
Change you MyModel to
public class MyModel
{
public string SelectedState {get;set; }
public IEnumerable<SelectListItem> States { get; set; }
}
modify your view to
#using (Html.BeginForm("MyAction", "MyController", FormMethod.Post, ...))
{
#Html.DropDownListFor(m => m.SelectedState, Model.States, "State",
new { #class = "form-control" })
}
I changed this to a DropDownListFor, because it will automatically generate the id and name attributes for you. It will also create an element at the top "State" so that you don't have to pre-pend it to your list.
I removed your placeholder because placeholders are not supported with select elements. As well as not to be used as replacements for labels.
Per W3C
The placeholder attribute specifies a short hint that describes the
expected value of an input field (e.g. a sample value or a short
description of the expected format).
Split your controller actions to a GET/POST pair
public class MyController : Controller
{
//Get
public ActionResult MyAction()
{
return View(new MyModel { States = GetStateList() });
}
[HttpPost]
public ActionResult MyAction(MyModel model)
{
if (!ModelState.IsValid)
{
model.States = GetStateList();
return View(model);
}
//do whatever you are going to do with the posted information.
return RedirectToAction("<some view>"); //redirect after a post usually to Index.
}
private static IEnumerable<SelectListItem> GetStatesList()
{
var states = new List<SelectListItem>();
foreach (var s in UsStates.ToList())
{
var state = new SelectListItem { Value = s.Abbreviation, Text = s.Name, Disabled = !s.Available };
states.Add(state);
}
return states;
}
}
After looking into the POSTed data, I realized that the submitted form data -States=AL-type is string, which would fail to be set as UsState type.
I changed the model to the following:
public class MyModel
{
public string States { get; set; }
}
I get the string value of the submitted form, at least. Not sure if this is given - if that's the case, I suppose I should use a separate ViewModel in order to get States as a string, and convert that into MyModel where I cast string States into UsState States.
I made a dropdown list for me to assign Admin Roles to certain users when I create them:
But they don't assign themselves properly, as you can see here:
It happens because of this line Value = "Administrator LVL2". My question is: How do i assign it to my model like I've done for assigning last names:
<div class="editor-field">
#Html.EditorFor(model => model.LastName)
#Html.ValidationMessageFor(model => model.LastName)
</div>
Views\User\Create.cshtml
<div class="editor-label">
#{
List<SelectListItem> listItems = new List<SelectListItem>();
listItems.Add(new SelectListItem
{
Text = "Administrator LVL1",
Value = model => model.AdminRole, <-- THIS IS WRONG
});
listItems.Add(new SelectListItem
{
Text = "Administrator LVL2",
Value = "Administrator LVL2",
Selected = true
});
listItems.Add(new SelectListItem
{
Text = "Administrator LVL3",
Value = "Administrator LVL3"
});
}
#Html.DropDownListFor(model => model.AdminRole, listItems, "-- Select Admin Role --")
</div>
UserController.cs
public class UserController : Controller
{
private IssueContext db = new IssueContext();
//
// GET: /User/
public ViewResult Index(string sortOrder, string currentFilter, string searchString, int? page)
{
ViewBag.CurrentSort = sortOrder;
ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "name_desc" : "";
ViewBag.DateSortParm = sortOrder == "Date" ? "date_desc" : "Date";
if (searchString != null)
{
page = 1;
}
else
{
searchString = currentFilter;
}
ViewBag.CurrentFilter = searchString;
var users = from s in db.Users
select s;
if (!String.IsNullOrEmpty(searchString))
{
users = users.Where(s => s.LastName.ToUpper().Contains(searchString.ToUpper())
|| s.FirstMidName.ToUpper().Contains(searchString.ToUpper()));
}
switch (sortOrder)
{
case "name_desc":
users = users.OrderByDescending(s => s.LastName);
break;
case "Date":
users = users.OrderBy(s => s.EnrollmentDate);
break;
case "date_desc":
users = users.OrderByDescending(s => s.EnrollmentDate);
break;
default: // Name ascending
users = users.OrderBy(s => s.LastName);
break;
}
int pageSize = 5;
int pageNumber = (page ?? 1);
return View(users.ToPagedList(pageNumber, pageSize));
}
//
// GET: /User/Details/5
public ActionResult Details(int id = 0)
{
User user = db.Users.Find(id);
if (user == null)
{
return HttpNotFound();
}
return View(user);
}
//
// GET: /User/Create
public ActionResult Create()
{
return View();
}
//
// POST: /User/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(
[Bind(Include = "LastName, FirstMidName, EnrollmentDate, DepartmentID, DepotID")]
User user)
{
try
{
if (ModelState.IsValid)
{
db.Users.Add(user);
db.SaveChanges();
return RedirectToAction("Index");
}
}
catch (DataException /* dex */)
{
//Log the error (uncomment dex variable name after DataException and add a line here to write a log.
ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists see your system administrator.");
}
return View(user);
}
//
// GET: /User/Edit/5
public ActionResult Edit(int id = 0)
{
User user = db.Users.Find(id);
if (user == null)
{
return HttpNotFound();
}
return View(user);
}
//
// POST: /User/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(
[Bind(Include = "UserID, LastName, FirstMidName, EnrollmentDate, DepartmentID, DepotID")]
User user)
{
try
{
if (ModelState.IsValid)
{
db.Entry(user).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
}
catch (DataException /* dex */)
{
//Log the error (uncomment dex variable name after DataException and add a line here to write a log.
ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists see your system administrator.");
}
return View(user);
}
//
// GET: /User/Delete/5
//This code accepts an optional Boolean parameter that indicates whether it was called after a failure to save changes.
//This parameter is false when the HttpGet Delete method is called without a previous failure. When it is called by the
//HttpPost Delete method in response to a database update error, the parameter is true and an error message is passed to the view.
public ActionResult Delete(bool? saveChangesError = false, int id = 0)
{
if (saveChangesError.GetValueOrDefault())
{
ViewBag.ErrorMessage = "Delete failed. Try again, and if the problem persists see your system administrator.";
}
User user = db.Users.Find(id);
if (user == null)
{
return HttpNotFound();
}
return View(user);
}
//
// POST: /User/Delete/5
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Delete(int id)
{
try
{
User user = db.Users.Find(id);
db.Users.Remove(user);
db.SaveChanges();
}
catch (DataException/* dex */)
{
// uncomment dex and log error.
return RedirectToAction("Delete", new { id = id, saveChangesError = true });
}
return RedirectToAction("Index");
}
//To make sure that database connections are properly closed and the resources they hold freed up, you should see to it that the context instance is disposed.
protected override void Dispose(bool disposing)
{
db.Dispose();
base.Dispose(disposing);
}
}
How my classes are mapped:
User to Admin is 1 to 0..1 (I can assign some users with admin status but I don't want every user to have it)
Admin to Ticket is 1 to Many(You can only assign 1 admin(to fix the issue) to a ticket)
User to Ticket is 1 to many (One user can create multiple tickets)
User.cs
public class User
{
public int UserID { get; set; }
[StringLength(50, MinimumLength = 1)]
public string LastName { get; set; }
[StringLength(50, MinimumLength = 1, ErrorMessage = "First name cannot be longer than 50 characters.")]
[Column("FirstName")]
public string FirstMidName { get; set; }
public string FullName
{
get { return LastName + ", " + FirstMidName; }
}
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime EnrollmentDate { get; set; }
public int? AdministratorID { get; set; }
[ForeignKey("AdministratorID")]
public virtual Administrator Administrator { get; set; }
public int DepartmentID { get; set; }
[ForeignKey("DepartmentID")]
public virtual Department Department { get; set; }
public int DepotID { get; set; }
[ForeignKey("DepotID")]
public virtual Depot Depot { get; set; }
public virtual ICollection<Ticket> Tickets { get; set; }
}
Ticket.cs
public class Ticket
{
public int TicketID { get; set; }
public string Issue { get; set; }
[DisplayFormat(NullDisplayText = "No Priority")]
public Priority? Priority { get; set; }
[ForeignKey("CategoryID")]
public virtual Category Category { get; set; }
public int CategoryID { get; set; }
public int UserID { get; set; }
[ForeignKey("UserID")]
public virtual User User { get; set; }
public int AdministratorID { get; set; }
[ForeignKey("AdministratorID")]
public virtual Administrator Administrator { get; set; }
}
Administrator.cs
public class Administrator
{
public int AdministratorID { get; set; }
public string AdministratorTitle { get; set; }
public virtual ICollection<User> Users { get; set; }
}
Here is what I would recommend:
1) Make a Roles Table (if you have done ASP.NET Membership, this is already provided).
Role:
RoleId Int
RoleName String
2) Add Roles into the table (you can use SQL Server [or any SQL you are using])
3) Add a ForeignKey to your User OR add a link table like UsersInRoles (once again, if you used ASP Membership this is added)
1st Example:
User:
UserId Int
FirstName String
LastName string
DepotId Int
DepartmentId Int
RoleId Int
2nd Example:
UsersInRole
UserId Int
RoleId Int
Now once you GET a user, you can bring back the RoleId:
public ActionResult List()
{
// Get Roles
ViewBag.Roles = (from role in dbContext.Roles
select new SelectListItem
{
Text = role.RoleName,
Value = role.RoleId
});
// Get Users
IEnumerable<User> users = (from user in dbContext.Users
select new User
{
UserId = user.UserId,
FirstName = user.FirstName,
LastName = user.LastName,
DepotId = user.DepotId,
DepartmentId = user.DepartmentId,
RoleId = user.RoleId,
// OR
// RoleId = dbContext.Roles.Where(r => r.UserId == user.UserId).First().RoleId
//
});
return users;
}
In your view:
<div>
#Html.DropDownListFor(model => model.RoleId, (SelectList)ViewBag.Roles)
</div>
if you have 2 tables in your database.. one that holds the User Info (for arguments sake the name of the table will be User), and the other that holds the possible roles (name of table is Role).. you can create a property in the User table called roleID(foreign key) to hold the Primary Key (ID) of the Role Table. So in the Role table let's say you have 2 properties, ID and text. The ID holds the unique value to represent the text. e.g ID = 1, text = Administrator... ID = 2, text = Member... so on and so on... then when you create a user, based on the example you gave above, you would see this is your User table test 2 test2 2016-11-03 1 1 1 //if you made him an administator
In your Details view you can display the text and not the ID by making sure that in your User model you have public virtual Role role { get; set; }
Then:
#Html.DisplayNameFor(model => model.Role.text)
Then in your User Controller under the Create Action you stuff the possible roles in a ViewBag:
public ActionResult Create()
{
ViewBag.roleID = new SelectList(database.Role, "ID", "text");
return View()
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "ID, firstName, lastName, enrollmentDate, departmentID, depotID, roleID")] User user)
{
if(ModelState.IsValid)
{
ViewBag.roleID = new SelectList(database.Role, "ID", "text", user.roleID);
return View(user);
}
}
Then in your Create cshtml page :
#Html.DropDownList("roleID", null, htmlAttributes: new { #class = "form-control" })
assuming you are using bootstrap for the form-control class name.
I am new to MVC and trying to understand ViewModels. I understand how to use Create and a ViewModel, But am unsure how to Edit using a View Model?
My VM:
public class BookingViewModel
{
[Display (Name = "Select Patient")]
public Guid PatientId { get; set; }
public IEnumerable<SelectListItem> PatientList { get; set; }
[Display(Name = "Select Practice")]
public Guid PracticeId { get; set; }
public IEnumerable<SelectListItem> PracticeList { get; set; }
[Display(Name = "Select Optician")]
public Guid OpticianId { get; set; }
public IEnumerable<SelectListItem> OpticiansList { get; set; }
public Optician Optician { get; set; }
[Display(Name = "Select Date")]
[DataType(DataType.Date)]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy}")]
public DateTime Date { get; set; }
[Display(Name = "Select Time")]
public Guid TimeId { get; set; }
public IEnumerable<SelectListItem> TimeList { get; set; }
}
My Controller:
public ActionResult Create()
{
// Creates a new booking
BookingViewModel bookingViewModel = new BookingViewModel();
// Initilises Select List
ConfigureCreateViewModel(bookingViewModel);
return View(bookingViewModel);
}
// Initilises Select List
public void ConfigureCreateViewModel(BookingViewModel bookingViewModel)
{
// Displays Opticians Name - Needs changed to full name
bookingViewModel.OpticiansList = db.Opticians.Select(o => new SelectListItem()
{
Value = o.OpticianId.ToString(),
Text = o.User.FirstName
});
// Displays Patients name - needs changed to full name DOB
bookingViewModel.PatientList = db.Patients.Select(p => new SelectListItem()
{
Value = p.PatientId.ToString(),
Text = p.User.FirstName
});
// Displays Practice Name
bookingViewModel.PracticeList = db.Practices.Select(p => new SelectListItem()
{
Value = p.PracticeId.ToString(),
Text = p.PracticeName
});
// Displays Appointment Times
bookingViewModel.TimeList = db.Times.Select(t => new SelectListItem()
{
Value = t.TimeId.ToString(),
Text = t.AppointmentTime
});
}
// Allows Admin to create booking for patient
// POST: Bookings1/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(BookingViewModel bookingViewModel)
{
// to ensure date is in the future
if (ModelState.IsValidField("Date") && DateTime.Now > bookingViewModel.Date)
{
ModelState.AddModelError("Date", "Please enter a date in the future");
}
// if model state is not valid
if (!ModelState.IsValid)
{
// Initilises Select lists
ConfigureCreateViewModel(bookingViewModel);
return View(bookingViewModel); // returns user to booking page
}
else // if model state is Valid
{
Booking booking = new Booking();
// Sets isAvail to false
booking.isAvail = false;
booking.PracticeId = bookingViewModel.PracticeId;
booking.Optician = bookingViewModel.Optician;
booking.PatientId = bookingViewModel.PatientId;
booking.Date = bookingViewModel.Date;
booking.TimeId = bookingViewModel.TimeId;
// Generates a new booking Id
booking.BookingId = Guid.NewGuid();
// Adds booking to database
db.Bookings.Add(booking);
// Saves changes to Database
db.SaveChanges();
// Redirects User to Booking Index
return RedirectToAction("Index");
}
}
I am really unsure how to Edit a View Model, any advice would be greatly appreciated
public ActionResult Edit(Guid? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Booking booking = db.Bookings.Find(id);
if (booking == null)
{
return HttpNotFound();
}
BookingViewModel bookingViewModel = new BookingViewModel()
{
Date = booking.Date,
OpticianId = booking.OpticianId,
PatientId = booking.PatientId,
PracticeId = booking.PracticeId,
TimeId = booking.TimeId
};
return View(booking, bookingViewModel);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(Booking booking)
{
if (ModelState.IsValid)
{
db.Entry(booking).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(booking);
}
There is no overload of Controller.View method that accepts 2 models/objects.
You Edit() GET method needs to be
public ActionResult Edit(Guid? id)
{
....
BookingViewModel bookingViewModel = new BookingViewModel()
{
....
}
// Call the ConfigureCreateViewModel() method so that you SelectList's are populated
// as you have done in the Create() method (ConfigureViewModel might be a better name?)
ConfigureCreateViewModel(bookingViewModel);
return View(bookingViewModel); // adjust this
}
and the POST method needs to be
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(BookingViewModel model)
{
if (!ModelState.IsValid)
{
ConfigureCreateViewModel(model)
return View(model);
}
// Get your data model and update its properties based on the view model
Booking booking = db.Bookings.Find(id);
booking.PracticeId = bookingViewModel.PracticeId;
booking.OpticianId = bookingViewModel.OpticianId;
.... // etc
db.Entry(booking).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
and your view should have #model BookingViewModel
Side note: Your view model should not contain property public Optician Optician { get; set; } (you binding to the property public Guid OpticianId { get; set; })