ASP.NET MVC - Настраиваемая привязка модели для полей идентификатора

у меня есть следующие сущности:

public class Category
{
    public virtual int CategoryID { get; set; }

    [Required(ErrorMessage = "Section is required")]
    public virtual Section Section { get; set; }

    [Required(ErrorMessage = "Category Name is required")]
    public virtual string CategoryName { get; set; }
}

public class Section
{
    public virtual int SectionID { get; set; }
    public virtual string SectionName { get; set; }
}

Теперь в моем представлении категории добавления у меня есть текстовое поле для ввода идентификатора раздела, например:

<%= Html.TextBoxFor(m => m.Section.SectionID) %>

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

Если ключ модели заканчивается идентификатором и имеет значение (значение было вставлено в текстовое поле), установите для родительского объекта (в этом примере раздел) значение Section.GetById (введенное значение), в противном случае установите для родительского объекта значение null.

Я был бы очень признателен за помощь здесь, так как это какое-то время сбивало меня с толку. Спасибо


person nfplee    schedule 03.09.2010    source источник


Ответы (2)


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

person Dave Thieben    schedule 03.09.2010
comment
Спасибо за ссылку. Это действительно помогло в том, что я делал до сих пор. Если бы вы могли проверить мою попытку решения и помочь завершить его, я был бы очень признателен :). - person nfplee; 04.09.2010

Используя решение, опубликованное Дэйвом Тибеном, я придумал следующее:

public class CustomModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);

        if (bindingContext.ModelType.Namespace.EndsWith("Models.Entities") && value != null && (Utilities.IsInteger(value.AttemptedValue) || value.AttemptedValue == ""))
        {
            if (value.AttemptedValue != "")
                return Section.GetById(Convert.ToInt32(value.AttemptedValue));
            else
                return null;
        }
        else
            return base.BindModel(controllerContext, bindingContext);
    }
}

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

person nfplee    schedule 03.09.2010
comment
если вы все еще работаете над этим, в операторе if у вас есть value.AttemptedValue == "", а затем в следующей строке у вас есть value.AttemptedValue != "", поэтому похоже, что он никогда не попадет в ваш код Section.GetById (). - person Dave Thieben; 07.09.2010
comment
Еще раз приветствую ваше предложение, но логика верна, даже если нужно немного прибраться, чтобы сделать его более читабельным. Решением проблемы было создание настраиваемого DropDownList, который обрабатывает свойство Selected объекта SelectItem. Надеюсь, они исправят ошибку в следующей версии MVC. - person nfplee; 09.09.2010
comment
У меня есть привязка пользовательской модели просмотрите его здесь, который пытается отсортировать свойства так, чтобы поля идентификаторов всегда были привязаны первыми. Я позволяю фактическому классу модели представления - в его установщиках свойств - запускать загрузку собственного репозитория, а не настраивать привязку. (перечитав ваш O.P., я понимаю, что это не совсем подходит, но, возможно, это подскажет кому-то еще) - person bkwdesign; 15.10.2013