Search code examples
c#asp.netmodel-view-controllermodelstate

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


I have a problem for use ModelState. I use a controller for show a list, edit, and create a element. I use partials views for create and edit. on the index view

My index view use a view model (contain a list of my model and the selected model) My problem is I would like to show the validation error on my partial view.

Can you help me for add this modelState on my save function?

RecordersViewModel.cs

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

MapRecorders (table db)

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

Solution

  • I find my solution.

    I just forgot to call the validation.js script ...

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