处理ASP.NET MVC中的复杂模型 [英] Dealing with complex models in ASP.NET MVC

查看:133
本文介绍了处理ASP.NET MVC中的复杂模型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的模型看起来像这样:

 
商业
- 分行
- 电话(*)
- 电话类型
- 电话号码
- 营业时间(*)
- 一周中的天数
- 工作时间(*)
- 从时间
- 时间
- 自定义字段(*)
- 名称
- 价值
- 地址
- 地址行
- 城市
- 状态
- Zip
- Yada yada

我创建了编辑模板上面的每个类类型。



我希望有一个共同的 Business 编辑器模板,其中包含一个提交表单对于现有的或新的实体,整个结构为单个动作并保存它。


  1. 编辑模板正确的做法?如何在整个下线提交表单?

  2. 如何使添加删除按钮添加/删除电话号码在表单中?

  3. 如何订购集合中的项目(即我希望在每个电话号码附近都有箭头,以便用户可以在客户端列表中向上或向下移动它,然后处理在服务器上保存,因为我已经有了解决方案)。

底线,我的问题是如何获得正确的值发布回到服务器,以及如何修改客户端上的内部集合。一旦正确的数据以这种方式在服务器上,我将知道如何处理它。我的问题是客户端和正确的数据提交方式。



更新



我看到这个答案,基本上回答了我的问题的第一部分,后两者仍然存在(添加 - 删除 - 订单按钮 - 管理客户端上的集合。

我的问题不是如何在客户端的DOM上添加/删除/重新排序行,但是如何修改客户端数据,然后在服务器中接收它,如下所示:

  [HttpPost] 
public ActionResult Save(商业)
{
/// blah blah
}



更新



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



查看:

  @ Ajax.ActionLink(添加,AddCustomField,新的AjaxOptions {UpdateTargetId =customFields, InsertionMode = InsertionMode.Inse rtAfter})

行动:

  public PartialViewResult AddOpeningTimes()
{
var ot = new OpeningTimes();
ot.WorkingPeriods.Add(new WorkingPeriod());
var e = EditorFor(ot);
//这里只是为了调试,值都是空字符串
e.ViewData.TemplateInfo.HtmlFieldPrefix = ViewData.TemplateInfo.HtmlFieldPrefix;
返回e;
}
//此方法位于基本控制器上:
protected PartialViewResult EditorFor< TModel>(TModel model)
{
return PartialView(EditorTemplates /+ typeof(TModel).Name,model);
}

事情是名称因为不需要枚举相应的字段( Branches [0] .CustomField [0] .Key ),而只是 Key

解决方案

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

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



避免自己生成表单部分的选项是创建隐藏的模板和收到。然后更改ID和名称。



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



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



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



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



UPDATE



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



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


I have a model that looks like this:

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
}

Update

Here is how I try to shove in the new data:

View:

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

Action:

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);
}

The thing is the name for the appropriate fields are not enumerated as needed (Branches[0].CustomField[0].Key), instead, it's just Key.

解决方案

As far as i know, there is no 'simple' way to do this.

Add button - you have to wire javascript that creates a part of form (eg. phone type select and phone text box) and set its id/name. Basically you find the last item in the form, which will have name of Phone[x].PhoneType, and set the values on new part of form to appropriate values with x + 1.

An option to avoid generating the part the form by yourself is to create a hidden 'template' and copy that. Then change id and name.

Remove button - if you simply deleted items from DOM, you would create gaps in the sequence and MVC doesn't know how to deal with that. One possible approach is to mark items in the form as deleted using a hidden field, then handling that on the server.

Reordering - I would add a property called Order to whatever needs this feature, then render it as hidden and change using javascript when reordering. You also have to set it appropriately when adding an item.

Useful properties in these situations are also: IsNew, IsUpdated - along with IsDeleted allow for relatively easy processing on the server.

Of course, if you have nested collections each needing add/remove/reorder functionality it will be kind of difficult to do and debug.

UPDATE

The action rendering the partial view can't know what the html prefix should be, because it doesn't have the context (that the parent is Branch object etc.).

If you want to use AJAX, i would recommend sending the html field prefix as a parameter (public PartialViewResult AddOpeningTimes(string htmlPrefix)). htmlPrefix could be Branches[0].CustomField[last_custom_field + 1].. It's probably the cleanest way to achieve what you want, even if it's in fact not very clean.

这篇关于处理ASP.NET MVC中的复杂模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆