2016-05-23 47 views
0

對於在執行自定義檢查之前執行自定義檢查的窗體,我有一個控制器操作(編輯 - 發佈)保存並在條件不滿足時返回消息。該表單還顯示IEnumerable關聯註釋列表的部分視圖。 我對錶單加載(GET)或成功保存(POST)沒有問題。 然而,當我試圖返回自定義消息,我收到以下錯誤:在自定義驗證失敗後使用IEnumerable填充部分錯誤

The model item passed into the dictionary is of type 'Vanguard.Models.ClientViewModel', but this dictionary requires a model item of type '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.Collections.Generic;使用System.Linq的 ; using System.Web; using 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)&nbsp;@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)&nbsp;@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"> 
       &nbsp; 
      </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");} 
} 

這裏是控制器郵政功能:

// 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)&nbsp;@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> 
} 
+0

由於錯誤解釋了你傳遞一個不同類型的模型比它預計的看法。如果NoteViewModel是ClientViewModel的一個特例,則可以使其繼承另一個。否則,您將不得不將對象轉換爲適當的類型。 –

+0

謝謝,Mattias。我理解這個概念,但不知道該怎麼做。你能提供一個使用上面的控制器的例子嗎? –

回答

0

看來我的問題是我沒有在我的ClientViewModel中包含Notes IEnumerable作爲HashSet。

添加以下到公共類ClientViewModel支架,不再看到錯誤:

public ClientViewModel() 
{ 
    Id = Guid.NewGuid(); 
    this.Notes = new HashSet<NoteViewModel>(); 
}