【问题标题】:How to render a model property of string type as checkbox in ASP.NET MVC如何在 ASP.NET MVC 中将字符串类型的模型属性呈现为复选框
【发布时间】:2011-08-26 10:49:07
【问题描述】:

我想在 MVC 视图上将字符串类型显示为复选框,但在 HTTP post 上将其作为字符串类型返回。问题是它在 HTTP Post 上返回 false。以下是我的代码:

查看:

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

型号:

public class Car
    {
        public string IsFourWheel { get; set; } //bad naming, but it can contain any type, include boolean
    }

控制器:

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

非常感谢任何理想。

【问题讨论】:

    标签: asp.net-mvc asp.net-mvc-3 asp.net-mvc-2


    【解决方案1】:

    您可以尝试在帮助程序中指定模板名称:

    @Html.EditorFor(car => car.IsFourWheel, "CheckBox")
    

    并定义模板以您想要的方式呈现数据,~/Views/{YourControllerName}/EditorTemplates/CheckBox.cshtml~/Views/Shared/EditorTemplates/CheckBox.cshtml

    您可以在此处找到 Brad Wilson 关于 MVC 模板的一系列帖子:

    Brad Wilson: ASP.NET MVC 2 Templates, Part 1: Introduction

    它适用于 MVC 2,但大多数概念仍然适用于 MVC 3(Razor 语法除外)。

    更新:

    实际上,您可能不需要为此自定义模板。尝试改用@Html.CheckBoxFor(car =&gt; car.IsFourWheel)

    更新 2:

    将以下模板放入~/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" })
    

    那么在你看来,这样称呼它:

    @Html.EditorFor(model => model.IsFourWheel, "IsFourWheel")
    

    我对其进行了测试,绑定在 GET 和 POST 场景中都有效。

    【讨论】:

    • 谢谢。您能否详细说明如何在 CheckBox.cshtml 上实现它。
    • 例如,您可以查看 MVC 源代码中布尔字段(CheckBoxFor 呈现的内容)的默认模板,例如 Boolean.ascx,但正如我所说,除非您是使用您的 IsFourWheels 属性做一些非常具体的事情,您可能不需要模板,只需使用 @Html.CheckBoxFor(car =&gt; car.IsFourWheel) 代替。
    • Daniel Liuzzi,@Html.CheckBoxFor 需要 bool 类型。
    • @Pingpong 是的,我的错。我使用模板更新了答案,该模板对存储为字符串的布尔值按预期工作。
    • 谢谢。我将使用它,看看它是否适用于我的实现。
    【解决方案2】:

    你可以像这样改变你的视图模型:

    public class Car
        {
            public string IsFourWheel { get; set; }
            public bool IsFourWheelBool { get { return bool.Parse(IsFourWheel); } }
        }
    

    您的视图将如下所示:

    @Html.EditFor(x => x.IsFourWheelBool);
    

    【讨论】:

    • 需要改变领域模型,这不是理想的。
    • 在视图中使用域模型通常被认为是糟糕的设计。 (stackoverflow.com/questions/4865806/…) 最好创建视图模型以方便您查看。使用 automapper (automapper.org) 之类的工具,可以轻松地从域模型创建视图模型。但手动创建视图模型也是可行的。
    • 谢谢。我知道。我的问题只是一个简化的例子。
    【解决方案3】:

    我认为如果你在你的模型中添加一个 ID 会更容易。像这样
    型号:

    public class Car
    {
        public int CarID { get; set; }
        public string IsFourWheel { get; set; }        
    }
    


    查看:

    @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" />
        }
    }
    

    控制器:

    [HttpPost]
    public ActionResult Index(List<int> carID)
    {
        //handle selected cars here
        return View();
    }
    

    【讨论】:

    • 感谢您的建议。我更新了我的问题。我有一些汽车,在邮寄时需要。您当前的解决方案仅适用于单车。
    • 当有汽车的集合时,输入标签需要一个允许模型绑定器分配值的id/name。
    猜你喜欢
    • 1970-01-01
    • 2014-06-24
    • 2016-10-10
    • 1970-01-01
    • 2012-09-30
    相关资源
    最近更新 更多