Атрибут 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 в класс напрямую, так как это может вызвать другие проблемы, такие как репликация кода, и не учитывает определенные сценарии, где вы можете захотеть иметь другую привязку.
(Я изменил имена переменных для некоторой ясности. Я также знаю, что ваш вопрос довольно устарел, однако, в поисках ответа сам, это первый, на котором я наткнулся, прежде чем пытаться использовать свои собственные решения и приходить к тому, который я опубликовал Надеюсь, это поможет другим людям, которые ищут решение одной и той же проблемы.)