Brian Brian - 2 months ago 21
ASP.NET (C#) Question

ASP.NET MVC Edit ViewModel with DropDownList

I have included my Model, ViewModel, Controller and View below. The trouble I'm having is retrieving data to my DropDownList control in my Edit Action were I try to retrieve data based on the "id" value passed. I haven't even gotten to the stage to attempt to Edit/Update the data yet. My Edit Action based on "id" value works fine if I don't attempt to retrive the DropDownList value. I had to initally add code for my "Create" Action in order to retrive the data to my DropDownList but not sure what I'm missing for the Edit.

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 State
{
public int StId { get; set; }
public string StAbbr { get; set; }

public List<Customer> Customers { 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;
customervm.StId = customer.StId;
}
return View(customervm);
}
}


Create View:

<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>

<div class="form-group">
<button type="submit" class="btn btn-primary">Submit</button>
</div>


Edit View:

<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">Update</button>
</div>

Answer

It is same as your create action, Load the collection property for all states (States) and also set the property for the selected item (StId) on your view model object.

So add this code to your Edit GET action method.

var customervm = new CustomerFormViewModel();
{
   // Your existing code to map the entity property values goes here
} 

//Load all the states

var states = _context.States.ToList();
customervm.States = states;

//Set the selected state
customervm.StId = customer.StId;

return View();
Comments