如何在View _CreateOrEdit.cshtml中使用CheckBox获取整数或字符数据库字段

时间:2011-07-29 17:58:16

标签: asp.net-mvc-3 entity-framework-4 checkbox razor html-helper

MVC 3,EntityFramework 4.1,数据库优先,Razor定制:

我有一个旧数据库,有时使用Int16或Char类型作为必须在MVC _CreateOrEdit.cshtml视图中显示为CheckBox的字段。如果是Int,则1 = true且0 = false。如果是Char,则“Y”=真,“N”=假。这对于实体框架来说自动转换太多了。对于详细信息视图,我可以使用:

@Html.CheckBox("SampleChkInt", Model.SampleChkInt==1?true:false)

但是在_CreateOrEdit.cshtml视图中,这不能代替EditorFor。 这该怎么做?我在想一个自定义的HtmlHelper,但我发现的例子并没有告诉我如何告诉EntityFramework正确更新数据库。还有其他我可能想要做的自定义,其中MVC View与数据库不完全匹配,以便EntityFramework进行更新。回答这个问题就是一个很好的例子。我正在研究一个示例项目,使用以下自动生成的(因此我无法对其进行更改)模型类:

namespace AaWeb.Models
{
    using System;
    using System.Collections.Generic;

    public partial class Sample
    {
        public int SampleId { get; set; }
        public Nullable<bool> SampleChkBit { get; set; }
        public Nullable<short> SampleChkInt { get; set; }
        public Nullable<System.DateTime> SampleDate { get; set; }
        public string SampleHtml { get; set; }
        public Nullable<int> SampleInt { get; set; }
        public Nullable<short> SampleYesNo { get; set; }
        public string Title { get; set; }
        public byte[] ConcurrencyToken { get; set; }
    }
}

3 个答案:

答案 0 :(得分:1)

我明白了。不需要模型绑定器或Html Helper扩展:

在_CreateOrEdit.cshtml中,我为复选框创建了一个新名称SampleChkIntBool,并根据模型SampleChkInt的值设置它:

@Html.CheckBox("SampleChkIntBool", Model == null ? false : ( Model.SampleChkInt == 1 ? true : false ), new { @value = "true" })

然后,在Sample.Controller的[HttpPost] Create和Edit方法中,我使用Request [“SampleChkIntBool”]获取SampleChkIntBool的值,并在保存之前使用它来设置模型SampleChkInt:

string value = Request["SampleChkIntBool"];
// @Html.CheckBox always generates a hidden field of same name and value false after checkbox,
// so that something is always returned, even if the checkbox is not checked.
// Because of this, the returned string is "true,false" if checked, and I only look at the first value.
if (value.Substring(0, 4) == "true") { sample.SampleChkInt = 1; } else { sample.SampleChkInt = 0; }

答案 1 :(得分:0)

我相信在这里可以使用自定义模型绑定器来处理模型的各种映射。

ASP.NET MVC Model Binder for Generic Type

等 等

答案 2 :(得分:0)

以下是从复选框到数据库的方法,没有控制器中的特殊代码:

// The following statement added to the Application_Start method of Global.asax.cs is what makes this class apply to a specific entity:
// ModelBinders.Binders.Add(typeof(AaWeb.Models.Sample), new AaWeb.Models.SampleBinder());

// There are two ways to do this, choose one:
// 1. Declare a class that extends IModelBinder, and supply all values of the entity (a big bother).
// 2. Declare a class extending DefaultModelBinder, and check for and supply only the exceptions (much better).

// This must supply all values of the entity:
//public class SampleBinder : IModelBinder 
//{
//    public object BindModel(ControllerContext cc, ModelBindingContext mbc)
//    {
//        Sample samp = new Sample();
//        samp.SampleId = System.Convert.ToInt32(cc.HttpContext.Request.Form["SampleId"]);
//        // Continue to specify all of the rest of the values of the Sample entity from the form, as done in the above statement.
//        // ...
//        return samp;
//    }
//}

// This must check the property names and supply appropriate values from the FormCollection.
// The base.BindProperty must be executed at the end, to make sure everything not specified is take care of.
public class SampleBinder : DefaultModelBinder
{
    protected override void BindProperty( ControllerContext cc, ModelBindingContext mbc, System.ComponentModel.PropertyDescriptor pd)
    {
        if (pd.Name == "SampleChkInt")
        {
            // This converts the "true" or "false" of a checkbox to an integer 1 or 0 for the database.
            pd.SetValue(mbc.Model, (Nullable<Int16>)(cc.HttpContext.Request.Form["SampleChkIntBool"].Substring(0, 4) == "true" ? 1 : 0));

            // To do the same in the reverse direction, from database to view, use pd.GetValue(Sample object).

            return;
        }

        // Need the following to get all of the values not specified in this BindProperty method:
        base.BindProperty(cc, mbc, pd);
    } 
}