Reputation: 345
I am getting values from a ViewModel into a view for form fields. In one of my DropDownList the values are correct but in another the value repeats itself instead of changing. What am I doing wrong?
ViewModel:
namespace FulfillmentPortal.ViewModels
{
public class ViewModel
{
[Required(ErrorMessage = "Please select a carrier")]
public List<Carrier> CarrierList { get; set; }
[Required(ErrorMessage = "Please select a service")]
public List<CarrierService> ServiceList { get; set; }
}
}
Controller:
public class FulfillmentController : Controller
{
private CarrierModel db = new CarrierModel();
// GET: Fulfillment
public ActionResult Index()
{
ViewModel vm = new ViewModel
{
CarrierList = db.Carriers.ToList(),
ServiceList = db.CarrierServices.ToList()
};
return View(vm);
}
}
View:
@model FulfillmentPortal.ViewModels.ViewModel
@{
ViewBag.Title = "index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div class="panel panel-primary">
<div class="panel-heading">REPORT OPTIONS</div>
<div class="panel-body" style="padding-left:35px;">
<form id="processForm" class="form-horizontal" action="~/Fulfillment/Report" method="post" enctype="multipart/form-data">
<div class="form-group">
<label for="sel1">Carrier:</label>
@Html.DropDownListFor(model => model.CarrierList, new SelectList(Model.CarrierList, "CarrierId", "CarrierName"), "Select a Carrier",
new { @class = "form-control", @style = "width:auto; margin-bottom:15px;" })
<label for="sel2">Carrier Services:</label>
@Html.DropDownListFor(model => model.ServiceList, new SelectList(Model.ServiceList, "Code", "WebName"), "Select a Service",
new { @class = "form-control", @style = "width:auto; margin-bottom:15px;" })
</div>
</form>
</div>
</div>
Model:
public partial class CarrierModel : DbContext
{
public CarrierModel()
: base("name=CarrierModel")
{
}
public virtual DbSet<Carrier> Carriers { get; set; }
public virtual DbSet<CarrierService> CarrierServices { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
}
}
[HttpPost]
public ActionResult Index(ViewModel viewModel)
{
if (ModelState.IsValid)
{
viewModel.CarrierList.ToList();
viewModel.ServiceList.ToList();
}
return View(viewModel);
}
This my controller now. Now my view is just erroring out. I think I am missing something or misunderstanding something.
Upvotes: 0
Views: 139
Reputation: 32139
Your ViewModel
should be as follows:
public class ViewModel
{
[Required(ErrorMessage = "Please select a carrier")]
public int CarrierId {get; set;}
[Required(ErrorMessage = "Please select a service")]
public int ServiceCode {get; set;}
public List<Carrier> CarrierList { get; set; }
public List<CarrierService> ServiceList { get; set; }
}
Then in the view:
<label for="sel1">Carrier:</label>
@Html.DropDownListFor(model => model.CarrierId, new SelectList(Model.CarrierList, "CarrierId", "CarrierName"), "Select a Carrier",
new { @class = "form-control", @style = "width:auto; margin-bottom:15px;" })
<label for="sel2">Carrier Services:</label>
@Html.DropDownListFor(model => model.ServiceCode, new SelectList(Model.ServiceList, "Code", "WebName"), "Select a Service",
new { @class = "form-control", @style = "width:auto; margin-bottom:15px;" })
Then your Index
Post
method should be as follows:
[HttpPost]
public ActionResult Index(ViewModel viewModel)
{
if(ModelState.IsValid)
{
// do whatever you want with `viewModel.CarrierId` and `viewModel.ServiceCode` here
}
viewModel.CarrierList = db.Carriers.ToList();
viewModel.ServiceList = db.CarrierServices.ToList();
return View(viewModel);
}
Upvotes: 1
Reputation: 56726
DropDownListFor(model => model.ServiceList
This is not how this method is supposed to work, and I suspect this is the answer to your problem.
This lambda is supposed to provide a field that will hold a value that this drop down list outputs. For your case you should have two fields in the model:
public class ViewModel
...
public int CarrierId { get; set; }
public string CarrierServiceCode { get; set; }
These will hold currently selected value, on none if nothing is selected (yet). And they are supposed to be used in that lambda:
DropDownListFor(model => model.CarrierServiceCode
Alternatively you could use DropDownList()
method, which does not require a field in the model, and give it a custom name that will be posted with selected value.
Upvotes: 2