C# 表单发布期间绑定复杂对象
我有一些功能需要放在许多页面上,所以我将其实现为一个局部视图 在这个局部视图中,我有一个下拉列表、一个添加按钮和一个“项目”列表,每个都包括一个删除按钮。其功能是显而易见的。单击任何删除按钮将删除关联的项目,从下拉列表中选择一个项目,然后单击添加添加该项目 复杂的是,这需要完全在javascript中进行——对项目列表的更改需要完全在客户端进行,在提交整个表单之前,服务器上不会发生任何事情。(也就是说,我们不希望在每次更改时都通过ajax更新服务器,我们希望收集更改并在表单提交时全部提交。) 第二个复杂性是,该表单需要非常方便,对父视图的要求尽可能少 因此,我已经为局部视图创建了一个viewmodel:C# 表单发布期间绑定复杂对象,c#,javascript,asp.net-mvc,C#,Javascript,Asp.net Mvc,我有一些功能需要放在许多页面上,所以我将其实现为一个局部视图 在这个局部视图中,我有一个下拉列表、一个添加按钮和一个“项目”列表,每个都包括一个删除按钮。其功能是显而易见的。单击任何删除按钮将删除关联的项目,从下拉列表中选择一个项目,然后单击添加添加该项目 复杂的是,这需要完全在javascript中进行——对项目列表的更改需要完全在客户端进行,在提交整个表单之前,服务器上不会发生任何事情。(也就是说,我们不希望在每次更改时都通过ajax更新服务器,我们希望收集更改并在表单提交时全部提交。) 第
public class ItemsModel
{
// The list to be displayed in the dropdown
public List<KeyValuePair<string, string>> itemsList { get; set; }
// The list of selected items
public List<string> items { get; set; }
public string itemsJson
{
get { return JsonConvert.SerializeObject(this.items); }
set { this.items = JsonConvert.DeserializeObject<List<string>>(value);
}
public ItemsModel()
{
this.itemsList = new List<KeyValuePair<string, string>>();
this.items = new List<string>();
}
}
当控制器构建模型时,在HttpGet期间,它用两个列表填充ItemsModel对象。页面的视图包括部分,传递itemsModel:
@{Html.RenderPartial("_itemsList", Model.itemsModel);
在partial中,我构建了下拉列表:
@Html.DropDownList("itemsList", new SelectList(Model.itemsList, "Key", "Value")
我用javascript填充了:
var items = $.parseJSON('@Html.Raw(Model.itemsJson)');
var itemsUl = $('#itemsUl');
itemsUl.empty();
var iTemplate = $('#itemTemplate').html();
for (var i=0; i<items.length; i++)
{
var template = iTemplate.nformat("{item}": items[i]);
itemsUl.append($(template));
}
var items=$.parseJSON('@Html.Raw(Model.itemsJson)');
var itemsUl=$(“#itemsUl”);
itemsUl.empty();
var iTemplate=$('#itemTemplate').html();
对于(var i=0;i,像往常一样,在这类问题中,我只是没有把事情想清楚
如果我想在表单提交期间在请求中包含一个值,我需要在表单元素中输入一个值
首先,我删除了parallel json属性-内联序列化/反序列化非常容易,这使事情变得更加明显
public class ItemsModel
{
// The list to be displayed in the <select>
public List<string> itemsList { get; set; }
// The list of selected items
public List<string> items { get; set; }
public ItemsModel()
{
this.itemsList = new List<string>();
this.items = new List<string>();
}
}
然后在javascript中,我们将数据提取到一个数组中:
var items = JSON.parse($('#itemsJson').val());
然后我从这些元素中构建,并将它们添加到我的。然后用户从中选择一个项目并单击“添加”按钮,或单击“删除”按钮,我从下拉列表中删除一个并将一个- 添加到
,或者从中删除一个- 并将一个添加到。在任何一种情况下,我都需要重新序列化数组并更新隐藏元素:
@Html.Hidden("itemsJson", JsonConvert.SerializeObject(Model.items))
$('#itemsJson').val(JSON.stringify(items));
然后,当我提交表单时,浏览器将在请求中包含一个名为“itemsJson”的JSON字符串。剩下的唯一问题是如何将其放入HttpPost操作中。有三种可能性:
- 我可以从请求[“itemsJson”]中提取值。我不喜欢这样
- 我可以构建一个自定义绑定来反序列化JSON并更新模型。这似乎是不必要的工作
- 或者,我可以在我的操作中添加另一个参数,并在那里反序列化它
我选择了选项3:
[Authorize]
[HttpPost]
public ActionResult Perishable(MyViewModel model, string itemsJson)
{
if (ModelState.IsValid)
{
model.itemsModel= new ItemsModel
{
items= JsonConvert.DeserializeObject<List<string>>(itemsJson)
};
...
}
}
[授权]
[HttpPost]
public ActionResult易腐(MyViewModel模型,string itemsJson)
{
if(ModelState.IsValid)
{
model.itemsModel=新的itemsModel
{
items=JsonConvert.DeserializeObject(itemsJson)
};
...
}
}
$('#itemsJson').val(JSON.stringify(items));
[Authorize]
[HttpPost]
public ActionResult Perishable(MyViewModel model, string itemsJson)
{
if (ModelState.IsValid)
{
model.itemsModel= new ItemsModel
{
items= JsonConvert.DeserializeObject<List<string>>(itemsJson)
};
...
}
}