Атрибут bind включает и исключает свойство со сложными типами вложенных объектов

Ок, это странно Я не могу использовать свойства BindAttribute Include и Exclude со вложенными объектами сложного типа в ASP.NET MVC.

Вот что я сделал:

Модель:

public class FooViewModel {

    public Enquiry Enquiry { get; set; }
}

public class Enquiry {

    public int EnquiryId { get; set; }
    public string Latitude { get; set; }
}

HTTP POST action:

[ActionName("Foo"), HttpPost]
public ActionResult Foo_post(
    [Bind(Include = "Enquiry.EnquiryId")]
    FooViewModel foo) {

    return View(foo);
}

Вид:

@using (Html.BeginForm()) {

    @Html.TextBoxFor(m => m.Enquiry.EnquiryId)
    @Html.TextBoxFor(m => m.Enquiry.Latitude)

    <input type="submit" value="push" />
}

вообще не работает. Могу ли я выполнить эту работу, только если определю класс BindAttribute для класса Enquiry, как указано здесь:

Как использовать атрибут [Bind (Include = " ")] для сложных вложенных объектов?

Ответ 1

Да, вы можете заставить его работать так:

[Bind(Include = "EnquiryId")]
public class Enquiry 
{
    public int EnquiryId { get; set; }
    public string Latitude { get; set; }
}

и ваше действие:

[ActionName("Foo"), HttpPost]
public ActionResult Foo_post(FooViewModel foo) 
{
    return View(foo);
}

Это будет включать только привязку EnquiryId и оставить Latitude null.

Говоря это, использование атрибута Bind не является тем, что я бы рекомендовал вам. Моя рекомендация - использовать модели просмотра. Внутри этих моделей просмотра вы включаете только те свойства, которые имеют смысл для этого конкретного вида.

Итак, просто прочтите ваши модели просмотра:

public class FooViewModel 
{
    public EnquiryViewModel Enquiry { get; set; }
}

public class EnquiryViewModel 
{
    public int EnquiryId { get; set; }
}

Там вы идете. Больше не нужно беспокоиться о привязке.

Ответ 2

ИМХО есть лучший способ сделать это.

По существу, если у вас есть несколько моделей в модели представления, подпись постконтроллера будет содержать те же модели, что и модель представления.

т.е.

public class FooViewModel {
    public Bar BarV { get; set; }
    public Enquiry EnquiryV { get; set; }
    public int ThisNumber { get; set; }
}

public class Bar {
    public int BarId { get; set; }
}

public class Enquiry {
    public int EnquiryId { get; set; }
    public string Latitude { get; set; }
}

И пост-действие в контроллере будет выглядеть так.

[ActionName("Foo"), HttpPost]
public ActionResult Foo_post(
    [Bind(Include = "EnquiryId")]
    Enquiry EnquiryV,
    [Bind(Include = "BarId"])]
    Bar BarV,
    int ThisNumber
{
    return View(new FooViewModel { Bar = BarV, Enquiry = EnquiryV, ThisNumber = ThisNumber });
}

Все, пока вид по-прежнему выглядит как

@using (Html.BeginForm()) {

    @Html.TextBoxFor(m => m.EnquiryV.EnquiryId)
    @Html.TextBoxFor(m => m.EnquiryV.Latitude)
    @Html.TextBoxFor(m => m.BarV.BarId)
    @Html.TextBoxFor(m => m.ThisNumber)

    <input type="submit" value="push" />
}

Имейте в виду, что эта форма по-прежнему будет возвращать Latitude (так, как вы ее настроили), однако, поскольку она не включена в строку Bind Include для запроса в действие post, действие не примет новое значение в результате запроса. Я бы предложил сделать широту либо отключенной, либо не элементом формы, чтобы предотвратить дополнительные данные проводки.

В любом другом сценарии вы можете использовать bind просто отлично, но по какой-то причине ему не нравится текстовая нотация для сложных моделей.

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

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