C# DropDownList所选值设置为";空";在关于事后行动的模型中

C# DropDownList所选值设置为";空";在关于事后行动的模型中,c#,asp.net,asp.net-mvc,drop-down-menu,asp.net-mvc-5,C#,Asp.net,Asp.net Mvc,Drop Down Menu,Asp.net Mvc 5,我希望利用ASP.NET MVC约定通过ActionResult MyAction(MyModel submitted)解析提交到模型的已发布表单MyModel包含我定义的类型的属性-UsState-。 submitted.UsState作为操作的结果返回null 有没有办法将提交的设置为正确的值 我在MyForm.cshtml ... @using (Html.BeginForm("MyAction", "MyController", FormMethod.Post, ...)) { @H

我希望利用ASP.NET MVC约定通过
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;
    }

}
公共类MyController:Controller
{
公共行动结果MyForm()
{
ViewBag.States=GetStatesList();
}
public ActionResult MyAction(MyModel info)//info.State在POST时设置为null
{
返回视图();
}
私有静态列表GetStatesList()
{
var states=新列表();
添加(新SelectListItem{Value=”“,Selected=true,Text=“State”});
foreach(UsStates.ToList()中的var s)
{
var state=new SelectListItem{Value=s.缩写,Text=s.Name,Disabled=!s.Available};
添加(州);
}
返回状态;
}
}
用模型

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;
    }
}
公共类MyModel
{
公共UsState状态{get;set;}//我需要合适的setter才能工作吗?
}
公共静态类UsStates//我应该以不同的方式获取UsStates吗?
{
私有静态列表状态=新列表{
新美国州(“阿拉巴马州”),
//...
}
公共静态列表ToList()
{返回状态;}
}
美国州立大学公共课
{
公共UsState(字符串ab、字符串名称、bool available=true)
{
名称=名称;
缩写=ab;
可用=可用;
}
}

查看发布的数据后,我意识到提交的表单数据-
States=AL
-类型是
string
,无法设置为
UsState
类型

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

public class MyModel
{
    public string States { get; set; }
}
我至少得到了提交表单的字符串值。不确定是否给出了此选项-如果是这种情况,我想我应该使用一个单独的
ViewModel
,以便将
States
作为字符串,并将其转换为
MyModel
,其中我将
字符串状态
转换为
UsState状态

将您的MyModel更改为

public class MyModel
{
    public string SelectedState {get;set; }
    public IEnumerable<SelectListItem> States { get; set; }  
}
我将其更改为DropDownListFor,因为它将自动为您生成id和name属性。它还将在顶部“状态”创建一个元素,这样您就不必将其预先挂起到列表中

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

根据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;
        }
    }
公共类MyController:Controller
{
//得到
公共行动结果MyAction()
{
返回视图(新的MyModel{States=GetStateList()});
}
[HttpPost]
公共行动结果MyAction(MyModel模型)
{
如果(!ModelState.IsValid)
{
model.States=GetStateList();
返回视图(模型);
}
//对发布的信息做任何你想做的事情。
return RedirectToAction(“”;//通常在发布到索引后重定向。
}
私有静态IEnumerable GetStatesList()
{
var states=新列表();
foreach(UsStates.ToList()中的var s)
{
var state=new SelectListItem{Value=s.缩写,Text=s.Name,Disabled=!s.Available};
添加(州);
}
返回状态;
}
}

我假设修订模型中的
公共美国各州
需要是
列表
IEnumerable
类型,对吗?之前,视图中的
状态
参考了
ViewBag.States
,而不是
MyModel.States
,非常感谢您对占位符属性的建议。我不知道该怎么做,注意应该是
model.States=GetStateList();在POST方法中返回视图(模型)
如果POST后
ModelState
无效,下拉项将消失。我的代码有问题吗?或者解决方案有一些问题?
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;
        }
    }