我正在尝试在视图中创建对象列表,但在post方法中,进入的参数为null。创建页面加载了我想要的所有信息,但是当我点击“创建”时,我得到了标题中列出的错误。我能做错什么?
员工每天都有与他们相关的可用性。这就是我想要实现的目标
模型
public class Availability
{
[Required]
public long Id { get; set; }
[Required]
[DataType(DataType.Text)]
[Display(Name = "Weekday")]
public string weekday { get; set; }
[DataType(DataType.Time)]
[Display(Name = "Start Time")]
public DateTime StartTime { get; set; }
[DataType(DataType.Time)]
[Display(Name = "End Time")]
public DateTime EndTime { get; set; }
public virtual Employee employee { get; set; }
}
}
自定义类
public class SetAvailability
{
public long EmpID { get; set; }
public String firstName {get; set;}
public String lastName { get; set; }
public Availability availability {get; set;}
}
控制器方法
// GET: /Availability/Create
public ActionResult Create(long id)
{
string[] weekdays ={"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
//find the employee
Employee emp = db.Employees.Find(id);
//create a list of setAvailability objects for each day
List<SetAvailability> editor = new List<SetAvailability>();
//instantiate each SetAvailability object and populate accordingly for 7 days
for (int i = 0; i < 7; i++)
{
//create a blank SetAvilability
var _editor = new SetAvailability();
//create a blank availability
_editor.availability = new Availability();
//set the weekday
_editor.availability.weekday = weekdays[i].ToString();
//set the employee id, first name and last name
_editor.EmpID = emp.Id;
_editor.firstName = emp.FirstName;
_editor.lastName = emp.LastName;
//add the _editor to the editorlist
editor.Add(_editor);
}
return View(editor);
}
//
// POST: /Availability/Create
[HttpPost]
public ActionResult Create(List<SetAvailability> dto)
{
//dto object is coming in null! (checked by debugging)
List<SetAvailability> temp = new List<SetAvailability>();
temp = dto;
if (ModelState.IsValid)
{
// set the values for each availability object
// breaks here!
foreach (var item in dto)
{
// get the employee
item.availability.employee = db.Employees.Find(item.EmpID);
// weekday should already be set
// start and end times should come in from the create view
db.Availability.Add(item.availability);
}
db.SaveChanges();
return RedirectToAction("Index","employee");
}
return View(temp);
}
查看
@model List<VolumeV2.Models.DTOs.SetAvailability>
@{
ViewBag.Title = "Create";
}
<h2>Create</h2>
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>Availability</legend>
<table>
<tr>
@foreach (var item in Model)
{
@Html.HiddenFor(model => item.EmpID)
@Html.HiddenFor(model => item.firstName)
@Html.HiddenFor(model => item.lastName)
<td>
@Html.LabelFor(model => item.availability.weekday)
</td>
<td>
@Html.LabelFor(model => item.availability.StartTime)
</td>
<td>
@Html.LabelFor(model => item.availability.EndTime)
</td>
break;
}
</tr>
@foreach (var item in Model){
@Html.HiddenFor(model => item.EmpID)
@Html.HiddenFor(model => item.firstName)
@Html.HiddenFor(model => item.lastName)
<tr>
<td>
@Html.EditorFor(modelitem => item.availability.weekday)
@Html.ValidationMessageFor(modelitem => item.availability.weekday)
</td>
<td>
@Html.EditorFor(modelitem => item.availability.StartTime)
@Html.ValidationMessageFor(modelitem => item.availability.StartTime)
</td>
<td>
@Html.EditorFor(modelitem => item.availability.EndTime)
@Html.ValidationMessageFor(modelitem => item.availability.EndTime)
</td>
</tr>
}
</table>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
答案 0 :(得分:0)
试试这个
要获取 POST 方法的对象集合,需要修改Html.BeginForm, 在您的应用程序中添加以下Helper类,它将返回对象列表。 (例如Helper类DemoApplication / Models /的位置)
public static class HtmlPrefixScopeExtensions
{
private const string idsToReuseKey = "__htmlPrefixScopeExtensions_IdsToReuse_";
public static IDisposable BeginCollectionItem(this HtmlHelper html, string collectionName)
{
var idsToReuse = GetIdsToReuse(html.ViewContext.HttpContext, collectionName);
string itemIndex = idsToReuse.Count > 0 ? idsToReuse.Dequeue() : Guid.NewGuid().ToString();
// autocomplete="off" is needed to work around a very annoying Chrome behaviour whereby it reuses old values after the user clicks "Back", which causes the xyz.index and xyz[...] values to get out of sync.
html.ViewContext.Writer.WriteLine(string.Format("<input type=\"hidden\" name=\"{0}.index\" autocomplete=\"off\" value=\"{1}\" />", collectionName, html.Encode(itemIndex)));
return BeginHtmlFieldPrefixScope(html, string.Format("{0}[{1}]", collectionName, itemIndex));
}
public static IDisposable BeginHtmlFieldPrefixScope(this HtmlHelper html, string htmlFieldPrefix)
{
return new HtmlFieldPrefixScope(html.ViewData.TemplateInfo, htmlFieldPrefix);
}
private static Queue<string> GetIdsToReuse(HttpContextBase httpContext, string collectionName)
{
// We need to use the same sequence of IDs following a server-side validation failure,
// otherwise the framework won't render the validation error messages next to each item.
string key = idsToReuseKey + collectionName;
var queue = (Queue<string>)httpContext.Items[key];
if (queue == null) {
httpContext.Items[key] = queue = new Queue<string>();
var previouslyUsedIds = httpContext.Request[collectionName + ".index"];
if (!string.IsNullOrEmpty(previouslyUsedIds))
foreach (string previouslyUsedId in previouslyUsedIds.Split(','))
queue.Enqueue(previouslyUsedId);
}
return queue;
}
private class HtmlFieldPrefixScope : IDisposable
{
private readonly TemplateInfo templateInfo;
private readonly string previousHtmlFieldPrefix;
public HtmlFieldPrefixScope(TemplateInfo templateInfo, string htmlFieldPrefix)
{
this.templateInfo = templateInfo;
previousHtmlFieldPrefix = templateInfo.HtmlFieldPrefix;
templateInfo.HtmlFieldPrefix = htmlFieldPrefix;
}
public void Dispose()
{
templateInfo.HtmlFieldPrefix = previousHtmlFieldPrefix;
}
}
}
之后修改了你的视图
@model List<VolumeV2.Models.DTOs.SetAvailability>
@{
ViewBag.Title = "Create";
}
<h2>Create</h2>
@Html.ValidationSummary(true)
@using(Html.BeginForm())
{
<fieldset>
<legend>Availability</legend>
<table>
@foreach (var item in Model)
{
@Html.Partial("_partialView",item)
}
</table>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
创建局部视图 _partailView.cshtml
@model VolumeV2.Models.DTOs.SetAvailability
@using DemoApplication.Models // Added Helper class reference
<tr>
@using (Html.BeginCollectionItem("dto")) {
@Html.HiddenFor(model => model.EmpID)
@Html.HiddenFor(model => model.firstName)
@Html.HiddenFor(model => model.lastName)
<td>
@Html.LabelFor(model => model.availability.weekday)
</td>
<td>
@Html.LabelFor(model => model.availability.StartTime)
</td>
<td>
@Html.LabelFor(model => model.availability.EndTime)
</td>
break;
}
</tr>
注意:您必须在POST方法中保留Html.BeginCollectionItem(“dto”)和参数名称的相同名称,否则您将无法在POST方法中获得值,并在视图中添加帮助程序类引用 。
答案 1 :(得分:0)
要快速解决此问题,您可以使用&#34; for&#34;对列表项使用索引。循环,因为这将呈现控件的名称以适应MVC模型绑定的命名约定。例如,[0] .availability.weekday,[1] .availability.weekday等,表示具有相应索引的项目数组,以便能够在模型绑定时构造项目列表。
@model List<MvcApplication5.Models.SetAvailability>
@using (Html.BeginForm("Create","Employee")) {
@Html.ValidationSummary(true)
<fieldset>
<legend>Availability</legend>
<table>
<tr>
@for (int i = 0; i < Model.Count; i++)
{
@Html.HiddenFor(model => Model[i].EmpID)
@Html.HiddenFor(model => Model[i].firstName)
@Html.HiddenFor(model => Model[i].lastName)
<td>
@Html.LabelFor(model => Model[i].availability.weekday)
</td>
<td>
@Html.LabelFor(model => Model[i].availability.StartTime)
</td>
<td>
@Html.LabelFor(model => Model[i].availability.EndTime)
</td>
break;
}
</tr>
@for (int i = 0; i < Model.Count; i++)
{
@Html.HiddenFor(model => Model[i].EmpID)
@Html.HiddenFor(model => Model[i].firstName)
@Html.HiddenFor(model => Model[i].lastName)
<tr>
<td>
@Html.EditorFor(modelitem => Model[i].availability.weekday)
@Html.ValidationMessageFor(modelitem => Model[i].availability.weekday)
</td>
<td>
@Html.EditorFor(modelitem => Model[i].availability.StartTime)
@Html.ValidationMessageFor(modelitem => Model[i].availability.StartTime)
</td>
<td>
@Html.EditorFor(modelitem => Model[i].availability.EndTime)
@Html.ValidationMessageFor(modelitem => Model[i].availability.EndTime)
</td>
</tr>
}
</table>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
现在,你应该在POST后看到列表中的七个项目。希望这能帮助你。