将选择框的值发布到控制器

时间:2017-06-14 18:28:33

标签: c# asp.net asp.net-mvc entity-framework

我有一个模型MyModel,它带有一个list属性和一个附带的字符串,用于存储数据库中的值。

简化一点以提高可读性。

public class MyModel
{
    public int ID { get; set; }
    public List<int> Numbers { get; set; }
    [Column, ScaffoldColumn(false)]
    public string NumbersStore { get { /*parses Numbers*/ } set { /*splits the value and sets Numbers accordingly*/ } }
}

我使用基于脚手架的基本CRUD。

在我的Create / Edit次观看中,我手动编写了select multiple。不使用助手可能是一个坏主意。我在IndexDetailsDelete视图中检索这些值没有问题,但我无法弄清楚在创建/编辑时如何将此数据实际绑定到我的模型。

只是从一些盲目的谷歌搜索,我已经尝试过:
- 在MyModelController.Create参数列表中添加了一个列表 - 尝试使用Request.Form["SelectNameAttribute"]

CSHTML:

@using (Html.BeginForm())
{
    <div class="form-group">
        @Html.LabelFor(model => model.Numbers, htmlAttributes: new { @class = "control-label col-md-2" })
        <select class="select2 col-md-10 form-control" multiple="multiple" id="Numbers" name="Numbers">
            <!-- Ultimately enumerated with a loop that goes through the database, probably butchering MVC conventions. Don't think that's relevant to the question. -->
            <option value="1">One</option>
            <option value="2">Two</option>
            <!-- Etc. -->
        </select>
    </div>

    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Create" class="btn btn-default" />
        </div>
    </div>
}

控制器:

public ActionResult Create([Bind(Include = "ID,NumbersStore")] MyModel myModel) // Changing NumbersStore to Numbers does nothing
{
    //myModel.NumbersStore = Request.Form["Numbers"].ToString();
    if (ModelState.IsValid)
    {
        db.MyModels.Add(myModel);
        db.SaveChanges();
        return RedirectToAction("Index");
    }

    return View(myModel);
}

3 个答案:

答案 0 :(得分:0)

只需分配一个与html标签同名的参数,就可以将值传递给控制器​​:

您可以选择名称(注意项目列表的括号)

<select class="select2 col-md-10 form-control" multiple="multiple" id="Numbers" name="Numbers[]">
    <option value="1">One</option>
    <option value="2">Two</option>
</select>

然后在控制器中使用参数int[] Numbers来访问发布的值

[HttpPost]
public ActionResult Create([Bind(Include = "ID,NumbersStore")] MyModel myModel, int[] Numbers)
{
    // do something with numbers

    db.MyModels.Add(myModel);
    db.SaveChanges();
    return RedirectToAction("Index");
}

答案 1 :(得分:0)

Lloyd's answer让我走近了。

我在这看起来像个傻瓜。答案就像命名select并将相同名称绑定到控制器操作一样简单 - 我可以发誓我已经完成了,但我认为我绑定了store而不是实际list

我不确定name属性是否必须与模型属性的名称相同,但我这样做是为了安全(并且为了清楚起见)。

所以正确的代码是:

MyModel.cs

public class MyModel
{
    public int ID { get; set; }
    public List<int> Numbers { get; set; } // This is the list we're changing
    [Column, ScaffoldColumn(false)]
    public string NumbersStore { get { /*parses Numbers*/ } set { /*splits the value and sets Numbers accordingly*/ } }
}

MyModelView.cshtml

@using (Html.BeginForm())
{
    <div class="form-group">
        @Html.LabelFor(model => model.Numbers, htmlAttributes: new { @class = "control-label col-md-2" })
        <select class="select2 col-md-10 form-control" multiple="multiple" id="Numbers" name="Numbers"> // Notice name attribute
            <option value="1">One</option>
            <option value="2">Two</option>
            <!-- Etc. -->
        </select>
    </div>

    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Create" class="btn btn-default" />
        </div>
    </div>
}

MyModelController.cs .Create

public ActionResult Create([Bind(Include = "ID,Numbers")] MyModel myModel) // Notice name attribute in Bind 
{
    if (ModelState.IsValid)
    {
        db.MyModels.Add(myModel);
        db.SaveChanges();
        return RedirectToAction("Index");
    }

    return View(myModel);
}

注意:
- 创建不需要数组作为参数(除非您需要进行进一步的更改)
- name HTML属性不需要以[]结尾 - 正如Sergey所描述的那样here,这是一个对ASP.NET没有影响的PHP约定 - 据我所知,name属性确实需要与最终被突变的属性相同

答案 2 :(得分:0)

只需从问题中的评论中重新解析解决方案。

+----------------------------+-------+--------+--------+--------+--------+--------+--------+--------+--------+ | ts | word1 | word2 | word3 | word4 | word5 | word6 | word7 | word8 | word9 | +----------------------------+-------+--------+--------+--------+--------+--------+--------+--------+--------+ | 2017-06-16 08:15:05.000000 | 2DF0 | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | | 2017-06-16 08:15:06.000000 | 2EF0 | 0000 | (null) | (null) | (null) | (null) | (null) | (null) | (null) | | 2017-06-16 08:15:07.000000 | 2DF0 | AAAA | BBBB | CCCC | (null) | (null) | (null) | (null) | (null) | | 2017-06-16 08:15:08.000000 | 2EF0 | 1111 | 2222 | (null) | (null) | (null) | (null) | (null) | (null) | | 2017-06-16 08:15:09.000000 | 2DF0 | | (null) | (null) | (null) | (null) | (null) | (null) | (null) | | 2017-06-16 08:15:10.000000 | 2EF0 | DDDD | EEEE | (null) | (null) | (null) | (null) | (null) | (null) | +----------------------------+-------+--------+--------+--------+--------+--------+--------+--------+--------+ 需要包含所发布表单中的属性。

在这种情况下,[Bind(Include = "")]需要NumbersStore才能匹配HTML中的属性。

Numbers