传递字典<string,list <string =“”>&gt;从MVC中的View到Controller

时间:2017-05-09 22:31:23

标签: c# jquery html asp.net-mvc dictionary

我想将一些数据从我的视图传递给我的控制器,我的视图如下所示:

  <div id="Section1" class="divFiles">
    <span>Section 1 </span>

<input type="text" name="test[0]">

<input type="text" name="test[1]">

<input type="text" name="test[2]">

<input type="text" name="test[3]">

</div>

  <div id="Section2" class="divFiles">
    <span>Section 2 </span>

<input type="text" name="test[4]">

<input type="text" name="test[5]">

<input type="text" name="test[6]">

<input type="text" name="test[7]">

</div>

但是这样我只是向控制器发送一个字符串列表,没有键,我需要键,因为我需要按键分组。

我希望按照Dictionary传递我的数据,按部分分组,例如:

Section 1: {"first string", "second string", "third string"}, Section 2: {"fourth string", "fifth string"}

就像那样,我认为最好的方法是将数据作为Dictionary Dictionary<string, List<string>>类型Section 1 Section 2发送,keys将是values,然后是他们的Dictionary<string, List<string>>字符串列表,我该怎么做?我也可以将JQuery用于此目的,但我不确定如何编写html来发送这样的数据。这样做我的控制器操作中的参数应该是max(Comparator)类型的任何建议也欢迎以不同方式执行此操作

2 个答案:

答案 0 :(得分:3)

对于除DictionaryKey都是值类型(例如Value)的简单Dictionary<string, int>之外的所有内容,DefaultModelBinder都需要控件名称采用以下格式(在您的情况下,假设POST方法签名为public ActionResult XX(Dictionary<string, List<string>> names)

<input name="names[0].Key" value="aaa" ... />
<input name="names[0].Value[0]" value="bbb" ... />
<input name="names[0].Value[1]" value="ccc" ... />
<input name="names[1].Key" value="xxx" ... />
<input name="names[1].Value[0]" value="yyy" ... />
<input name="names[1].Value[1]" value="zzz" ... />

没有HtmlHelper个扩展方法可以为包含name和/或Dictionary的{​​{1}}生成正确的Key属性一个复杂的对象或集合,这意味着您需要手动生成所有html并失去强类型绑定,客户端验证等所有好处。

创建表示结构的视图模型要容易得多,例如

Value

然后在GET方法中初始化一个public class ValueVM { public string Name { get; set; } } public class GroupVM { public string Key { get; set; } public List<ValueVM> Values { get; set; } } 的集合,填充数据并将其传递给视图,例如

GroupVM

然后在视图中

var model = new List<GroupVM>
{
    new GroupVM
    {
        Key = "Section 1",
        Values = new List<ValueVM>
        {
            new ValueVM { Name = "...." },
            new ValueVM { Name = "...." }
        }
    },
    new GroupVM
    {
        Key = "Section 2",
        ....
    }
};
return View(model);

POST方法签名将是

@model List<GroupVM>
....
@using (Html.BeginForm())
{
    @for(int i = 0; i < Model.Count; i++)
    {
        <div>
            <h2>@Model[i].Key</h2>
            @Html.HiddenFor(m => m[i].Key)
            @for (int j = 0; j < Model[i].Values.Count; j++)
            {
                @Html.TextBoxFor(m => m[i].Values[j].Name)
            }
        </div>
    }
    ....
}

答案 1 :(得分:2)

您应该创建一个对象,然后将该对象传递给Controller。这将会容易得多,否则您将拥有一个控制器,其中包含一组执行表单提交的大量参数。我会使用JavaScript,然后只是做一个Ajax请求。

public class Example
{
     public int Id { get; set; }
     public string Key { get; set; } // Bad name
     public string Value { get; set; } // Bad name
}

所以你的控制器会期望,示例

public IActionResult Submit(List<Example> examples)
{
     // Collection of our inputs as an object, manipulate.
}

然后对于JavaScript,您只需执行:

function getFormDataAndCreateObject() {
     var formElements = $('[data-rel="section"]');
     var elements = [];

     $.each(formElements, function (index) {
          elements.push(buildExample(index, formElements[index].attr('name'), formElements[index].value));
     });

     // Either return elements, or simply perform Ajax to send to controller.
}

function buildExample(id, section, name) {
     var examples = [{
          Id : id,
          Section: section,
          Name: name
     }];
}

可能有拼写错误,但这个概念很重要。