10

Хорошо, это странно. Я не могу использовать BindAttribute's Include и Exculude свойства со сложными типами вложенных объектов на 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 действия:

[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 класса, как это указано здесь:

How do I use the [Bind(Include="")] attribute on complex nested objects?

+1

Я думаю, что лучше всего сделать это, как описано в другом сообщении, на которое вы ссылаетесь. – JoJa

+0

Да, похоже, так: я не могу сделать это в проекте модели домена. Я должен определить частичные классы внутри проекта mvc и сделать это там, я думаю. – tugberk

+0

Попробуйте мое решение здесь https://stackoverflow.com/questions/47644699/how-to-bind-nested-objects-on-httppost-in-asp-net-mvc/47645228#47645228 –

ответ

15

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

[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 NUL л.

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

Так просто реадаптироваться ваши модели вид:

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

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

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

+0

спасибо @darin. Это единственный способ. Я не вникнул в это, но можем ли мы настроить класс DefaultModelBinder, чтобы сделать эту работу, создав новое настраиваемое связующее устройство? – tugberk

+2

@tugberk, я действительно не пошел бы по этому маршруту. Использование моделей просмотра - способ решить эти проблемы. И не только такие проблемы. Вы всегда должны использовать модели представления в приложении ASP.NET MVC. –

+0

Для вас вторая рекомендация, я всегда между ними: s – tugberk

1

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

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

I.E.

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" /> 
} 

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

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

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

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