Asp.Net 带有索引、添加、编辑的控制器中的 MVC 5 ModelState

Asp.Net MVC 5 ModelState in a controller with index, add, edit

我在使用 ModelState 时遇到问题。 我使用控制器来显示列表、编辑和创建元素。 我使用局部视图来创建和编辑。在索引视图上

我的索引视图使用视图模型(包含我的模型和所选模型的列表) 我的问题是我想在我的部分视图中显示验证错误。

你能帮我在我的保存功能上添加这个模型状态吗?

RecordersViewModel.cs

public class RecordersViewModel
{
    public List<MapRecorders> Recorders { get; set; }
    public MapRecorders SelectedRecorder { get; set; }
    public string DisplayMode { get; set; }
}

地图记录器(table 数据库)

public partial class MapRecorders
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public MapRecorders()
    {
        this.Timers = new HashSet<Timers>();
    }
    [Key]
    [Display(Name = "Id")]
    public int MapRecordersID { get; set; }
    
    [Display(Name = "Nom")]
    [Required(ErrorMessage = "Le nom est obligatoire.")]
    public string Name { get; set; }
}

recordersController.cs

public ActionResult Index()
{
    using (ScheduleRecDBEntities db = new ScheduleRecDBEntities())
    {
        List<MapRecordingtypes> recodersTypesModel = db.MapRecordingtypes.ToList();
        ViewData["RecordingTypeList"] = recodersTypesModel.Select(x => new SelectListItem { Value = x.MapRecordingtypesID.ToString(), Text = x.Name });

        RecordersViewModel model = new RecordersViewModel();
        model.Recorders = db.MapRecorders.OrderBy(m => m.MapRecordersID).ToList();
        model.SelectedRecorder = null;
        return View(model);
    }
}
[HttpPost]
public ActionResult Add()
{
    using (ScheduleRecDBEntities db = new ScheduleRecDBEntities())
    {
        List<MapRecordingtypes> recodersTypesModel = db.MapRecordingtypes.ToList();
        ViewData["RecordingTypeList"] = recodersTypesModel.Select(x => new SelectListItem { Value = x.MapRecordingtypesID.ToString(), Text = x.Name });

        RecordersViewModel model = new RecordersViewModel();
        model.Recorders = db.MapRecorders.OrderBy(
            m => m.MapRecordersID).ToList();
        model.SelectedRecorder = null;
        model.DisplayMode = "WriteOnly";
        return View("Index", model);
    }
}
[HttpPost]
public ActionResult Edit(int id)
{
    using (ScheduleRecDBEntities db = new ScheduleRecDBEntities())
    {
        List<MapRecordingtypes> recodersTypesModel = db.MapRecordingtypes.ToList();
        ViewData["RecordingTypeList"] = recodersTypesModel.Select(x => new SelectListItem { Value = x.MapRecordingtypesID.ToString(), Text = x.Name });

        RecordersViewModel model = new RecordersViewModel();
        model.Recorders = db.MapRecorders.OrderBy(
            m => m.MapRecordersID).ToList();
        model.SelectedRecorder = db.MapRecorders.Find(id);
        model.DisplayMode = "ReadWrite";
        return View("Index", model);
    }
}
[HttpPost]
public ActionResult Save(MapRecorders obj)
{
    using (ScheduleRecDBEntities db = new ScheduleRecDBEntities())
    {
        MapRecorders existing = db.MapRecorders.Find(obj.MapRecordersID);

        if (existing == null)
        {
            obj.Active =
                Convert.ToByte(Request.Form["Active"]
                    .ToString()); //Request.Form["Active"].ToString() == "false" ? 0 : 1;
            db.MapRecorders.Add(obj);
        }
        else
        {
            existing.Name = obj.Name;
            existing.Link = obj.Link;
            existing.LinkBackup = obj.LinkBackup;
            existing.MapRecordingTypesID = obj.MapRecordingTypesID;
            existing.Active =
                Convert.ToByte(Request.Form["Active"]
                    .ToString()); //Request.Form["Active"].ToString() == "false" ? 0 : 1;
        }

        db.SaveChanges();

        RecordersViewModel model = new RecordersViewModel();
        model.Recorders = db.MapRecorders.OrderBy(
            m => m.MapRecordersID).ToList();
        return RedirectToAction("Index", "Recorders");
    }
}

index.cshtml

@model ScheduleRecordings.Models.RecordersViewModel

@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<div class="row">
    <div class="col-lg-12 col-sm-12 float-left btn-list titlebar">
        <h1>Liste des décodeurs</h1>
        <form method="post">
            <input class="btn btn-default" type="submit"
                   value="Ajouter" formaction="/Recorders/Add" />
        </form>
    </div>
    <div class="col-lg-6 col-sm-12 float-left" style="margin-bottom: 15px;">
        <form method="post">
            <table class="table-list" border="1" cellpadding="10">
                <tr>
                    <th>@Html.LabelFor(m => m.SelectedRecorder.MapRecordersID)</th>
                    <th>@Html.LabelFor(m => m.SelectedRecorder.Name)</th>
                    <th>@Html.LabelFor(m => m.SelectedRecorder.Link)</th>
                    <th>@Html.LabelFor(m => m.SelectedRecorder.LinkBackup)</th>
                    <th>@Html.LabelFor(m => m.SelectedRecorder.MapRecordingtypes.Name)</th>
                    <th>@Html.LabelFor(m => m.SelectedRecorder.Active)</th>
                    <th></th>
                </tr>
                @foreach (var item in Model.Recorders)
                {
                    if (Model.SelectedRecorder != null)
                    {
                        if (item.MapRecordersID ==
                            Model.SelectedRecorder.MapRecordersID)
                        {
                            @:<tr class="SelectedRecorder">
                            }
                            else
                            {
                                @:<tr>
                            }
                        }
                        else
                        {
                            @:<tr>
                                }
                                <td>@item.MapRecordersID</td>
                                <td>@item.Name</td>
                                <td><a target="_blank" href="http://@item.Link">@item.Link</a></td>
                                <td><a target="_blank"  href="http://@item.LinkBackup">@item.LinkBackup</a></td>
                                <td>@item.MapRecordingtypes.Name</td>
                                <td>@Html.CheckBox("Active_" + @item.MapRecordersID.ToString(), Convert.ToBoolean(@item.Active), new { @disabled = "disabled" })</td>
                                <td>
                                    <input type="submit"
                                           formaction="/Recorders/Edit/@item.MapRecordersID"
                                           value="Editer" />
                                </td>
                                @:</tr>
                }
            </table>
        </form>
    </div>

    <div class="col-lg-6 col-sm-12 float-left">
        @{
            if (Model.SelectedRecorder != null)
            {
                if (Model.DisplayMode == "ReadOnly")
                {
                    Html.RenderPartial
                    ("ShowRecorder", Model.SelectedRecorder);
                }
                if (Model.DisplayMode == "ReadWrite")
                {
                    Html.RenderPartial
                    ("EditRecorder", Model.SelectedRecorder);
                }
            }
            if (Model.DisplayMode == "WriteOnly")
            {
                Html.RenderPartial("InsertRecorder",
                new ScheduleRecordings.Models.MapRecorders());
            }
        }
    </div>
</div>

InsertRecorder.cshtml

@using ScheduleRecordings.Models
@model ScheduleRecordings.Models.MapRecorders

@using (Html.BeginForm("Insert", "Recorders", FormMethod.Post))
{
    <table class="table-info" border="1" cellpadding="10">
        <tr>
            <td colspan="2">
                <span>Ajouter</span>
            </td>
        </tr>
        <tr>
            <td>@Html.LabelFor(m => m.Name)</td>
            <td>@Html.TextBoxFor(m => m.Name, new { @autofocus = "autofocus" })</td>
        </tr>
        <tr>
            <td>@Html.LabelFor(m => m.Link)</td>
            <td>@Html.TextBoxFor(m => m.Link)</td>
        </tr>
        <tr>
            <td>@Html.LabelFor(m => m.LinkBackup)</td>
            <td>@Html.TextBoxFor(m => m.LinkBackup)</td>
        </tr>
        <tr>
            <td>@Html.LabelFor(m => m.MapRecordingtypes.Name)</td>
            <td>@Html.DropDownListFor(m => m.MapRecordingTypesID, (IEnumerable<SelectListItem>)ViewData["RecordingTypeList"], "[Type]", new { @class = "form-control" })</td>
        </tr>
        <tr>
            <td>@Html.LabelFor(m => m.Active)</td>
            <td>@Html.CheckBox("Active", Convert.ToBoolean(Model.Active))</td>
        </tr>
        <tr>
            <td colspan="2">
                <input type="submit" value="Sauvegarder"
                       formaction="/Recorders/Save" />
                <input type="submit" value="Annuler"
                       formaction="/Recorders" />
            </td>
        </tr>
    </table>
    <div>
        @Html.ValidationMessageFor(m => m.Name, "", new { @class = "text-danger" })
        @Html.ValidationMessageFor(m => m.Link, "", new { @class = "text-danger" })
        @Html.ValidationMessageFor(m => m.LinkBackup, "", new { @class = "text-danger" })
    </div>
}

根据我对问题的理解:

1:) 在保存方法中使用ModeState.IsValid 属性。为此只需使用

 If(ModelState.IsValid)
{ 
   //Save Code
}
    else
{
   //Do Something
}

2:) 您需要将验证消息添加到您的 ViewModel,并将验证消息帮助器方法添加到分部视图。就像在给定的参考中一样显示错误消息。

Link:- https://forums.asp.net/post/6080694.aspx

编辑 将这种类型的验证添加到您的 ViewModel

[StringLength(2000, ErrorMessage = "The Description Can Not Exceed 2000 Characters")]

并在分部视图中添加此类验证辅助方法

@Html.ValidationMessageFor(model => model.DisplayMode, "", new { @class = "text-danger" })

我找到了我的解决方案。

我只是忘了调用 validation.js 脚本 ...

@Scripts.Render("~/bundles/jqueryval")