简体   繁体   中英

ASP.NET MVC - jQuery POST method is null

I'm calling a PartialView and injected it to a <div> from another PartialView to make it popup modal using Boostrap Modal . So far, my Boostrap Modal is displaying as expected BUT, NOT behaving as expected. The following are my objectives in my Boostrap Modal.

  1. Make a Boostrap Modal - OK
  2. Add validation on the Boostrap Modal - OK
  3. Send the value of my modal to save in the database - NOT OK

This is the <div> where I inject the PartialView and make it a modal

<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
    <div class="modal-content">
        <div class="modal-header">
            <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
            <h4 class="modal-title" id="myModalLabel">Create Sample</h4>
        </div>
        <div class="modal-body">
            <div id="modalBodyContainer">

            </div>
        </div>
        <div class="modal-footer">
            <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
            <button type="button" class="btn btn-primary" id="btnCreateSample">Create</button>
        </div>
    </div>
</div>

PartialView to show as Boostrap Modal (This will be injected in the above <div> )

@model WebSensoryMvc.Models.SampleData

 @using (Html.BeginForm("Create", "SessionData", FormMethod.Post, new { id = "FormCreateSample", name = "FormCreateSample" }))
 {
@Html.AntiForgeryToken()

<div class="container">
    <div class="form-horizontal">
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })

        <div class="row">
            <div class="form-group">
                @Html.LabelFor(model => model.GroupNo, htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.EditorFor(model => model.GroupNo, new { htmlAttributes = new { @class = "form-control" } })
                    @Html.ValidationMessageFor(model => model.GroupNo, "", new { @class = "text-danger" })
                </div>
            </div>
        </div>

        <div class="row">
            <div class="form-group">
                @Html.LabelFor(model => model.MaterialID, "Material", htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.DropDownList("MaterialID", null, htmlAttributes: new { @class = "form-control" })
                    @Html.ValidationMessageFor(model => model.MaterialID, "", new { @class = "text-danger" })
                </div>
            </div>
        </div>

        <div class="row">
            <div class="form-group">
                @Html.LabelFor(model => model.SampleCode, htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.EditorFor(model => model.SampleCode, new { htmlAttributes = new { @class = "form-control" } })
                    @Html.ValidationMessageFor(model => model.SampleCode, "", new { @class = "text-danger" })
                </div>
            </div>
        </div>

        <div class="row">
            <div class="form-group">
                @Html.LabelFor(model => model.BatchCode, htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.EditorFor(model => model.BatchCode, new { htmlAttributes = new { @class = "form-control text-uppercase" } })
                    @Html.ValidationMessageFor(model => model.BatchCode, "", new { @class = "text-danger" })
                </div>
            </div>
        </div>

        <div class="row">
            <div class="form-group">
                @Html.LabelFor(model => model.SizeID, "Size", htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.DropDownList("SizeID", null, htmlAttributes: new { @class = "form-control" })
                    @Html.ValidationMessageFor(model => model.SizeID, "", new { @class = "text-danger" })
                </div>
            </div>
        </div>

        <div class="row">
            <div class="form-group">
                @Html.LabelFor(model => model.AgeID, "Age", htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.DropDownList("AgeID", null, htmlAttributes: new { @class = "form-control" })
                    @Html.ValidationMessageFor(model => model.AgeID, "", new { @class = "text-danger" })
                </div>
            </div>

        </div>

        <div class="row">
            <div class="form-group">
                @Html.LabelFor(model => model.TemperatureID, "Temperature", htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.DropDownList("TemperatureID", null, htmlAttributes: new { @class = "form-control" })
                    @Html.ValidationMessageFor(model => model.TemperatureID, "", new { @class = "text-danger" })
                </div>
            </div>
        </div>

        <div class="row">
            <div class="form-group">
                @Html.LabelFor(model => model.PackagingTypeID, "Packaging Type", htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.DropDownList("PackagingTypeID", null, htmlAttributes: new { @class = "form-control" })
                    @Html.ValidationMessageFor(model => model.PackagingTypeID, "", new { @class = "text-danger" })
                </div>
            </div>
        </div>

        <div class="row">
            <div class="form-group">
                @Html.LabelFor(model => model.Spike, htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    <div class="checkbox">
                        @Html.EditorFor(model => model.Spike)
                        @Html.ValidationMessageFor(model => model.Spike, "", new { @class = "text-danger" })
                    </div>
                </div>
            </div>
        </div>

        <div class="row">
            <div class="form-group">
                @Html.LabelFor(model => model.SampleType, htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.EditorFor(model => model.SampleType, new { htmlAttributes = new { @class = "form-control" } })
                    @Html.ValidationMessageFor(model => model.SampleType, "", new { @class = "text-danger" })
                </div>
            </div>
        </div>

        <div class="row">
            <div class="form-group">
                @Html.LabelFor(model => model.Remarks, htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.EditorFor(model => model.Remarks, new { htmlAttributes = new { @class = "form-control" } })
                    @Html.ValidationMessageFor(model => model.Remarks, "", new { @class = "text-danger" })
                </div>
            </div>
        </div>
    </div>
</div>
 }

Currently, I'm having hard time debugging in saving the modal value in the database. I'm using ajax to call a method in a controller. But, I'm experiencing the following problems.

  1. When the below code is executed, the $('#FormCreateSample').serialize() which expected to return the model of the PartialView is blank, where all the properties are null.

      $(document).ready(function () { $("#btnModal").on('click', function () { var url = "/SessionData/Create"; $.ajax({ url: url, type: 'GET', success: function (data) { $('#modalBodyContainer').html(data) $('#myModal').modal('show'); $("#btnCreateSample").off().on('click', function () { var form = $('form'); form.data('validator', null); $.validator.unobtrusive.parse(form); if ($('form').valid()) { $.ajax({ url: "/SessionData/Create", type: "POST", data: $('#FormCreateSample').serialize(), success: function () { alert("POST success"); }, error: function () { alert("POST error"); } }); } }); } }); }); }); 
  2. Since my action method in controller have [ValidateAntiForgeryToken] annotation, the above script throw an exception "Token is not present..." . To fix that, I updated my code and add the below lines of code.

      var token = $('input[name="__RequestVerificationToken"]').val(); $.ajax({ url: "/SessionData/Create", type: "POST", data: { $('#FormCreateSample').serialize(), __RequestVerificationToken: token }, success: function () { alert("POST success"); }, error: function () { alert("POST error"); } }); 

The problem in # 2 approach is, it passes null value in my action method sampleData parameter. Below is my action method in my controller.

    [HttpPost]
    [ValidateAntiForgeryToken]
    public void Create(SampleData sampleData)
    {
        if (ModelState.IsValid)
        {
            sampleData.SessionID = Convert.ToInt32(TempData["CurrentSessionId"]);

            db.SampleDatas.Add(sampleData);
            db.SaveChanges();

            RedirectToAction("List", "SessionData");
        }

    }

Anyone have an idea why $("FormCreateSample").serialize() is null ? Or maybe it cannot find the form id FormCreateSample ?

TIA

UPDATE 1 After using the first answer, the model is now pass to method but all properties are still null .

在此输入图像描述

You need to add AntiForgeryToken in your message header in the ajax call:

var token = $('input[name="__RequestVerificationToken"]').val();
var tokenadr = $('form[action="/SessionData/Create"] input[name="__RequestVerificationToken"]').val(); 

var headers = {};
var headersadr = {};
headers['__RequestVerificationToken'] = token;
headersadr['__RequestVerificationToken'] = tokenadr;

 $.ajax({
 url: "/SessionData/Create",
 type: "POST",
 headers: headersadr,
 data: "__RequestVerificationToken=" + token + "" + $('form[action="/SessionData/Create"]').serialize(),
success: function () {
   alert("POST success");
},
error: function () {
    alert("POST error");
}
});

Try changing

.serialize()

To

.serializeArray()
var token = $('input[name="__RequestVerificationToken"]').val();
  $.ajax({
     url: "/SessionData/Create",
     type: "POST",
     data: { $('#FormCreateSample').serialize(), __RequestVerificationToken: token },
     content-type : 'application/json',
    success: function () {
       alert("POST success");
    },
    error: function () {
        alert("POST error");
    }
 });

ADD this : content-type : 'application/json',

After couple of days in debugging my scenario, I found my solution now. Instead of using Bootstrap Modal , I use Bootbox . Using Bootbox fixed all my problems from validation up to saving to database.

Below is the script that I use to open a modal.

<script>
$(document).ready(function () {
    $("#modalCreateSample").on('click', function () {
        $.ajax({
            url: "/SessionData/Create",
            type: 'GET',
            success: function (data) {

                bootbox.dialog({
                    title: "Create Session",
                    message: data,
                    buttons: {
                        success: {
                            label: "Save",
                            className: "btn-success",
                            callback: function () {

                                var form = $('#FormCreateSample');
                                form.data('validator', null);
                                $.validator.unobtrusive.parse(form);

                                if ($(form).valid()) {
                                    $.post("/SessionData/Create", $("#FormCreateSample").serialize(), function (data, status) {
                                        if (status == "success") {
                                            // Refresh list of samples

                                            return false;
                                        }
                                    });
                                } else {
                                    return false;
                                }
                            }
                        }
                    }
                });

            },
            error: function (error) {
                bootbox.alert("We encounter problem while retrieving the Sample Code of the selected Session");
            }
        });
    });
});
 </script>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM