0

我想在对象 B 中嵌入对象 A 的一个实例。我已经有一个操作和一个编辑视图,它为对象 B 呈现一个表单。我将其设置为一个接受 B 的强类型局部视图。

我现在正在处理 Create 操作,所以我做 b = new B(); bA = 新 A();

现在我将为 B 渲染表单,然后为 A 调用局部视图,并将其传递给 bA

但是我得到的要么是 FormCollection,要么是我的 B 字段设置为 null 的新 A 对象。在第一种情况下,一切都很好,但是如果表单无法验证,我该怎么办?我是否需要使用错误的数据手动创建对象并使用无效的 ModelState 再次传递它们?第二种选择可能吗?

还是我只需要避免嵌套视图?作为替代方案,我想创建一个特殊的模型对象来处理包含 A 和 B 的所有值的表单,然后当这个表单验证时,我会手动填充 A 和 B 对象并保存它们。 .这是唯一的解决方案吗?

4

3 回答 3

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"])
            };
    }
}
于 2009-09-11T14:25:39.753 回答
1

创建您自己的包含 A 和 B 的自定义模型,然后在提交表单时从该模型创建一个视图,您将能够更新您的自定义模型并更新/添加您的单个模型。

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

该模型的视图将创建一个包含 A 和 B 的表单,并使您能够然后您发布的表单集合可用于为每个单独的模型设置值并更新/创建然后分开。

于 2009-09-11T14:28:05.597 回答
0

我对这段代码的问题是由两件事引起的,都在模型类中:

  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() {}
 } 
于 2009-09-14T08:32:29.630 回答