开发者

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();
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜