Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 表单发布期间绑定复杂对象_C#_Javascript_Asp.net Mvc - Fatal编程技术网

C# 表单发布期间绑定复杂对象

C# 表单发布期间绑定复杂对象,c#,javascript,asp.net-mvc,C#,Javascript,Asp.net Mvc,我有一些功能需要放在许多页面上,所以我将其实现为一个局部视图 在这个局部视图中,我有一个下拉列表、一个添加按钮和一个“项目”列表,每个都包括一个删除按钮。其功能是显而易见的。单击任何删除按钮将删除关联的项目,从下拉列表中选择一个项目,然后单击添加添加该项目 复杂的是,这需要完全在javascript中进行——对项目列表的更改需要完全在客户端进行,在提交整个表单之前,服务器上不会发生任何事情。(也就是说,我们不希望在每次更改时都通过ajax更新服务器,我们希望收集更改并在表单提交时全部提交。) 第

我有一些功能需要放在许多页面上,所以我将其实现为一个局部视图

在这个局部视图中,我有一个下拉列表、一个添加按钮和一个“项目”列表,每个都包括一个删除按钮。其功能是显而易见的。单击任何删除按钮将删除关联的项目,从下拉列表中选择一个项目,然后单击添加添加该项目

复杂的是,这需要完全在javascript中进行——对项目列表的更改需要完全在客户端进行,在提交整个表单之前,服务器上不会发生任何事情。(也就是说,我们不希望在每次更改时都通过ajax更新服务器,我们希望收集更改并在表单提交时全部提交。)

第二个复杂性是,该表单需要非常方便,对父视图的要求尽可能少

因此,我已经为局部视图创建了一个viewmodel:

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