Reputation: 605
I am trying to pass categorized value (string) into model that requires int value.
I have model AccountViewModel
below:
[Required]
[Display(Name = "Fleet Type")]
public int FleetType { get; set; }
When a user registers for the first time, they must choose the fleet type
I have an AccountController
:
public async Task<ActionResult> Register(RegisterViewModel model)
{
if (ModelState.IsValid)
{
var fleetType = 0;
string fleetTypeStr = ViewBag.FleetType;
switch (fleetTypeStr)
{
case "17' Truck":
fleetType = 1;
break;
case "20' Truck":
fleetType = 2;
break;
default:
fleetType = 0;
break;
}
var user = new ApplicationUser
{
UserName = model.Email,
Email = model.Email,
LoginId = model.LoginId,
FirstName = model.FirstName,
LastName = model.LastName,
//FleetType = model.FleetType,
FleetType = fleetType,
};
In Account/Register view:
ViewBag.FleetTypeList = new SelectList(new List<string>
{
"Pickup Truck", "Cargo Vans", "10' Truck", "15' Truck", "17' Truck",
"20' Truck", "26' Truck"
}, "fleetTypeList");
@using (Html.BeginForm("Register", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
// ........
@Html.DropDownListFor(m => m.FleetType, ViewBag.FleetTypeList as SelectList, new { @class = "btn btn-primary btn-lg dropdown-toggle" })
But I get a error message because the ViewBag.FleetTypeList
is list of strings but the datatype FleetType
requires int inside the model.
Please help me!
Upvotes: 0
Views: 2306
Reputation: 218822
You should not be reading the ViewBag
value in your HttpPost action method.
ViewBag is usually used to transfer some data from your GET action method to the view. You can use it to pass the list of items you want to build your dropdown.
With your current code, the HTML helper will render a SELECT element with name attribute value "FleetType" and when you submit the form, the selected option's value attribute value (in your case the same as the text) will be posted as the value of this SELECT element. But since your FleetType property is of int
type, model binder will not be able to bind that string
value to the int property !
A better solution is added after this. Read further.
You should add a string type property to your view model and use that
public class RegisterViewModel
{
public string SelectedFleet { set;get;}
// Your other properties
}
And in the view, use this property as the first param if the DropDownListFor
helper method.
@Html.DropDownListFor(m => m.SelectedFleet ,
ViewBag.FleetTypeList as SelectList,
new { @class = "btn btn-primary btn-lg dropdown-toggle" })
Now in your httppost action method, read the SelectedFleet
value and use it
var fleetType = 0;
var fleetTypeStr = model.SelectedFleet ;
switch (fleetTypeStr)
{
}
But a better solution is to completely avoid the switch block. What if you set the option's value
attribute to the corresponding int value ?
So update your GET action method to have a list of SelectListItem in ViewBag.FleetTypeList
ViewBag.FleetTypeList = new List<SelectListItem>{
new SelectListItem { Text="17 Truck", Value="1"},
new SelectListItem { Text="20 Truck", Value="2"},
new SelectListItem { Text="Something else", Value="0"}
};
and in the view
@Html.DropDownListFor(m => m.FleetType, ViewBag.FleetTypeList as List<SelectListItem>
, new { @class = "btn btn-primary btn-lg dropdown-toggle" })
Now the SELECT element will be rendered with name attribute "FleetType" and when you submit the form, the selected option's value (int) will be submitted. You can avoid the switch block and simply use model.FleetType
wherever needed.
Upvotes: 2