Viewbag Fed DropdownFor - 一旦Action有Param

时间:2017-10-27 14:16:03

标签: javascript c# asp.net-mvc razor html.dropdownlistfor

好的,这里很奇怪......

我有一个包含4天前和今天日期的下拉列表的视图...

当使用null为DateTime推出Index(Action)时,DropDownList会出现,当前日期已经选中......太棒了!

HTML SOURCE URL \ Controller \ Index

    <select class="form-control" id="Date" name="Date" onchange="Change_Date(this)"
    <option value="23/10/2017">23/10/2017</option>
    <option value="24/10/2017">24/10/2017</option>
    <option value="25/10/2017">25/10/2017</option>
    <option value="26/10/2017">26/10/2017</option>
    <option selected="selected" value="27/10/2017">27/10/2017</option>
    </select>

使用DateTime启动Index(Action)时,即使它经历了完全相同的过程,我可以在ViewBag.DateList中实际看到Selected = True属性...下拉列表中没有选择的选项并恢复为第一个。

HTML SOURCE URL \ Controller \ Index?date = 2017-10-26

    <select class="form-control" id="Date" name="Date" onchange="Change_Date(this)"
    <option value="23/10/2017">23/10/2017</option>
    <option value="24/10/2017">24/10/2017</option>
    <option value="25/10/2017">25/10/2017</option>
    <option value="26/10/2017">26/10/2017</option>
    <option value="27/10/2017">27/10/2017</option>
    </select>

我试过绕过JS并将日期时间直接放在URL中但没有运气所以它不是......

我无法理解为什么在URL中使用?date = date 会从选项元素中删除所选属性...

只是在两个实例中都是Clear,ViewBag.DateList中存在Selected = True属性,但是当参数传递给动作时,它不会按预期呈现。

查看

@Html.DropDownList("Date", (IEnumerable<SelectListItem>)ViewBag.DateList, 
    new { @class = "form-control", @onchange="Change_Date(this)" })

方式

  public ActionResult Index(DateTime? date)
    {
        if (date.HasValue == false)
        {
            date = DateTime.Now.Date;
        }
        List<SelectListItem> Dates = new List<SelectListItem>();
        for (int i = -4; i < 1; i++)
        {
            string date_display = DateTime.Now.Date.AddDays(i).ToShortDateString();
            Dates.Add(new SelectListItem { Text = date_display, Value =date_display});
        }

        foreach (SelectListItem item in Dates)
        {
            if (item.Value == date.ToShortDateString())
                item.Selected = true;
        }
        ViewBag.DateList = Dates;
     }

JS

function Change_Date(val)
{
    var value = $('#Date').val();
    value = value.split("/").reverse().join("-");
    var url = "/Controller/Index?date=" + value;
    window.location.href = url;
}

1 个答案:

答案 0 :(得分:1)

您网址中的

?date=date会为date添加ModelState的值,因为您的方法中有一个名为date的参数。生成表单控件的HtmlHelper方法使用ModelState中的值进行绑定(如果存在)(然后来自ViewData,最后来自实际的模型属性)。请参阅this answer的第2部分,了解行为的解释。

DropDownList()(和DropDownListFor())方法在内部构建一个新的IEnumerable<SelectListItem>,并根据绑定的属性设置Selected属性的值(在您的情况下) Date)如果不是null

使用../Controller/Index?date=2017-10-26重定向时,date参数(以及ModelState值)的值变为26/10/2017 12:00:00 AM。当DropDownList()方法通过循环IEnumerable<SelectListItem>构建其ViewBag.DateList时,它会将.ToString()值的SelectListItem属性与date的值进行比较在ModelState中找不到任何匹配项(字符串"26/10/2017 12:00:00 AM"不等于"26/10/2017"),因此没有选项设置为选中。

选择正确选项的一些选项包括

  1. 在您之前在控制器方法中添加ModelState.Clear() 返回视图。
  2. 更改方法中参数的名称或名称 例如,在下拉列表中,它们不匹配 @Html.DropDownList("SelectedDate", ...)