Brian
asked on
ASP.NET MVC Create/Edit ViewModel
Hello Experts,
I'm trying to create one Action to handle my Create/Edit instead of having two separate actions one for Create and the other for Edit. Currently, my CustomerController Action below shows that two Action Methods (Create/Edit) which both work. I would like to be able to combine both of those into just one Action.
Customer Model:
State Model:
Manufacturer Model:
CustomerFormViewModel:
CustomerController:
CustomerForm View:
I'm trying to create one Action to handle my Create/Edit instead of having two separate actions one for Create and the other for Edit. Currently, my CustomerController Action below shows that two Action Methods (Create/Edit) which both work. I would like to be able to combine both of those into just one Action.
Customer Model:
public class Customer
{
public int CustId { get; set; }
public string CustDisplayName { get; set; }
public string CustFirstName { get; set; }
public string CustLastName { get; set; }
public string CustCompanyName { get; set; }
public string CustAddress { get; set; }
public string CustPhoneNumber { get; set; }
public string CustMobileNumber { get; set; }
public string CustEmailAddress { get; set; }
public int StId { get; set; }
public State State { get; set; }
}
State Model:
public class Customer
{
public int CustId { get; set; }
public string CustDisplayName { get; set; }
public string CustFirstName { get; set; }
public string CustLastName { get; set; }
public string CustCompanyName { get; set; }
public string CustAddress { get; set; }
public string CustPhoneNumber { get; set; }
public string CustMobileNumber { get; set; }
public string CustEmailAddress { get; set; }
public int StId { get; set; }
public State State { get; set; }
}
Manufacturer Model:
public class Manufacturer
{
public int MfrId { get; set; }
public string MfrCompanyName { get; set; }
public string MfrWebsiteDomainName { get; set; }
}
CustomerFormViewModel:
public class CustomerFormViewModel
{
public int CustId { get; set; }
[Required(ErrorMessage = "Display Name is required!")]
[Display(Name = "Display Name")]
[StringLength(100)]
public string CustDisplayName { get; set; }
[Display(Name = "First Name")]
[StringLength(50)]
public string CustFirstName { get; set; }
[Display(Name = "Last Name")]
[StringLength(50)]
public string CustLastName { get; set; }
[Display(Name = "Company Name")]
[StringLength(50)]
public string CustCompanyName { get; set; }
[Display(Name = "Phone Number")]
[DataType(DataType.PhoneNumber)]
[StringLength(12)]
[RegularExpression(@"((\(\d{3}\) ?)|(\d{3}-))?\d{3}-\d{4}", ErrorMessage = "Invalid Phone Number format!")]
public string CustPhoneNumber { get; set; }
[Display(Name = "Mobile Number")]
[DataType(DataType.PhoneNumber)]
[StringLength(12)]
[RegularExpression(@"((\(\d{3}\) ?)|(\d{3}-))?\d{3}-\d{4}", ErrorMessage = "Invalid Number!")]
public string CustMobileNumber { get; set; }
[Display(Name = "Email Address")]
[DataType(DataType.EmailAddress)]
[StringLength(320)]
public string CustEmailAddress { get; set; }
[Required(ErrorMessage = "Address is required!")]
[Display(Name = "Address")]
[StringLength(100)]
public string CustAddress { get; set; }
[Required(ErrorMessage = "State is required!")]
[Display(Name = "State")]
public int StId { get; set; }
public IEnumerable<State> States { get; set; }
}
CustomerController:
public class CustomerController : Controller
{
private WebAppDbContext _context;
public CustomerController(WebAppDbContext context)
{
_context = context;
}
// GET: /<Customer>/
public IActionResult Index()
{
return View(_context.Customers.ToList());
}
public ActionResult Create()
{
var states = _context.States.ToList();
var viewModel = new CustomerFormViewModel
{
States = states
};
return View(viewModel);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(CustomerFormViewModel vm)
{
if (ModelState.IsValid)
{
var customer = new Customer();
{
customer.CustDisplayName = vm.CustDisplayName;
customer.CustFirstName = vm.CustFirstName;
customer.CustLastName = vm.CustLastName;
customer.CustCompanyName = vm.CustCompanyName;
customer.CustAddress = vm.CustAddress;
customer.CustPhoneNumber = vm.CustPhoneNumber;
customer.CustMobileNumber = vm.CustMobileNumber;
customer.CustEmailAddress = vm.CustEmailAddress;
customer.StId = vm.StId;
}
_context.Customers.Add(customer);
_context.SaveChanges();
return RedirectToAction("Index");
}
else
{
vm.States = _context.States.ToList();
return View(vm);
}
}
public ActionResult Edit(int? id)
{
if (id == null)
{
return NotFound();
}
var customervm = new CustomerFormViewModel();
{
Customer customer = _context.Customers.SingleOrDefault(c => c.CustId == id);
if (customer == null)
{
return NotFound();
}
customervm.CustId = customer.CustId;
customervm.CustDisplayName = customer.CustDisplayName;
customervm.CustFirstName = customer.CustFirstName;
customervm.CustLastName = customer.CustLastName;
customervm.CustCompanyName = customer.CustCompanyName;
customervm.CustAddress = customer.CustAddress;
customervm.CustPhoneNumber = customer.CustPhoneNumber;
customervm.CustMobileNumber = customer.CustMobileNumber;
customervm.CustEmailAddress = customer.CustEmailAddress;
var states = _context.States.ToList();
customervm.States = states;
//Set the selected state
customervm.StId = customer.StId;
}
return View(customervm);
}
}
CustomerForm View:
@using (Html.BeginForm("Save", "Customer"))
{
<div class="form-group">
@Html.LabelFor(c => c.CustDisplayName)
@Html.TextBoxFor(c => c.CustDisplayName, new { @class = "form-control" })
@Html.ValidationMessageFor(c => c.CustDisplayName)
</div>
<div class="form-group">
@Html.LabelFor(c => c.CustFirstName)
@Html.TextBoxFor(c => c.CustFirstName, new { @class = "form-control" })
</div>
<div class="form-group">
@Html.LabelFor(c => c.CustLastName)
@Html.TextBoxFor(c => c.CustLastName, new { @class = "form-control" })
</div>
<div class="form-group">
@Html.LabelFor(c => c.CustCompanyName)
@Html.TextBoxFor(c => c.CustCompanyName, new { @class = "form-control" })
</div>
<div class="form-group">
@Html.LabelFor(c => c.CustAddress)
@Html.TextBoxFor(c => c.CustAddress, new { @class = "form-control" })
@Html.ValidationMessageFor(c => c.CustAddress)
</div>
<div class="form-group">
@Html.LabelFor(c => c.CustPhoneNumber)
@Html.TextBoxFor(c => c.CustPhoneNumber, new { @class = "form-control" })
@Html.ValidationMessageFor(c => c.CustPhoneNumber)
</div>
<div class="form-group">
@Html.LabelFor(c => c.CustMobileNumber)
@Html.TextBoxFor(c => c.CustMobileNumber, new { @class = "form-control" })
@Html.ValidationMessageFor(c => c.CustMobileNumber)
</div>
<div class="form-group">
@Html.LabelFor(c => c.CustEmailAddress)
@Html.TextBoxFor(c => c.CustEmailAddress, new { @class = "form-control" })
@Html.ValidationMessageFor(c => c.CustEmailAddress)
</div>
<div class="form-group">
@Html.LabelFor(s => s.StId)
@Html.DropDownListFor(s => s.StId, new SelectList(Model.States, "StId", "StAbbr"), "", new { @class = "form-control" })
@Html.ValidationMessageFor(s => s.StId)
</div>
@Html.HiddenFor(c => c.CustId)
<div class="form-group">
<button type="submit" class="btn btn-primary">Save</button>
</div>
}
ASKER
@louisfr,
Sorry, just a little confused. You are showing 2 Actions (Edit / Save). Is there a way to just have 1 Action for retrieving Data based on an ID and if no ID exist create new customer?
Sorry, just a little confused. You are showing 2 Actions (Edit / Save). Is there a way to just have 1 Action for retrieving Data based on an ID and if no ID exist create new customer?
That Save action was in your View.
You can remove the parameters of BeginHtml in your view.
You can remove the parameters of BeginHtml in your view.
@using (Html.BeginForm())
and rename the Save method in my code to Edit.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(CustomerFormViewModel vm)
ASKER
Ok, I modified the Edit Action to what you supplied but with giving me errors. Please see attached code with errors below:
CustomerController:
Errors:
The result of this expression is always "false" since a value of type "int" is never equal to "null" of type "int?"
CustomerController:
private WebAppDbContext _context;
public CustomerController(WebAppDbContext context)
{
_context = context;
}
// GET: /<Customer>/
public IActionResult Index()
{
return View(_context.Customers.ToList());
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(CustomerFormViewModel vm)
{
if (ModelState.IsValid)
{
Customer customer;
if (vm.CustId == null)
customer = new Customer();
else
customer = _context.Customers.SingleOrDefault(c => c.CustId == id);
customer.CustDisplayName = vm.CustDisplayName;
customer.CustFirstName = vm.CustFirstName;
customer.CustLastName = vm.CustLastName;
customer.CustCompanyName = vm.CustCompanyName;
customer.CustAddress = vm.CustAddress;
customer.CustPhoneNumber = vm.CustPhoneNumber;
customer.CustMobileNumber = vm.CustMobileNumber;
customer.CustEmailAddress = vm.CustEmailAddress;
customer.StId = vm.StId;
if (vm.CustId == null)
_context.Customers.Add(customer);
else
_context.Entry(customer).State = EntityState.Modified;
_context.SaveChanges();
return RedirectToAction("Index");
}
else
{
vm.States = _context.States.ToList();
return View(vm);
}
}
}
Errors:
The result of this expression is always "false" since a value of type "int" is never equal to "null" of type "int?"
if (vm.CustId == null)
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
@louisfr,
I think I'm just going to stick with having 2 separate Actions (Create and Edit) instead of combining both Actions into one. I modified my code for that purpose, could you please feel in what I would need for my Edit Action [HttpPost]?
If this needs to be another ticket then please let me know and I'll post another ticket for strictly Edit Action.
CustomerController
I think I'm just going to stick with having 2 separate Actions (Create and Edit) instead of combining both Actions into one. I modified my code for that purpose, could you please feel in what I would need for my Edit Action [HttpPost]?
If this needs to be another ticket then please let me know and I'll post another ticket for strictly Edit Action.
CustomerController
public class CustomerController : Controller
{
private WebAppDbContext _context;
public CustomerController(WebAppDbContext context)
{
_context = context;
}
// GET: /<Customer>/
public IActionResult Index()
{
return View(_context.Customers.ToList());
}
public ActionResult Create()
{
var states = _context.States.ToList();
var viewModel = new CustomerFormViewModel
{
States = states
};
return View(viewModel);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(CustomerFormViewModel vm)
{
if (ModelState.IsValid)
{
var customer = new Customer();
{
customer.CustDisplayName = vm.CustDisplayName;
customer.CustFirstName = vm.CustFirstName;
customer.CustLastName = vm.CustLastName;
customer.CustCompanyName = vm.CustCompanyName;
customer.CustAddress = vm.CustAddress;
customer.CustPhoneNumber = vm.CustPhoneNumber;
customer.CustMobileNumber = vm.CustMobileNumber;
customer.CustEmailAddress = vm.CustEmailAddress;
customer.StId = vm.StId;
}
_context.Customers.Add(customer);
_context.SaveChanges();
return RedirectToAction("Index");
}
else
{
vm.States = _context.States.ToList();
return View(vm);
}
}
public ActionResult Edit(int? id)
{
if (id == null)
{
return NotFound();
}
var customervm = new CustomerFormViewModel();
{
Customer customer = _context.Customers.SingleOrDefault(c => c.CustId == id);
if (customer == null)
{
return NotFound();
}
customervm.CustId = customer.CustId;
customervm.CustDisplayName = customer.CustDisplayName;
customervm.CustFirstName = customer.CustFirstName;
customervm.CustLastName = customer.CustLastName;
customervm.CustCompanyName = customer.CustCompanyName;
customervm.CustAddress = customer.CustAddress;
customervm.CustPhoneNumber = customer.CustPhoneNumber;
customervm.CustMobileNumber = customer.CustMobileNumber;
customervm.CustEmailAddress = customer.CustEmailAddress;
// Retrieve list of States
var states = _context.States.ToList();
customervm.States = states;
// Set the selected state
customervm.StId = customer.StId;
}
return View(customervm);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(CustomerFormViewModel vmEdit)
{
if (ModelState.IsValid)
{
}
return View();
}
}
ASKER
I was able to get this issue resolved. Thank you for your help though.
Open in new window