我想在对象B中嵌入一个对象A的实例。我已经有一个动作和一个编辑视图,它为对象B呈现一个表单。我使它成为一个强类型的局部视图,接受B。
我正在处理Create动作,所以我做b = new B(); b.A =新A();
现在我将为B渲染表单,然后调用A的局部视图,将其传递给b.A。
但我得到的是FormCollection,或者我的新A对象,其中B字段设置为null。 在第一种情况下,一切都很好,但如果表格没有出现错误,我该怎么办?我是否需要使用错误的数据手动创建对象,并使用无效的ModelState再次传递它们? 第二种选择是否可能?
或者我只是需要避免使用嵌套视图?作为替代方案,我认为创建一个特殊的模型对象只是为了处理包含A和B的所有值的表单,然后当这个表单验证时,我会手动填充A和B对象并保存它们。这是唯一的解决方案吗?
答案 0 :(得分:1)
你应该能够像你所描述的那样使用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"])
};
}
}
答案 1 :(得分:1)
创建自己的包含A和B的自定义模型,然后从该模型创建视图 当您提交表单时,您只需更新自定义模型并更新/添加单个模型即可。
public class CustomViewModel
{
public ModelA myAModel {get;set;}
public ModelB mybModel {get;set;}
}
该模型的视图将创建一个包含A和B的表单,然后使您能够使用 然后,您发布的formcollection可用于为每个单独模型设置值,然后更新/创建然后单独使用。
答案 2 :(得分:0)
我对此代码的问题是由模型类中的两件事引起的:
所以上面解决方案中的类应该是:
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() {}
}