DropDownList选择值在POST on Action动作

时间:2018-01-09 14:27:08

标签: c# asp.net asp.net-mvc drop-down-menu asp.net-mvc-5

我希望利用ASP.NET MVC约定将POSTed表单提交解析为ActionResult MyAction(MyModel submitted)的模型。 MyModel包含我定义的类型的属性 - UsState - 。 submitted.UsState作为操作的结果返回null

有没有办法让提交设置为正确值?

我在MyForm.cshtml

中有一个表格的以下视图
...
@using (Html.BeginForm("MyAction", "MyController", FormMethod.Post, ...))
{
  @Html.DropDownList("States", 
    null, 
    new { @id = "state", @class = "form-control", @placeholder = "State"})
}
...

使用控制器

public class MyController : Controller
{
    public ActionResult MyForm()
    {
        ViewBag.States = GetStatesList();
    }

    public ActionResult MyAction(MyModel info) //info.State is set to null on POST
    {
        return View();
    }
    private static List<SelectListItem> GetStatesList()
    {
        var states = new List<SelectListItem>();
        states.Add(new SelectListItem { Value = "", Selected = true, Text = "State" });
        foreach (var s in UsStates.ToList())
        {
            var state = new SelectListItem { Value = s.Abbreviation, Text = s.Name, Disabled = !s.Available };
            states.Add(state);
        }
        return states;
    }

}

使用模型

public class MyModel
{
    public UsState States { get; set; } //Do I need proper setter for it to work? 
}
public static class UsStates  //Should I get the UsStates in a different way? 
{
    private static List<UsState> states = new List<UsState> {
        new UsState("AL", "Alabama"),
        //...
    }
    public static List<UsState> ToList()
    { return states; }
}

public class UsState
{
    public UsState(string ab, string name, bool available = true)
    {
        Name = name;
        Abbreviation = ab;
        Available = available;
    }
}

2 个答案:

答案 0 :(得分:3)

将MyModel更改为

public class MyModel
{
    public string SelectedState {get;set; }
    public IEnumerable<SelectListItem> States { get; set; }  
}

将您的观点修改为

@using (Html.BeginForm("MyAction", "MyController", FormMethod.Post, ...))
{
  @Html.DropDownListFor(m => m.SelectedState, Model.States, "State", 
    new { @class = "form-control" })
}

我将其更改为DropDownListFor,因为它会自动为您生成id和name属性。它还将在顶部创建一个元素&#34; State&#34;因此,您不必将其预先挂在列表中。

我删除了占位符,因为select元素不支持占位符。同时不得用作标签的替代品。

Per W3C

  

占位符属性指定描述的短提示   输入字段的期望值(例如,样本值或短的   预期格式的描述。)

将控制器操作拆分为GET / POST对

public class MyController : Controller
{
    //Get
        public ActionResult MyAction()
        {
            return View(new MyModel { States = GetStateList() });
        }

        [HttpPost]
        public ActionResult MyAction(MyModel model)
        {
            if (!ModelState.IsValid)
            {
                model.States = GetStateList();
                return View(model);
            }

            //do whatever you are going to do with the posted information.

            return RedirectToAction("<some view>");  //redirect after a post usually to Index.
        }

        private static IEnumerable<SelectListItem> GetStatesList()
        {
            var states = new List<SelectListItem>();
            foreach (var s in UsStates.ToList())
            {
                var state = new SelectListItem { Value = s.Abbreviation, Text = s.Name, Disabled = !s.Available };
                states.Add(state);
            }
            return states;
        }
    }

答案 1 :(得分:0)

在查看POSTed数据后,我意识到提交的表单数据 - States=AL - 类型为string,无法将其设置为UsState类型。

我将模型更改为以下内容:

public class MyModel
{
    public string States { get; set; }
}

我至少获得了提交表单的字符串值。不确定是否给出了 - 如果是这种情况,我想我应该使用单独的ViewModel以便将States作为字符串,并将其转换为我MyModel { {1}}进入string States

相关问题