hi 考虑以下三个具有级联关系的类
public class Specification
{
public int SpecificationId { get; set; }
public string Caption { get; set; }
public ICollection<Feature> Features { get; set; }
}
public class Feature
{
public int? SpecificationId { get; set; }
public Specification Specification { get; set; }
public int FeatureId { get; set; }
public string Caption { get; set; }
public ICollection<FeatureValue> FeatureValues { get; set; }
}
public class FeatureValue
{
public int? FeatureId { get; set; }
public Feature Feature { get; set; }
public int FeatureValueId { get; set; }
public string Caption { get; set; }
}
在下一步和一个表单中,我读取并显示与上述类相关的信息(来自数据库) 像下面的代码片段:
@foreach (var specification in Model.FirstOrDefault().Specifications)
{
<fieldset>
<legend> @specification.Caption</legend>
@foreach (var feature in specification.Features)
{
<div class="form-group">
<label for="Specification_@(specification.SpecificationId)__Feature_@(feature.FeatureId)__FeatureValues">@feature.Caption :</label>
<select name="Specifications[@specification.SpecificationId].Feature[@feature.FeatureId].FeatureValues"
id="Specification_@(specification.SpecificationId)__Feature_@(feature.FeatureId)__FeatureValues"
@(feature.IsMultipleChoices ? "multiple" : null)
data-multiple="@(feature.IsMultipleChoices?"true":"false")"
class="sffv-select form-control"
>
<option></option>
@foreach (var featureValue in feature.FeatureValues)
{
<option value="@featureValue.FeatureValueId">
@featureValue.Caption
</option>
}
</select>
</div>
}
</fieldset>
}
最后,我将表单信息发送到服务器,类似于以下代码片段:
$.ajax({
async: true,
data: $('#MyForm').serialize(),
type: "Post",
url: "@FormUrl",
contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
success: function () {
alert("Submitted!");
}
});
像这样的东西会在最后发送:
我的问题是我应该如何在服务器端获得这个模型? 另外,括号内的ID是用来存储信息的。
答案 0 :(得分:2)
请参考以下示例并使用 Asp.net Core Tag helper 显示模型属性。
添加以下视图模型以在视图中显示数据:
public class SpecificationViewModel
{
public List<SpecificationVM> Specifications { get; set; }
}
public class SpecificationVM
{
public int SpecificationId { get; set; }
public string Caption { get; set; }
public List<FeatureVM> Features { get; set; }
}
public class FeatureVM
{
public int? SpecificationId { get; set; }
public Specification Specification { get; set; }
public int FeatureId { get; set; }
public string Caption { get; set; }
public Boolean IsMultipleChoices { get; set; } // Whether the <select> element is multiple select or single select.
public List<int> selectedFeatureValue { get; set; } // used to store the selected FeatureValueId.
public List<FeatureValueVM> FeatureValues { get; set; }
}
public class FeatureValueVM
{
public int? FeatureId { get; set; }
public Feature Feature { get; set; }
public int FeatureValueId { get; set; }
public string Caption { get; set; }
}
控制器代码:
private readonly ApplicationDbContext _context;
public SpecificationController(ApplicationDbContext context)
{
_context = context;
}
public IActionResult Index()
{
//query database and set value for the ViewModel.
List<SpecificationViewModel> items = new List<SpecificationViewModel>()
{
new SpecificationViewModel(){ Specifications= _context.Specifications.Include(c=>c.Features).ThenInclude(c=>c.FeatureValues)
.Select(c=>new SpecificationVM()
{
SpecificationId = c.SpecificationId,
Caption = c.Caption,
Features = c.Features.Select(d=> new FeatureVM()
{
Caption = d.Caption,
IsMultipleChoices = d.IsMultipleChoices,
FeatureId = d.FeatureId,
Specification =d.Specification,
SpecificationId = d.SpecificationId,
FeatureValues = d.FeatureValues.Select(v=> new FeatureValueVM()
{
Caption = v.Caption,
FeatureValueId = v.FeatureValueId,
FeatureId = v.FeatureId,
Feature =v.Feature
}).ToList()
}).ToList()
}).ToList() }
};
return View(items);
}
[HttpPost]
public IActionResult SaveSpecification(SpecificationViewModel model)
{
return Ok("success");
}
查看页面:
@model IEnumerable<WebApplication.Models.SpecificationViewModel>
@{
ViewData["Title"] = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<form id="MyForm">
@for (var i = 0; i < Model.FirstOrDefault().Specifications.Count; i++)
{
<fieldset>
<legend>@Model.FirstOrDefault().Specifications[i].Caption</legend>
<input type="hidden" asp-for="@Model.FirstOrDefault().Specifications[i].Caption" />
<input type="hidden" asp-for="@Model.FirstOrDefault().Specifications[i].SpecificationId" />
@for (var f = 0; f < Model.FirstOrDefault().Specifications[i].Features.Count; f++)
{
<div class="form-group">
<label>@Model.FirstOrDefault().Specifications[i].Features[f].Caption :</label>
<input type="hidden" asp-for="@Model.FirstOrDefault().Specifications[i].Features[f].Caption" />
<input type="hidden" asp-for="@Model.FirstOrDefault().Specifications[i].Features[f].FeatureId" />
<input type="hidden" asp-for="@Model.FirstOrDefault().Specifications[i].Features[f].SpecificationId" />
<input type="hidden" asp-for="@Model.FirstOrDefault().Specifications[i].Features[f].IsMultipleChoices" />
<select asp-for="@Model.FirstOrDefault().Specifications[i].Features[f].selectedFeatureValue"
asp-items='new SelectList(Model.FirstOrDefault().Specifications[i].Features[f].FeatureValues, "FeatureValueId", "Caption")'
data-multiple="@Model.FirstOrDefault().Specifications[i].Features[f].IsMultipleChoices"
class="sffv-select form-control">
<option></option>
</select>
</div>
}
</fieldset>
}
<input type="button" value="Submit" id="btnSubmit" />
</form>
@section Scripts{
<script>
$(function () {
//loop through the <select> element, add or remove multiple attribute from the <select> element
$(".sffv-select").each(function (index, item) {
if ($(item).attr("data-multiple") == "True") {
$(item).attr("multiple", "multiple");
}
else {
$(item).removeAttr("multiple");
}
});
$("#btnSubmit").click(function () {
$.ajax({
async: true,
data: $('#MyForm').serialize(),
type: "Post",
url: "/Specification/SaveSpecification", //change the url to yours
contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
success: function () {
alert("Submitted!");
}
});
});
});
</script>
}
提交表单后,在Post方法中,可以循环遍历ViewModel,获取所有选中的值(selectedFeatureValue),然后根据它们找到相关的FeatureValue并做一些事情。结果如下: