2016-05-23 51 views
0

Ich habe eine Controller-Aktion (Bearbeiten - Post) für ein Formular, das vor dem Speichern eine benutzerdefinierte Überprüfung durchführt und eine Nachricht zurückgibt, wenn die Bedingungen nicht erfüllt sind. Das Formular zeigt auch eine Teilansicht einer IEnumerable-Liste verknüpfter Notizen an. Ich habe kein Problem mit dem Laden des Formulars (GET) oder mit einem erfolgreichen Speichern (POST). Allerdings, wenn ich versuchen, die benutzerdefinierte Nachricht zurück, erhalte ich folgende Fehlermeldung:Fehler beim Auffüllen von partiell mit IEnumerable nach erfolgloser benutzerdefinierter Überprüfung

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]'.

Dank für irgendwelche und alle Hilfe.

Hier ist meine ClientViewModel Klasse:

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; } 
} 
} 

Hier ist die NoteViewModel Klasse: using System; mit System.Collections.Generic; mit System.Linq; mit System.Web; mit System.ComponentModel.DataAnnotations; mit 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; } 
} 
} 

Hier ist die Formularansicht:

@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");} 
} 

Hier ist die Funktion Controller-Beitrag:

// 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); 
     } 
    } 

Schließlich ist hier die _notes Teilansicht:

@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

Da der Fehler, den Sie vorbei eine andere Art von Modell zu der Ansicht erklärt, als sie erwartet. Wenn NoteViewModel eine Spezialisierung von ClientViewModel ist, können Sie das andere übernehmen. Andernfalls müssen Sie die Objekte in den entsprechenden Typ konvertieren. –

+0

Danke, Mattias. Ich verstehe das Konzept, weiß aber nicht wohin. Können Sie mit dem obigen Controller ein Beispiel angeben? –

Antwort

0

Es scheint, mein Problem war, dass ich es nicht getan hatte habe die Notes IEnumerable als HashSet in mein ClientViewModel aufgenommen.

Ich habe folgendes in die öffentlichen ClientViewModel Klammer Klasse und nicht mehr den Fehler sehen:

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