asp.net-mvc - 在 ASP.NET MVC 中处理复杂模型

标签 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

I created Editor Templates for each of the class types above.

I want to have a common Business editor template with a submit form that posts the entire structure to a single action and saves it, both for an existing or new entity.

  1. Is Editor Templates the right approach? How do I submit the form along its entire downline?
  2. How do I make Add and Remove buttons to add/remove phone numbers within the form?
  3. How do I order items in the collection (i.e. I want to have arrows near each phone number so the user can move it up or down in the client list, then handle the saving on server, for that I already have the solution).

Bottom line, my issue is how to get the right values posted back to the server, and how to modify the inner collections on the client. Once the proper data is on the server in this way or another I'll know how to deal with it. My problem is the client side and the correct way of data submission.

Update

I saw this answer, which basically answers the 1st part of my question, tho the latter two still remain (add-remove-order buttons - manage collections on client).
My problem is not how to add/remove/reorder rows at the client's DOM, but how to modify the client data and then receive it in the server in the action the looks like this:

[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

最佳答案

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

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

避免自己生成表单部分的一个方法是创建一个隐藏的"template"并复制它。然后修改id和name。

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

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

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

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

更新

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

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

关于asp.net-mvc - 在 ASP.NET MVC 中处理复杂模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16423073/

相关文章:

c# - 根据远程验证 MVC 检查当前项目 ID

jquery - 网页动态生成下拉?

c# - 模型在 XML POST 上始终为 null

asp.net-mvc - SqlException(0x80131904) : "connection was recovered and rowcount in the first query is not available"

asp.net-mvc - automapper + 延迟加载 + mvc contrib 网格 + s#arp 存储库

asp.net-mvc - SWF上传验证

asp.net-mvc - MVC/Razor 引擎如何从模型中找到 View ?

javascript - 从 Razor 代码中使用 javascript/jquery

php - 使用 PHP 格式化 HTTP POST 请求中的数据

java - 如何从 httpResponse 检索 session token ?