asp.net MVC: редактирование встроенных объектов - PullRequest
0 голосов
/ 11 сентября 2009

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

Сейчас я имею дело с действием Create, поэтому я делаю b = new B (); b.A = новый A ();

Теперь я отрисовываю форму для B, а затем вызываю частичное представление для A, передавая его b.A.

Но я получаю либо FormCollection, либо мой новый объект A с полем B, установленным в нуль. В первом случае все хорошо, но что я буду делать, если форма не сможет фальсифицировать? Нужно ли создавать объекты вручную с неверными данными и снова передавать их с недействительным ModelState? Возможен ли второй вариант?

Или мне просто нужно избегать наличия вложенного представления? В качестве альтернативы я подумал создать специальный объект модели просто для обработки формы со всеми значениями как для A, так и для B, а затем, когда эта форма будет проверена, я заполнил бы вручную объекты A и B и сохранил бы их. Это единственное решение?

Ответы [ 3 ]

1 голос
/ 11 сентября 2009

создайте свою собственную модель, которая включает в себя A и B, а затем создайте вид из этой модели Когда вы отправите форму, вы сможете просто обновить свою пользовательскую модель и обновить / добавить отдельные модели.

public class CustomViewModel
{
    public ModelA myAModel {get;set;}
    public ModelB mybModel {get;set;}
}

представление для этой модели создаст форму, которая включает в себя A и B и позволит вам затем Ваша отправленная коллекция форм может затем использоваться для установки значений для каждой отдельной модели и обновления / создания, а затем разделения.

1 голос
/ 11 сентября 2009

Вы должны быть в состоянии использовать A и B, как вы описали.

Предположим, у нас есть следующее:

public class B {
    public A A {get; set;}
    public string X {get; set;}
    public int Y {get;set;}
}

public class A {
    public string Z {get; set;}
} 

//then in your controller:

public ActionResult Edit () {
    return View ( 
        new B {
            A = new A { Z = "AyyZee" } ,
            X = "BeeEcks",
            Y = 7
        } );
}

Итак, ваша модель является экземпляром B.

Ваше представление и ваше вложенное частичное представление должны генерировать HTML примерно так:

 <input type="text" name="A.Z" value="AyyZee" />
 <input type="text" name="X" value="BeeEcks" />
 <input type="text" name="Y" value="7" />

Теперь связыватель модели по умолчанию должен иметь возможность подключиться:

[AcceptVerbs( HttpVerbs.Post )]
public ActionResult Edit (B input) {
    // apply changes
    //the binder should have populated input.A
}

Обратите внимание, что это работает, только если A и B имеют конструктор по умолчанию и являются относительно простыми классами. Если у вас есть что-то более сложное, вы можете использовать свой собственный переплет:

[AcceptVerbs( HttpVerbs.Post )]
public ActionResult Edit ( [ModelBinder( typeof( BBinder ) )] B input) {
    //...
}

public class BBinder : IModelBinder
{
    public object BindModel( ControllerContext controllerContext, ModelBindingContext bindingContext )
    {
        return  
            new B {
                A = new A { Z = Request["A.Z"] } ,
                X = Request["X"],
                Y = int.Parse(Request["Y"])
            };
    }
}
0 голосов
/ 14 сентября 2009

Мои проблемы с этим кодом были вызваны двумя причинами в классе модели:

  1. Поля должны быть свойствами, а не обычными полями
  2. Отсутствовал конструктор, который инициализировал бы внутренние объекты

Таким образом, классы из решения выше должны быть:

public class B {
  public A a {get; set;}
  public string x {get; set;}
  public int y {get;set;}
  public B() {
    a = new A();
  }
}

public class A {    
  public string z {get; set;}
  public A() {}
 } 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...