我有一个控制器操作(编辑 - 发布)用于在保存之前执行自定义检查的表单,并在不满足条件时返回消息 . 该表单还显示IEnumerable关联注释列表的部分视图 . 我没有表单加载(GET)或成功保存(POST)的问题 . 但是,当我尝试返回自定义消息时,我收到以下错误:
传递到字典中的模型项的类型为'Vanguard.Models.ClientViewModel',但此字典需要类型为'System.Collections.Generic.IEnumerable`1 [Vanguard.Models.NoteViewModel]'的模型项 .
感谢您的帮助 .
这是我的ClientViewModel类:
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Vanguard.DAL;
namespace Vanguard.Models
{
public class ClientViewModel
{
[JsonProperty(PropertyName = "id")]
public System.Guid Id { get; set; }
[Display(Name = "Create Time")]
[JsonProperty(PropertyName = "createTime")]
public System.DateTime CreateTime { get; set; }
[JsonProperty(PropertyName = "createUserId")]
public string CreateUserId { get; set; }
[Display(Name = "ChangeTime")]
[JsonProperty(PropertyName = "changeTime")]
public Nullable<System.DateTime> ChangeTime { get; set; }
[JsonProperty(PropertyName = "changeUserId")]
public string ChangeUserId { get; set; }
[JsonProperty(PropertyName = "statusId")]
public System.Guid StatusId { get; set; }
[Required]
[JsonProperty(PropertyName = "name")]
[StringLength(255, MinimumLength = 3)]
[RegularExpression(@"^[A-Z0-9][a-zA-Z0-9\'\s\.\-\,]*$", ErrorMessage = "Letters, Numbers, and the following characters only ('.-,)")]
[Display(Name = "Client Name", Order = 15000)]
public string Name { get; set; }
[Required(ErrorMessage = "The Client Type is Required")]
[JsonProperty(PropertyName = "clientTypeId")]
public System.Guid ClientTypeId { get; set; }
[StringLength(255)]
[RegularExpression(@"^[A-Z0-9][a-zA-Z0-9\'\s\.\-\,]*$", ErrorMessage = "Letters, Numbers, and the following characters only ('.-,)")]
[Display(Name = "Xytech Name", Order = 15002)]
[JsonProperty(PropertyName = "xytechName")]
public string XytechName { get; set; }
[StringLength(50)]
[RegularExpression(@"^[0-9][0-9\s\-]*$", ErrorMessage = "Numbers, and the following characters only (-)")]
[Display(Name = "Xytech Number", Order = 15003)]
[JsonProperty(PropertyName = "xytechNumber")]
public string XytechNumber { get; set; }
[StringLength(45)]
[RegularExpression(@"^[a-zA-Z0-9][a-zA-Z0-9\.\-\/]*$", ErrorMessage = "Letters, Numbers, and the following characters only (.-/)")]
[Display(Name = "EIDR", Order = 15004)]
[JsonProperty(PropertyName = "eidr")]
public string EIDR { get; set; }
public virtual AspNetUser AspNetUser { get; set; }
public virtual AspNetUser AspNetUser1 { get; set; }
public virtual Option_ClientTypeViewModel Option_ClientType { get; set; }
public virtual Option_StatusViewModel Option_Status { get; set; }
public virtual ICollection<Specification> Specifications { get; set; }
public virtual ICollection<NoteViewModel> Notes { get; set; }
}
}
这是NoteViewModel类:using System;使用System.Collections.Generic;使用System.Linq;使用System.Web;使用System.ComponentModel.DataAnnotations;使用Vanguard.DAL;
namespace Vanguard.Models
{
public class NoteViewModel
{
public NoteViewModel()
{
Id = Guid.NewGuid();
}
public System.Guid Id { get; set; }
[Display(Name = "Create Time")]
public System.DateTime CreateTime { get; set; }
public string CreateUserId { get; set; }
[Display(Name = "Change Time")]
public Nullable<System.DateTime> ChangeTime { get; set; }
public string ChangeUserId { get; set; }
public Nullable<System.Guid> StatusId { get; set; }
public System.Guid ModuleId { get; set; }
public Nullable<System.Guid> ItemId { get; set; }
[Display(Name = "Note")]
[DataType(DataType.MultilineText)]
[Required]
public string Note1 { get; set; }
public int Section { get; set; }
public virtual AspNetUser AspNetUser { get; set; }
public virtual AspNetUser AspNetUser1 { get; set; }
public virtual Module Module { get; set; }
public virtual Option_StatusViewModel Option_Status { get; set; }
public virtual ClientViewModel Client { get; set; }
public virtual Specification Specification { get; set; }
}
}
这是表单视图:
@model Vanguard.Models.ClientViewModel
@{
var isCreating = ViewBag.isCreating;
ViewBag.Title = (isCreating) ? "Create" : "Edit";
}
<div data-bind="visible: !saveCompleted()">
<h2>@ViewBag.Title</h2>
@using (Html.BeginForm((isCreating) ? "Create" : "Edit", "Clients", FormMethod.Post, new { data_bind = "submit: validateAndSave" }))
{
@Html.AntiForgeryToken()
@Html.HiddenFor(model => model.Id)
<div class="form-horizontal">
<h4>Client</h4>
<div class="form-actions no-color">
@Html.ActionLink("<-", "Index", null, new { @class = "btn btn-info", data_toggle = "tooltip", title = "Back" })
</div>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@if (isCreating)
{
<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", data_bind = "value: client.name" } })
@Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
<div class="text-danger">@ViewBag.Error</div>
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Option_ClientType.Text, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownList("ClientTypeId", null, String.Empty, htmlAttributes: new { @class = "form-control", data_bind = "value: client.clientTypeId" })
@Html.ValidationMessageFor(model => model.ClientTypeId, "", new { @class = "text-danger" })
</div>
</div>
}
else
{
@Html.HiddenFor(model => model.CreateTime)
@Html.HiddenFor(model => model.CreateUserId)
@Html.HiddenFor(model => model.ChangeTime)
@Html.HiddenFor(model => model.ChangeUserId)
<div class="form-group">
@Html.LabelFor(model => model.CreateTime, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DisplayFor(model => model.CreateTime) @Html.DisplayFor(model => model.AspNetUser.UserName)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.ChangeTime, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DisplayFor(model => model.ChangeTime) @Html.DisplayFor(model => model.AspNetUser1.UserName)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Option_Status.Text, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@if (Model.Name == "Advanced Digital Services")
{
@Html.HiddenFor(model => model.StatusId)
@Html.DisplayFor(model => model.Option_Status.Text)
}
else
{
@Html.DropDownList("StatusId", null, htmlAttributes: new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.StatusId, "", new { @class = "text-danger" })
}
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@if (Model.Name == "Advanced Digital Services")
{
@Html.HiddenFor(model => model.Name)
@Html.DisplayFor(model => model.Name)
}
else
{
@Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control", data_bind = "value: client.name" } })
@Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
<div class="text-danger">@ViewBag.Error</div>
}
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Option_ClientType.Text, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@if (Model.Name == "Advanced Digital Services")
{
@Html.HiddenFor(model => model.ClientTypeId)
@Html.DisplayFor(model => model.Option_ClientType.Text)
}
else
{
@Html.DropDownList("ClientTypeId", null, String.Empty, htmlAttributes: new { @class = "form-control", data_bind = "value: client.clientTypeId" })
@Html.ValidationMessageFor(model => model.ClientTypeId, "", new { @class = "text-danger" })
}
</div>
</div>
}
<div class="form-group">
@Html.LabelFor(model => model.XytechName, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.XytechName, new { htmlAttributes = new { @class = "form-control", data_bind = "value: client.xytechName" } })
@Html.ValidationMessageFor(model => model.XytechName, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.XytechNumber, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.XytechNumber, new { htmlAttributes = new { @class = "form-control", data_bind = "value: client.xytechNumber" } })
@Html.ValidationMessageFor(model => model.XytechNumber, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.EIDR, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.EIDR, new { htmlAttributes = new { @class = "form-control", data_bind = "value: client.eidr" } })
@Html.ValidationMessageFor(model => model.EIDR, "", new { @class = "text-danger" })
</div>
</div>
@if (isCreating)
{
<div class="form-group">
<label class="control-label col-md-2">Note</label>
<div class="col-md-10">
<input type="text" id="Note1" name="Note1" class="form-control" />
</div>
</div>
}
else
{
<div class="col-md-2">
</div>
<div class="col-md-10">
@Html.Partial("_Notes", Model.Notes)
</div>
}
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="@if (isCreating){ @Html.Raw("Create")} else {@Html.Raw("Update")}" class="btn btn-primary" />
@if (!isCreating)
{
<a href="javascript:confirmDelete('@Model.Id')" class="btn btn-danger" data-toggle="tooltip" title="Delete">X</a>
}
</div>
</div>
</div>
}
</div>
<div class="form-actions no-color">
@Html.ActionLink("<-", "Index", null, new { @class = "btn btn-info", data_toggle = "tooltip", title = "Back" })
</div>
<form id="deleteForm" method="POST">
@Html.AntiForgeryToken()
<input type="hidden" name="id" id="deleteFormItemId" />
</form>
<form id="NoteForm" method="post">
@Html.AntiForgeryToken()
<input type="hidden" name="id" id="NoteFormItemId" />
<input type="hidden" name="view" id="view" value="e" />
<input type="hidden" name="Note1" id="NoteFormNote1" />
<input type="hidden" name="ModuleId" id="ModuleId" value="@ViewBag.ModuleId" />
<input type="hidden" name="ItemId" id="ItemId" value="@ViewBag.ItemId" />
<input type="hidden" name="Section" id="Section" value="@ViewBag.SectionId" />
</form>
@section scriptsTop{
@{ Html.RenderPartial("_Delete.Modal");}
}
@section Scripts {
@{ Html.RenderPartial("_Delete.js");}
}
这是Controller Post功能:
// POST: Clients/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "Id,CreateTime,CreateUserId,ChangeTime,ChangeUserId,StatusId,Name,ClientTypeId,XytechName,XytechNumber,EIDR,Notes")] ClientViewModel client)
{
var UID = User.Identity.GetUserId();
if (ModelState.IsValid)
{
var data = (from record in db.Clients
where record.Option_Status.Sequence < 3
&& record.Name == client.Name
&& record.ClientTypeId == client.ClientTypeId
&& record.Id != client.Id
select record).FirstOrDefault();
if (data == null)
{
//Okay to Save//
client.ChangeTime = DateTime.Now;
client.ChangeUserId = UID;
db.Entry(Mapper.Map<ClientViewModel,Client>(client)).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Edit", new { id=client.Id });
}
else
{
//EXISTS//
var ct = (from record in db.Option_ClientType where record.Id == client.ClientTypeId select record.Text).FirstOrDefault();
var cts = (from record in db.Option_ClientType where record.Id == client.ClientTypeId select record.Sequence).FirstOrDefault();
ViewBag.Error = "A Client of the type " + ct + " with this name already exists";
ViewBag.ClientTypeId = new SelectList(db.Option_ClientType
.Where(c => c.Sequence > 0)
.OrderBy(c => c.Sequence), "Id", "Text", client.ClientTypeId);
ViewBag.StatusId = new SelectList(db.Option_Status.Where(s => s.Sequence < 3).OrderBy(s => s.Sequence), "Id", "Text", client.StatusId);
ViewBag.ModuleId = ModuleId();
ViewBag.ItemId = client.Id;
ViewBag.isCreating = false;
return View("Form", client);
}
}
else
{
var cts = (from record in db.Option_ClientType where record.Id == client.ClientTypeId select record.Sequence).FirstOrDefault();
ViewBag.ClientTypeId = new SelectList(db.Option_ClientType
.Where(c => c.Sequence > 0)
.OrderBy(c => c.Sequence), "Id", "Text", client.ClientTypeId);
ViewBag.StatusId = new SelectList(db.Option_Status.Where(s => s.Sequence < 3).OrderBy(s => s.Sequence), "Id", "Text", client.StatusId);
ViewBag.ModuleId = ModuleId();
ViewBag.ItemId = client.Id;
ViewBag.isCreating = false;
return View("Form", client);
}
}
最后,这是_Notes部分视图:
@model IEnumerable<Vanguard.Models.NoteViewModel>
<a href="javascript:confirmNoteCreate(@ViewBag.SectionId)" class="btn-sm btn-info" data-toggle="tooltip" title="Add Note">+</a>
@if (@Model.Where(n => n.Option_Status.Sequence < 3).Count() > 0)
{
<div class="panel">
@foreach (var item in Model.Where(n => n.Option_Status.Sequence < 3).OrderByDescending(n => n.ChangeTime))
{
<div class="form-group">
<div class="col-md-4">
@Html.DisplayFor(modelItem => item.ChangeTime) @Html.DisplayFor(modelItem => item.AspNetUser1.UserName)
</div>
<div class="col-md-6">
@Html.DisplayFor(modelItem => item.Note1)
</div>
<div class="col-md-2">
<a href="javascript:confirmNoteEdit('@item.Id')" class="btn-sm btn-primary" data-toggle="tooltip" title="Edit">E</a>|
<a href="javascript:confirmNoteDelete('@item.Id')" class="btn-sm btn-danger" data-toggle="tooltip" title="Delete">X</a>
</div>
</div>
}
</div>
}
1 回答
看来我的问题是我没有在我的ClientViewModel中将Notes IEnumerable包含为HashSet .
我将以下内容添加到公共类ClientViewModel括号中,不再看到错误: