DropDownList没有设置选定的值

时间:2017-07-10 21:43:20

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

我正在运行asp.net 4 mvc并且我创建了一个日期的DropDownList,默认为列表中的第一个条目。当我选择一个条目时,我调用一个控制器函数并进行一些处理。但是,当我的页面执行PostBack时,它不再显示我选择的列表项,而是再次显示原始默认列表项。

如何让我的页面显示我从列表中选择的最后一项?我花了整整两天的时间搜索这个网站和互联网寻求解决方案,但我尝试的任何东西似乎都没有用。非常感谢任何帮助。

我的Html视图

@Html.DropDownList("selectList", Model.ReverseMonthsLists(),
    new { @onchange = "CallChangefunc(this.value)" })
<script>
    function CallChangefunc(val) {
        window.location.href = "/dashboard/Report_Performance?id=" + val;
    }
</script>

我的ViewModel

public SelectList MonthList { get; set; }

public IEnumerable<SelectListItem> ReverseMonthsLists()
{
    var selectListItems = GetDates()
        .Select(_ => _.ToString("MMM yyyy"))
        .Select((dateString, index) => new SelectListItem { Selected = index == 0, Text = dateString, Value = dateString })
        .ToList();
    return selectListItems;
}


public static IEnumerable<DateTime> GetDates()
{
    DateTime startDate = new DateTime(2017, 6, 1).Date;
    var currentDate = DateTime.Now.Date;
    int numberOfMonthsToShow = (currentDate.Year - startDate.Year) * 12 + currentDate.Month - startDate.Month;
    var dates = new List<DateTime>(numberOfMonthsToShow);
    currentDate = currentDate.AddMonths(-1);

    for (int i = 0; i < numberOfMonthsToShow; i++)
    {
        dates.Add(currentDate);
        currentDate = currentDate.AddMonths(-1);
    }

    return dates;
}

我的控制器

[RequireLogin]
public ActionResult Report_Performance(string id)
{
    DateTime newDate = DateTime.Now.Date.AddMonths(-1);
    if (id != null)
        newDate = DateTime.Parse(id);
    var aVar = Models.Reporting.ListingStatsReportingViewModel.GetStats(userCurrentService.CompanyId.Value, Models.Reporting.DateTimePeriod.Monthly, newDate);
    return this.View(aVar);
}

2 个答案:

答案 0 :(得分:2)

您可以按如下方式更改代码:

让我们说GetStats操作中Report_Performance方法返回的模型类是MyStats,其中包含一个名为SelectedDateString的字符串属性(您需要将此属性添加到视图模型类中。)

更新了视图标记:

@model MyStats
@Html.DropDownList("SelectedDateString", Model.ReverseMonthsLists(),
    new { @onchange = "CallChangefunc(this.value)" })
<script>
    function CallChangefunc(val) {
        window.location.href = "/dashboard/Report_Performance?id=" + val;
    }
</script>

更新了控制器:

[RequireLogin]
public ActionResult Report_Performance(string id)
{
    DateTime newDate = DateTime.Now.Date.AddMonths(-1);
    if (id != null)
        newDate = DateTime.Parse(id);
    var aVar = Models.Reporting.ListingStatsReportingViewModel.GetStats(userCurrentService.CompanyId.Value, Models.Reporting.DateTimePeriod.Monthly, newDate);

    //This will make sure that the model returns the correct value of the property as a string.
    aVar.SelectedDateString = id;

    return this.View(aVar);
}

Html.DropDownList()的工作原理是从模型中的string property获取与DropDownList本身名称相同的数据。

在您的情况下,您需要使用javascript或jquery设置DropDownList值,因为它未连接到模型属性。

我举个例子: 可以使用

创建MVC中的下拉列表
@Html.DropDownListFor(m => m.PreferredContactMethod, Model.PreferredContactMethods, "")

@Html.DropDownList("PreferredContactMethod", Model.PreferredContactMethods, "")

在这两种情况下,PreferredContactMethod是我的模型中连接到视图的字符串属性 - 通过在视图顶部指定@model PreferredContactModel来完成。

在您的情况下,您的列表名称是selectList,如果指定的模型已连接到视图,并且模型中有属性获取所选日期,则需要更改下拉列表的名称列出来。

我希望有意义,如果有任何问题,请回复。我想帮助解决这个问题。

答案 1 :(得分:1)

问题在于:

window.location.href = "/dashboard/Report_Performance?id=" + val;

这个必要条件告诉浏览器导航到新页面,这是一个HttpGet操作。因此,您当前的设置与新页面的设置之间没有相关性。

就好像你刚刚走到地址栏并点击回车一样。它会发布一个包含所有新默认值的新页面。

有很多方法可以解决这个问题。最简单的方法是使用一些查看URL的javascript并提取id查询参数,然后在下拉框中选择与id对应的项目。

另一种选择是根据控制器中的ID设置下拉列表的选定值。

在控制器中:

ViewBag.SelectedItem = id;

在视图中:

@Html.DropDownList("SelectedItem", Model.ReverseMonthsLists(), ...)