Как использовать CheckBox в View _CreateOrEdit.cshtml для целого или символьного поля базы данных - PullRequest
2 голосов
/ 29 июля 2011

MVC 3, EntityFramework 4.1, Database First, настройка Razor:

У меня есть старая база данных, которая иногда использует типы Int16 или Char для поля, которое должно отображаться как CheckBox в представлении MVC _CreateOrEdit.cshtml.Если это Int, 1 = true и 0 = false.Если это Char, "Y" = true и "N" = false.Это слишком много для Entity Framework для автоматического преобразования.Для представления сведений я могу использовать:

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

Но это не сработает вместо EditorFor в представлении _CreateOrEdit.cshtml.Как это сделать?Я думал о собственном 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 ]

1 голос
/ 01 августа 2011

Я понял это. Не требуется модельный переплет или расширение Html Helper:

В _CreateOrEdit.cshtml я создал новое имя SampleChkIntBool для флажка и установил его в соответствии со значением модели SampleChkInt:

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

Затем в методах [HttpPost] Create и Edit Sample.Controller я использую 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; }
0 голосов
/ 16 августа 2011

Вот способ перехода от флажка к базе данных без специального кода в контроллере:

// 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);
    } 
}
0 голосов
/ 29 июля 2011

Я полагаю, что связующее для пользовательской модели было бы здесь для обработки различных сопоставлений с вашей моделью.

Связыватель модели ASP.NET MVC для универсального типа

и т. д.

...