【问题标题】:asp net mvc post gives empty viewmodelasp net mvc post 给出空视图模型
【发布时间】:2018-03-16 22:17:22
【问题描述】:

所以我有一个我遍历的视图模型列表,并且视图模型对象中的属性之一是字典。在我的客户控制器中,在详细信息操作中,我从 asp-route 获取与 id 对应的所有视图模型,并且在视图中,我有一个表单,其中显示了所有字典值,以便您可以根据需要修改它们。之后,您可以提交表格。这是我认为视图模型列表为“0”的地方。为什么是这样?

这是我的模型:

   public class CustomerViewModel
{
    public CustomerViewModel()
    {
        EmployeeAndHours = new Dictionary<string, int>();
    }

    public string projectName { get; set; }
    public Dictionary<string, int> EmployeeAndHours { get; set; }
}

这是获取操作:

        // GET: Customers/Details/5
    public IActionResult Details(int? id) 
    {
        if (id == null)
        {
            return NotFound(); 
        }

        var customers = _customerHelper.GetCustomerDetails(id);

        if (customers == null)
        {
            return NotFound();
        }

        return View(customers);
    }

这是发布操作:

        [HttpPost]
    public IActionResult EditCustomerDetailViewModel(List<customerViewModel> customers)
    {
        //TODO
        return View("Details");
    }

这是我的看法:

@model List<myNamespace.Models.ViewModels.CustomerViewModel>

<div class="container-fluid">
    <form asp-controller="Customers" asp-action="EditCustomerDetailViewModel" method="post">
        @foreach (var customer in Model)
        {
            <div class="media">
                <div class="media-body">
                    <div class="text-wrapper">
                        <h5 class="mt-0">@customer.projectName</h5>
                    </div>
                    <div class="slider-wrapper">
                        @foreach (var employee in customer.EmployeeAndHours) // This is the dictionary
                        {
                            <input name="@("EmployeeAndHours[" + employee.Key + "]")" type="range" min="0" max="1000" step="1" value="@employee.Value" data-orientation="horizontal">
                            <hr />
                        }
                    </div>
                </div>
            </div>
        }
        <div class="form-group" style="text-align:center">
            <input id="customer-detail-form-button" type="submit" value="Save changes" class="btn btn-success" />
        </div>
    </form>
</div>

【问题讨论】:

  • 在推送到 razor 视图之前,您的视图模型数据是否显示在控制器操作级别?
  • 鉴于您 具有 显示的内容,我会假设您输入的名称与您的 CustomerViewModel 类的属性不匹配。模型绑定器只能与从您的页面发布的任何内容一起使用,而您没有给予足够的资源来成功地做到这一点。
  • @Hazarath 是的,在 get 操作中一切正常,我在控制台中没有错误。
  • @Tieson,也许是这样,我早上去看看!
  • 您需要展示您的模型(如上所述,您生成的 name 属性与您的模型无关(当然也与您不应该使用的 Dictionary 无关)无论如何)

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


【解决方案1】:

您不能使用 foreach 循环为集合项生成表单控件并获得正确的 2-way 模型绑定。如Post an HTML Table to ADO.NET DataTable 中所述,您需要使用for 循环或EditorTemplate for typeof CustomerViewModel

此外,您应该避免绑定到 Dictionary,因为您不能使用强类型化的 HtmlHelper 方法或 TagHelpers 来提供 2 路模型绑定。

为了绑定到您当前的模型,您的name 属性需要采用name="[#].EmployeeAndHours[Key]" 格式,其中# 是从零开始的集合索引器。

改为将您的视图模型修改为

public class CustomerViewModel
{
    public string ProjectName { get; set; }
    public List<EmployeeHoursViewMode> EmployeeHours { get; set; }
}
public class EmployeeHoursViewModel
{
    public string Employee { get; set; }
    public int Hours{ get; set; }
}

然后视图就变成了

@model List<CustomerViewModel>
<form asp-controller="Customers" .... >
    @for(int i = 0; i < Model.Count i++)
    {
        ....
        <h5>@Model[i].ProjectName</h5>
        @Html.HiddenFor(m => m[i].ProjectName)
        // or <input type="hidden" asp-for-"Model[i].ProjectName />
        <div>
            @for(int j = 0; j < Model[i].EmployeeHours.Count; j++)
            {
                @Html.HiddenFor(m => m[i].EmployeeHours[j].Employee)
                @Html.LabelFor(m => m[i].EmployeeHours[j].Hours, Model[i].EmployeeHours[j].Employee)
                // or <label asp-for="Model[i].EmployeeHours[j].Hours">@Model[i].EmployeeHours[j].Employee</label>
                @Html.TextBoxFor(m => m[i].EmployeeHours[j].Hours, new { type = "range", ... })
                // or <input asp-for-"Model[i].EmployeeHours[j].ProjectName type="range" ... />
            }
        </div>
    }
    <input type="submit" value="Save changes" class="btn btn-success" />
}

请注意,上面的代码假设您想要回传 ProjectName 的值(因此隐藏了输入),并且您想要在每个“小时”输入旁边显示员工姓名。

【讨论】:

  • 这很好,我现在明白为什么了,感谢您的长篇解释!
【解决方案2】:

您没有从 POST 操作中引用模型名称,试试这个:

@{int index = 0;}
@foreach (var customer in Model)
{
    ...
    @foreach (var employee in customer.EmployeeAndHours)
    {
        <input name="customer[@(index)].EmployeeAndHours[@(employee.Key)]" type="range" min="0" max="1000" step="1" value="@employee.Value" data-orientation="horizontal">
        <hr />
    }
    ...
    index++;
}

【讨论】:

    猜你喜欢
    • 2021-04-23
    • 2012-03-25
    • 2011-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-27
    • 1970-01-01
    相关资源
    最近更新 更多