How to render a model property of string type as checkbox in ASP.NET MVC
I want to display a string type as checkbox on MVC view, but returns it as string type on HTTP post. The problem is that it returns false on HTTP Post. Below is my code:
View:
@model List<Car>
foreach(var car in Model){
bool isFourWheel = false;
if(bool.TryParse(car.IsFourWheel, out isFourWheel){
@Html.CheckBox("IsFourWheel", isFourWheel); //need to be rendered as checkbox, but returns string type 开发者_运维问答on HTTP POST
}
}
Model:
public class Car
{
public string IsFourWheel { get; set; } //bad naming, but it can contain any type, include boolean
}
Controller:
public ActionResult Index()
{
var cars = new List<Car>(){ new Car(){IsFourWheel = "true"},new Car(){IsFourWheel = "false"} };
return View(cars);
}
[HttpPost]
public ActionResult Index(List<Car> cars) **Problem IsFourWheel is false when true is selected **
{
return View(cars);
}
Any ideal would be very much appreciated.
You can try specifying a template name in your helper:
@Html.EditorFor(car => car.IsFourWheel, "CheckBox")
And defining the template to render the data the way you want, in either ~/Views/{YourControllerName}/EditorTemplates/CheckBox.cshtml
or ~/Views/Shared/EditorTemplates/CheckBox.cshtml
.
You can find a whole series of post by Brad Wilson on MVC templates here:
Brad Wilson: ASP.NET MVC 2 Templates, Part 1: Introduction
It is for MVC 2, but most concepts still apply to MVC 3 as well (save for the Razor syntax).
Update:
Actually you probably don't need a custom template for this. Try using @Html.CheckBoxFor(car => car.IsFourWheel)
instead.
Update 2:
Drop the following template in ~/Views/Shared/EditorTemplates
:
IsFourWheel.cshtml
@functions {
private bool IsChecked() {
if (ViewData.Model == null) return false;
return Convert.ToBoolean(ViewData.Model, System.Globalization.CultureInfo.InvariantCulture);
}
}
@Html.CheckBox("", IsChecked(), new { @class = "check-box" })
Then from your view, call it like so:
@Html.EditorFor(model => model.IsFourWheel, "IsFourWheel")
I tested it and binding works in both GET and POST scenarios.
You could alter your viewmodel like this:
public class Car
{
public string IsFourWheel { get; set; }
public bool IsFourWheelBool { get { return bool.Parse(IsFourWheel); } }
}
Your view would look like this:
@Html.EditFor(x => x.IsFourWheelBool);
I think it will be easier, if you add an Id to your model. Just like this
Model:
public class Car
{
public int CarID { get; set; }
public string IsFourWheel { get; set; }
}
View:
@model IEnumerable<Car>
foreach (var car in Model)
{
if(car.IsFourWheel == "true"){
<input type="checkbox" name="carID" value="@car.CarID" checked="checked" />
}
else
{
<input type="checkbox" name="carID" value="@car.CarID" />
}
}
Controller:
[HttpPost]
public ActionResult Index(List<int> carID)
{
//handle selected cars here
return View();
}
精彩评论