ModelState.IsValid = false using jquery datepicker

2019-09-06 01:59发布

问题:

I have this model:

[MetadataType(typeof(MovieMetadata))]
public partial class Movie
{

}

class MovieMetadata
{
    [ScaffoldColumn(false)]
    public int id { get; set; }

    [Required(ErrorMessage = "Title is required")]
    public string title { get; set; }

    [Required]
    public DateTime releaseDate { get; set; }

    public string storyline { get; set; }

    public Binary poster { get; set; }

    [ScaffoldColumn(false)]
    public DateTime? duration { get; set; }

    [ScaffoldColumn(false)]
    public Binary trailer { get; set; }
}

this is the controller code:

    [HttpPost]
     public ActionResult Create([Bind(Exclude = "poster, trailer")]Movie movie, HttpPostedFileBase poster, HttpPostedFileBase trailer)
    {
        if (ModelState.IsValid)
        {
            //saving the movie
            OperationStatus opStatus = Repository.Save(movie);

            if (!opStatus.Status)
            {
                return View("Error");
            }
        }

        return View(movie);
    }

This is the View:

@model MoviesModel.Movie

@{
    ViewBag.Title = "Create";
    Layout = "~/Views/Shared/MoviesLayout.cshtml";
}

    @section createMovie{
    @using (Html.BeginForm(null, null, FormMethod.Post, new { id = "createForm", enctype = "multipart/form-data" }))
    {
        @Html.AntiForgeryToken()
        @Html.ValidationSummary(true)

        <div class="gallMemberBox">

            <div class="leftFormContent">
                <a href="#">Movie Name</a>

                <div class="imgTmpl">
                    <!--solo hay que especificar el src de la imagen-->
                    <img src="../../Content/img/imgTest.jpg" alt="" />  
                </div>
            </div>

            <div class="rightFormContent">

                <div>
                    @Html.LabelFor(model => model.title)

                    @Html.EditorFor(model => model.title)
                    @Html.ValidationMessageFor(model => model.title)
                </div>

                <div>
                    @Html.LabelFor(model => model.releaseDate)

                    @Html.EditorFor(model => model.releaseDate)
                    @Html.ValidationMessageFor(model => model.releaseDate)
                </div>

                <input type="submit" value="Create" />

            </div>

            <div class="clearBoth"></div>
        </div> 
    }
}

This is the template from Views\Shared\EditorTemplates\DateTime.cshtml

@Styles.Render("~/Content/themes/base/jquery-ui.css")

@Scripts.Render("~/Scripts/jquery-ui-1.8.24.js")

<script>
        $(function () {
            $("#datepicker").datepicker();
        });
</script>

@Html.TextBox("datepicker", null, new{id="datepicker"})

When I select a date and submit the form, the ModelState is false, and releaseDate comes with an error:

回答1:

If you want to use the editor template, change it to something like this:

@model DateTime?

@Styles.Render("~/Content/themes/base/jquery-ui.css")

@Scripts.Render("~/Scripts/jquery-ui-1.8.24.js")

@Html.TextBoxFor(m => m, new{@class="datepicker"})

<script>
        $(function () {
            $(".datepicker").datepicker();
        });
</script>

Using the TextBoxFor will wire up the model binding correctly.

Also, I would recommend moving your Styles.Render() and Scripts.Render() to your _Layout if possible. Since I changed the datepicker() to wire up a class, you could also move that if you wanted.



回答2:

I believe the problem is with this line:

@Html.TextBox("datepicker", null, new{id="datepicker"})

Here, you are creating a textbox withe the name and id of "datepicker". So when you submit the form, MVC will try to find a property in Movie called "datepicker", which is why releaseDate is empty.

I don't think there is a need for the Editor Template, you can just use @krillgar's recommendation.

If you still want to use an Editor Template, you will need to get the field name using the following approach:

How to get model's field name in custom editor template



回答3:

Instead of creating a separate Textbox with an ID of datepicker, just use another EditorFor for the property, and add an HTML class to the object of datepicker, and use that instead.

EDIT

This would be the syntax to set it up. (In your "View" section of the code above)

@Html.LabelFor(model => model.releaseDate, new { @class = "datepicker" })

Then your javascript would change to:

$(document).ready(function () {
    $('.datepicker').datepicker();
});


回答4:

To include this in your view instead, try something like the following:

    @Html.TextBox("releaseDate", Model.releaseDate.ToString("MM/dd/yyyy"), new {id="datepicker" })

Remember to also include your JQuery refs later followed by the script block.