asp net mvc post 给出空视图模型
asp net mvc post gives empty viewmodel
所以我有一个我循环访问的视图模型列表,视图模型对象中的一个属性是一个字典。在我的客户控制器中,在详细信息操作中,我从 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);
}
这是 post 操作:
[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>
您没有从您的 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++;
}
您不能使用 foreach
循环为集合项生成表单控件并获得正确的 2 向模型绑定。您需要对 typeof CustomerViewModel
使用 for
循环或 EditorTemplate
,如 .
中所述
此外,您应该避免绑定到 Dictionary
,因为您不能使用强类型 HtmlHelper
方法或 TagHelpers 来提供双向模型绑定。
为了 oo 绑定到您当前的模型,您的 name
属性需要采用 name="[#].EmployeeAndHours[Key]"
格式,其中 #
是 zero-based 集合索引器。
相反,将您的视图模型修改为
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" />
}
请注意,上面的代码假设您想要 post 返回 ProjectName
的值(因此隐藏输入),并且您想要显示每个 'Hours' 旁边的员工姓名输入。
所以我有一个我循环访问的视图模型列表,视图模型对象中的一个属性是一个字典。在我的客户控制器中,在详细信息操作中,我从 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);
}
这是 post 操作:
[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>
您没有从您的 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++;
}
您不能使用 foreach
循环为集合项生成表单控件并获得正确的 2 向模型绑定。您需要对 typeof CustomerViewModel
使用 for
循环或 EditorTemplate
,如
此外,您应该避免绑定到 Dictionary
,因为您不能使用强类型 HtmlHelper
方法或 TagHelpers 来提供双向模型绑定。
为了 oo 绑定到您当前的模型,您的 name
属性需要采用 name="[#].EmployeeAndHours[Key]"
格式,其中 #
是 zero-based 集合索引器。
相反,将您的视图模型修改为
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" />
}
请注意,上面的代码假设您想要 post 返回 ProjectName
的值(因此隐藏输入),并且您想要显示每个 'Hours' 旁边的员工姓名输入。