处理ASP.NET MVC中的复杂模型

时间:2013-05-07 15:35:58

标签: asp.net-mvc razor http-post form-submit

我的模型看起来像这样:

Business
 - Branch  
   - Phone(*)
     - Phone Type  
     - Number  
   - Opening hours (*)     
     - Days in week
     - Working period (*)
       - From time
       - To time
 - Custom field (*)
   - Name
   - Value
 - Address
   - Address line
   - City
   - State
   - Zip
 - Yada yada

我为上面的每个班级类型创建了编辑模板

我希望有一个共同的Business编辑器模板,其中包含一个提交表单,该表单将整个结构发布到单个操作并保存,无论是现有实体还是新实体。

  1. 编辑模板是正确的方法吗?如何在整个下线提交表单?
  2. 如何制作添加删除按钮以在表单中添加/删除电话号码?
  3. 如何订购集合中的项目(即我希望每个电话号码附近有箭头,以便用户可以在客户端列表中上下移动它,然后处理服务器上的保存,因为我已经有了解决方案)。
  4. 最重要的是,我的问题是如何将正确的值发布回服务器,以及如何修改客户端上的内部集合。一旦正确的数据以这种方式在服务器上,我将知道如何处理它。我的问题是客户端和正确的数据提交方式。

    更新

    我看到了this回答,这基本上回答了我问题的第一部分,后两者仍然存在(添加 - 删除 - 订单按钮 - 在客户端管理集合)。
    我的问题不是如何在客户端的DOM上添加/删除/重新排序行,如何修改客户端数据,然后在服务器中接收它像这样:

    [HttpPost]
    public ActionResult Save(Business business)
    {
      /// blah blah
    }
    

    更新

    以下是我尝试推送新数据的方法:

    查看:

    @Ajax.ActionLink("Add", "AddCustomField", new AjaxOptions { UpdateTargetId = "customFields", InsertionMode = InsertionMode.InsertAfter })
    

    动作:

    public PartialViewResult AddOpeningTimes()
    {
      var ot = new OpeningTimes();
      ot.WorkingPeriods.Add(new WorkingPeriod());
      var e = EditorFor(ot);
      //just here for debugging, the values are both empty strings
      e.ViewData.TemplateInfo.HtmlFieldPrefix = ViewData.TemplateInfo.HtmlFieldPrefix;
      return e;
    }
    //this method is on the base controller:
    protected PartialViewResult EditorFor<TModel>(TModel model)
    {
      return PartialView("EditorTemplates/" + typeof(TModel).Name, model);
    }
    

    根据需要,name不会枚举适当字段的Branches[0].CustomField[0].Key,而只是Key

1 个答案:

答案 0 :(得分:1)

据我所知,没有“简单”的方法可以做到这一点。

添加按钮 - 您必须连接创建表单一部分的javascript(例如,电话类型选择和电话文本框)并设置其ID /名称。基本上,您会找到表单中的最后一项,其名称为Phone [x]。PhoneType,并使用x + 1将表单新部分的值设置为适当的值。

避免自己生成表单部分的选项是创建隐藏的“模板”并复制它。然后更改ID和名称。

删除按钮 - 如果您只是从DOM中删除项目,则会在序列中创建间隙,而MVC不知道如何处理。一种可能的方法是使用隐藏字段将表单中的项目标记为已删除,然后在服务器上处理该项目。

重新排序 - 我会将一个名为Order的属性添加到需要此功能的任何内容中,然后将其呈现为隐藏,并在重新排序时使用javascript进行更改。您还必须在添加项目时进行适当设置。

在这些情况下的有用属性还有:IsNew,IsUpdated - 以及IsDeleted允许在服务器上进行相对简单的处理。

当然,如果您有嵌套的集合,每个集合都需要添加/删除/重新排序功能,那么执行和调试将很困难。

<强>更新

呈现局部视图的操作无法知道html前缀应该是什么,因为它没有上下文(父级是Branch对象等)。

如果你想使用AJAX,我建议发送html字段前缀作为参数(public PartialViewResult AddOpeningTimes(string htmlPrefix))。 htmlPrefix可以是Branches[0].CustomField[last_custom_field + 1].。它可能是达到你想要的最干净的方式,即使它实际上不是很干净。