我有一个带有提交按钮的表单,该表单应该将项目传递给actionlistener。我认为这可能与@Html.HiddenFor does not work on Lists in ASP.NET MVC中的问题相似,但没有一个答案似乎有效。你甚至可以从那里的一个答案中看到我的for循环。
[ 编辑:我已经摆脱了大量的隐藏循环并替换为@ Html.EditorFor,以便您可以看到,即使没有隐藏,标志列表也不会到达actionlistener。这是一个问题,因为当有人编辑标志时,无法更新数据库,因为我无法更新标志的ID。 ]
控制器中的ModelState永远不会有效,无论我是否保留" [Bind(包括="有没有。因为教程为 ASP.NET MVC Tutorial: Web application development with Azure Cosmos DB
ItemController.cs:
[HttpPost]
[ActionName("ProductEdit")]
[ValidateAntiForgeryToken]
public async Task<ActionResult> EditProductAsync( [Bind(Include = "Id, Name, Flags")] Item model)
{
Item product = await DocDBRepo<Item>.GetItem(model.Id);
model.Organisations = product.Organisations;
if (ModelState.IsValid) //Checks item validation via "required" set on properties
{
await DocDBRepo<Item>.UpdateItemAsync(model.Id, model);
return RedirectToAction("Index");
}
return View(model);
}
[HttpGet]
[ActionName("ProductEdit")]
public async Task<ActionResult> EditProductAsync(string id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Item item = await DocDBRepo<Item>.GetItem(id);
if (item == null)
{
return HttpNotFound();
}
return View(item);
}
ProductEdit.cs:
@model RRPortal.Models.Item
@{
ViewBag.Title = "ProductEdit";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>ProductEdit</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@Html.HiddenFor(model => model.Id)
<div class="form-group">
@Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Flags, htmlAttributes: new { @class = "control-label col-md-2 " })
</div>
@*Flags list*@
@for (int i = 0; i < Model.Flags.Count; i++) //foreach (var flag in Model.Flags)
{
<div class="form-group">
//@Html.HiddenFor(modelItem => Model.Flags[i].Id)
@Html.Label(Model.Flags[i].Name, htmlAttributes: new { @class = "control-label col-md-3" })
@Html.LabelFor(modelItem => Model.Flags[i].Enabled, htmlAttributes: new { @class = "control-label col-md-1" })
<div class="col-md-8">
@Html.EditorFor(modelItem => Model.Flags[i].Enabled, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(modelItem => Model.Flags[i].Enabled, "", new { @class = "text-danger" })
</div>
</div>
}
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
Item.cs:
public class Item
{
[JsonProperty(PropertyName = "id")]
public string Id { get; set; }
[Required]
[JsonProperty(PropertyName = "name")]
public string Name { get; set; }
[JsonProperty(PropertyName = "flags")]
public List<Flag> Flags { get; set; }
[JsonProperty(PropertyName = "organisations")]
public List<Organisation> Organisations { get; set; }
}
public class Flag
{
[JsonProperty(PropertyName = "id")]
public int Id { get; set; }
[Required]
[JsonProperty(PropertyName = "name")]
public string Name { get; set; }
[Required]
[JsonProperty(PropertyName = "enabled")]
public bool Enabled { get; set; }
}
public class Organisation
{
[JsonProperty(PropertyName = "id")]
public int Id { get; set; }
[JsonProperty(PropertyName = "name")]
public string Name { get; set; }
[JsonProperty(PropertyName = "users")]
[Display(Name ="Users")]
public List<User> UserStore { get; set; }
}
public class User
{
[JsonProperty(PropertyName = "id")]
public int Id { get; set; }
[Required]
[JsonProperty(PropertyName = "fname")]
public string FName { get; set; }
[Required]
[JsonProperty(PropertyName = "lname")]
public string LName { get; set; }
[Required]
[Display(Name = "Admin?")]
[JsonProperty(PropertyName = "isadmin")]
public bool IsAdmin { get; set; }
}
当我调试控制器时,项目的ID和名称通过并且不为空,但标志列表始终为空。 ModelState显示以下异常:{&#34;参数转换类型&#39; System.String&#39;输入&#39; RRPortal.Models.Flag&#39;失败,因为没有类型转换器可以在这些类型之间进行转换。&#34;}
我也被问到ModelState在哪里显示异常,所以下面是截图:
如果有人有任何问题,我会很乐意更新这个问题。我一直在调整视图2天,仍然无法获得包含任何内容的项目。渲染的HTML似乎完全包含组织和内部对象。
感谢任何帮助!
答案 0 :(得分:0)
我的猜测是,在HttpGet
视图中,您有以下内容:
[HttpGet]
public ActionResult EditProductAsync()
{
var model = new ProductViewModel()
{
Flags = _uow.Products.GetFlags(),
Organisations = _uow.Products.GetOrganisations()
};
return View(model);
}
因为这些对象也不是作为表单的一部分返回的,所以它们将返回到服务器为空,这会为您抛出错误,从而使模型无效。在检查模型是否有效之前,您应该首先执行以下操作:
[HttpPost]
[ActionName("ProductEdit")]
[ValidateAntiForgeryToken]
public async Task<ActionResult> EditProductAsync( [Bind(Include = "Id, Name, Flags, Organisations")] Item model)
{
model.Organisations = _uow.Products.GetOrganisations();
model.Flags = _uow.Products.GetFlags();
if (ModelState.IsValid)
{
await DocDBRepo<Item>.UpdateItemAsync(model.Id, model);
return RedirectToAction("Index");
}
return View(model);
}
通过填充这些字段,您所遇到的任何模型错误都是您提交表单时客户的错误。