首页 文章

在自定义验证失败后使用IEnumerable填充Partial时出错

提问于
浏览
0

我有一个控制器操作(编辑 - 发布)用于在保存之前执行自定义检查的表单,并在不满足条件时返回消息 . 该表单还显示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)&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");}
}

这是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)&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>
}

1 回答

  • 0

    看来我的问题是我没有在我的ClientViewModel中将Notes IEnumerable包含为HashSet .

    我将以下内容添加到公共类ClientViewModel括号中,不再看到错误:

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

相关问题