MVC 5 - 控制器端的JSON post to controller始终为null

时间:2015-04-13 13:35:47

标签: json asp.net-mvc

我现在已经找了几个小时,希望不要复制一个问题,而我却找不到我想要的东西。

我正在努力将一个复杂的对象从一个表单传递回一个控制器,然后将它解析出来。我得到的问题是控制器显示空输入,尽管Chrome的标题帖显示数据输出。任何人都可以帮我一把吗?我在下面提供了代码。

模型

public class QuizTakenObject
    {
        [NotMapped]
        public QuizTakenComplete quizTakenComplete { get; set; }

        [NotMapped]
        public List<QuizSubmittedAnswers> submittedAnswers { get; set; }

        [NotMapped]
        public TopicList Topic { get; set; }

        [NotMapped]
        public QuizHeader QuizHeader { get; set; }

    }

查看/脚本

@model App.Models.QuizTakenObject

@{
    ViewBag.Title = "Take Quiz";
}

@section pageScripts{
    <script type="text/javascript">
        $(document).ready(function () {

            //Highlight background of selected background for increased visibility
            $("input[name^=QuizSubmittedAnswer]").change(function () {
                $(this).parent().addClass("bg-primary");
                $(this).parent().siblings().removeClass("bg-primary");
            });

            //Show save prompt on page after one answer is picked
            var i = 0;
            if (i == 0) {
                $("input[name^=QuizSubmittedAnswer]").change(function () {

                    $("#quizSave").fadeIn('fast');
                    $("#quizSave").animate({ height: '125px' }, 'fast')
                                  .animate({ width: '250px' }, 'fast', function () {
                                  $("#quizSaveText").fadeIn('500');
                        });

                });

            }

            //Prevent submitting before all answers have been selected
            //Count all questions, one per form group
            var questionsCount = $("form-group").length;

            //Listen for answers to be selected
            $("input[name^=QuizSubmittedAnswer]").change(function () {
                //Check to see if all answers are selected
                if ($("input[name^=QuizSubmittedAnswer]:checked").length >= questionsCount) {
                    $("#saveAndSubmitQuizButton").removeClass("disabled");
                }

            });

            //Save and submit quiz
            $("#saveAndSubmitQuizButton").click(function () {
                event.preventDefault;

                var complete = true;

                saveQuizAttempt(complete);
            });

            //Save but not submit quiz
            $("#saveQuizOnlyButton").click(function () {
                event.preventDefault;

                var complete = false;

                saveQuizAttempt(complete);
            });

            //Create or update quiz attempt in DB
            //saveQuizAttempt complete indicates if the record is to be marked as final
            function saveQuizAttempt(complete) {

                var array = $("#takeQuizForm").serializeArray();

                //build JSON array
                var json = {};

                $.each(array, function () {
                    json[this.name] = this.value || '';
                })
                //array.push({ "IsComplete": complete });


                //AJAX to post data
                $.ajax({
                    type: "POST",
                    url: "SubmitQuiz",
                    data: JSON.stringify(array),
                    dataType: "json",
                    contentType:"application/json; charset=UTF-8",

                    success: function (data) {
                        console.log("Success!");
                    },

                    error: function () {
                        console.log("Error");
                    }
                });
            }


        });
    </script>
}

<style>
    #quizSave {
        display: none;
        position: fixed;
        z-index: 999;
        height: 0;
        width: 0;
        bottom: 100px;
        right: 0;
        background-color: khaki;
        border: 1px solid black;
        border-radius: 2px 2px 2px 2px;
        padding: .5em 1em .5em 1em;
    }
</style>

<h2>@ViewBag.TopicName Quiz</h2>

<div class="row">
    <div class="container col-xs-9 col-sm-9 col-md-9 col-lg-9">
        <div class="well well-sm">
            <strong>Directions:</strong> @Model.QuizHeader.QuizSummary
        </div>

        @using (Html.BeginForm("SubmitQuiz", "Quiz", FormMethod.Post, new { id = "takeQuizForm" }))
        {
            @Html.AntiForgeryToken()

            @Html.ValidationSummary(true, "", new { @class = "text-danger" })
            @Html.HiddenFor(model => model.QuizHeader.QuizID)
            @Html.HiddenFor(model => model.QuizHeader.TopicID);
            <input type="hidden" name="QuizTakenComplete.UserID" id="QuizTakenComplete.UserID" value="@(ViewBag.UserID)" />
            <input type="hidden" name="QuizTakenComplete.IsComplete" id="QuizTakenComplete.IsComplete" value="false" />

            <!--Questions/Answers-->

            for (int i = 0; i < @Model.QuizHeader.QuizQuestions.Count(); i++)
            {
                <div class="quizQuestionBlock@(i)">
                    <hr />
                    <h4>@Model.QuizHeader.QuizQuestions.ElementAt(i).Question</h4>
                    <form-group>
                        <input type="hidden" name="QuizSubmittedAnswers[@(i)].QuestionID" id="QuizSubmittedAnswers[@(i)].QuestionID" value="@(Model.QuizHeader.QuizQuestions.ElementAt(i).QuestionID)">
                        @{for (int j = 0; j < Model.QuizHeader.QuizQuestions.ElementAt(i).QuizAnswers.Count(); j++)
                        {

                        <!--answers via radio buttons-->
                            <div id="answer@(j)@(i)" class="quizAnswer@(j)">
                                <input type="radio" class="individualQuizAnswer" name="QuizSubmittedAnswers[@(i)].AnswerID" value="@Model.QuizHeader.QuizQuestions.ElementAt(i).QuizAnswers.ElementAt(j).AnswerID"> @Model.QuizHeader.QuizQuestions.ElementAt(i).QuizAnswers.ElementAt(j).Answer
                            </div>

                        }

                        }
                    </form-group>
                </div>
            }
            <hr />
            <button class="btn btn-success btn-block disabled" id="saveAndSubmitQuizButton" type="button">submit quiz</button>
            <div style="text-align:center;">
                <small> Submitting quiz will finalize this attempt and update your score records.</small>
            </div>
            <br />
            <br />

        }

    </div>


    <!--Sidebar-->
    <div class="container col-xs-3 col-sm-3 col-md-3 col-lg-3">
        <div class="panel panel-default">
            <div class="panel-heading collapsable">
                <h5><span class="glyphicon glyphicon-cog"></span> Actions</h5>
            </div>
            <div class="panel-body">
                <span class="glyphicon glyphicon-backward"></span> @Html.ActionLink("return to library", "Index", new { controller = "Library" })<br />
                @Html.ActionLink("cancel/go home", "Index", new { controller = "Home" }, new { @style = "color:red;" })
            </div>
        </div>
    </div>

    <!--Quiz Save/Quit-->
    <div id="quizSave">
        <div id="quizSaveText" style="display:none;">
            Save current answers and return to App training/quiz library?<br />
            <button type="button" id="saveQuizOnlyButton" class="btn btn-success">yes</button>
            <button type="button" data-toggle="tooltip" class="btn btn-danger" title="this will cancel all previous work without saving and return to the main menu">no</button>
            <br />
            <small>You will be able to return later to resume your work.</small>
        </div>
    </div>
</div>

控制器

//POST: Quiz/SubmitQuiz
[HttpPost]
public async Task<ActionResult> SubmitQuiz(string quizObject)
{
    //Send false value for complete in AJAX call, just parse based on this
    //Two starting JS scripts, which flow into a unified function

    var input = new JavaScriptSerializer().Deserialize<QuizTakenObject>(quizObject);

    var quizTakenComplete = new QuizTakenComplete
    {
        UserID = input.quizTakenComplete.UserID,
        IsComplete = input.quizTakenComplete.IsComplete,
        LastUpdate = DateTime.Now
    };

    //Parse if complete for purposes of updating records.
    if (quizTakenComplete.UserID != null || quizTakenComplete.UserID != "")
    {
        db.QuizTakenComplete.Add(quizTakenComplete);
        await db.SaveChangesAsync();

        var quizAttemptID = quizTakenComplete.QuizAttemptID;

        //Now Add Each Answer

        var quizTaken = new QuizSubmittedAnswers();
        quizTaken.QuizAttemptID = quizAttemptID;
        quizTaken.TopicID = input.Topic.TopicID;
        quizTaken.QuizID = input.QuizHeader.QuizID;



        return Content("Saved");
    }

    else
    {
        return Content("Not Saved");
    }

 }

1 个答案:

答案 0 :(得分:3)

我认为问题出在Ajax Call中,你没有指定属性名称 试试这个

$.ajax({
                type: "POST",
                url: "SubmitQuiz",
                data: {quizObject : JSON.stringify(array)},
                dataType: "json",
                contentType:"application/json; charset=UTF-8",

                success: function (data) {
                    console.log("Success!");
                },

                error: function () {
                    console.log("Error");
                }
            });