代码之家  ›  专栏  ›  技术社区  ›  Palantir

ASP.NET MVC:嵌入对象编辑

  •  0
  • Palantir  · 技术社区  · 15 年前

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

    我现在正在处理创建操作,所以我做b=new b();b.a=new a();

    现在我将为B呈现表单,然后调用A的局部视图,并将其传递给B.A。

    但我得到的是一个FormCollection,或者我的新a对象,其中b字段设置为空。 在第一种情况下,一切都很好,但是如果表单没有失效,我该怎么办?是否需要使用错误的数据手动创建对象,并使用无效的ModelState再次传递这些对象? 第二种选择是否可能?

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

    3 回复  |  直到 15 年前
        1
  •  1
  •   Keith    15 年前

    你应该能够像你描述的那样使用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"])
                };
        }
    }
    
        2
  •  1
  •   davethecoder    15 年前

    创建包含A和B的自定义模型,然后从该模型创建视图 提交表单时,您只需更新自定义模型和更新/添加单个模型即可。

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

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

        3
  •  0
  •   Palantir    15 年前

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

    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() {}
     }