Home > Software engineering >  ASP.NET Core Partialview does not bind to the class with formserialize
ASP.NET Core Partialview does not bind to the class with formserialize

Time:01-16

I want to create a Quiz, add questions to the quiz, and add answers to the question. I bound all items with asp-for, serialize my form, and send it to the controller, but they don't bind.

My classes:

    public class Answer
    {
        [Key]
        public Guid Id { get; } = Guid.NewGuid();
        public string Content { get; set; }
        public Guid QuestionId { get; set; }
    }
    public class Question
    {
        [Key]
        public Guid Id { get; } = Guid.NewGuid();
        public string Content { get; set; }
        public Guid QuizId { get; set; }
        public ICollection<Answer> Answers { get; set; } = new List<Answer>() { 
            new Answer() { Content = "Answeeeer" }, 
            new Answer() { Content = "Answeeeer2" },
            new Answer() { Content = "Answeeeer3" }
        };
    }
    public class Quiz
    {
        [Key]
        public Guid Id { get; } = Guid.NewGuid();
        public string Name { get; set; }
        public ICollection<Question> Questions { get; set; } = new List<Question>() { };
    }

Quiz view:

@model QuizIt_Tests.Entities.Quiz

@{
ViewData\["Title"\] = "Create";
}

\<h1\>Create\</h1\>

\<h4\>Quiz\</h4\>
\<hr /\>
\<div \>
\<div \>
\<form id="myform" asp-action="Create" method="post" \>

            <div >
                <label asp-for="Name" >Quiz Name</label>
                <input asp-for="Name"  />
                <span asp-validation-for="Name" ></span>
            </div>
    
            <div id="questionRows" >
                @Html.EditorFor(model => model.Questions)
                <button type="button" id="AddQuestion" >Add Question</button>
            </div>
    
            <div >
                input id="submitbutton" type="submit" value="Create"  />
            </div>
        </form>
    </div>

\</div\>

\<div\>
    \<a asp-action="Index"\>Back to List\</a\>
\</div\>

@section Scripts {
@{
await Html.RenderPartialAsync("\_ValidationScriptsPartial");
}

    <script>
    
        $("#submitbutton").click(function (e) {
            e.preventDefault();
    
            console.log("Serialized Data: ");
            console.log($('#myform').serialize())
    
            $.ajax({
                async: true,
                data: $('#myform').serialize(),
                method: 'post',
                url: "Quizes/AddQuestion",
                success: function () {
                }
            });
    
        });
    
        $("#AddQuestion").click(function () {
    
            console.log("Serialized Data: ");
            console.log($('#myform').serialize())
            console.log($('#questionRows').serialize())
    
            $.ajax({
                url: '@Url.Action("AddBlankQuestion", "Quizes")',
                cache: false,
                success: function (html) { $("#questionRows").append(html); },
                error: function (xhr, status, error) {
                    console.log(xhr.responseText);
                }
            });
            return false;
        });
    
        $("a.deleteRow").on("click", function () {
            $(this).parents("div.editorRow:first").remove();
            return false;
        });
    </script>

}

Question partial view:


@model QuizIt_Tests.Entities.Question

\<hr style="height: 4px; color: black;" /\>
\<div \>

    <div >
        <label asp-for="Content" >Question</label>
        <input asp-for="Content"  value="@Model.Content" />
        <span asp-validation-for="Content" ></span>
    </div>
    <input type="hidden" asp-for="Id"  value="@Model.Id" />
    
    @{
        var answerrowid = "answerRows"   @Model.Id;
        var addanswerbtnid = "addAnswer"   @Model.Id;
    }
    <div id="@answerrowid" >
        @Html.EditorFor(model => model.Answers)
    </div>
    <button type="button"  id="@addanswerbtnid">Add Answer</button>

\</div\>

<script>

    console.log("#@addanswerbtnid");
    $("#@addanswerbtnid").click(function () {
        console.log("Add Answer clicked");
        $.ajax({
            url: '@Url.Action("AddBlankAnswer", "Quizes")',
            cache: false,
            success: function (html) {
                $("#@answerrowid").append(html);
            },
            error: function (xhr, status, error) {
                console.log(xhr.responseText);
            }
        });
        return false;
    });

</script> 

Answer partial view:

@model QuizIt_Tests.Entities.Answer

\<div  style="margin: 20px;"\>

    <div asp-validation-summary="ModelOnly" ></div>
    
    <div >
        <label asp-for="Content" >Answer Content</label>
        <input asp-for="Content"  value="@Model.Content" />
        <span asp-validation-for="Content" ></span>
    </div>
    
    <input type="hidden" asp-for="Id"  value="@Model.Id" />

\</div\>

This is my controller:

    public class QuizesController : Controller
    {
        private readonly ApplicationDBContext _context;

        public QuizesController(ApplicationDBContext context)
        {
            _context = context;
        }

        public async Task<IActionResult> Index()
        {
            return View(await _context.Quizzes.ToListAsync());
        }

        public IActionResult Create()
        {
            var newquiz = new Quiz();
            return View(newquiz);
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Create(Quiz quiz)
        {
            if (ModelState.IsValid)
            {
                _context.Add(quiz);
                await _context.SaveChangesAsync();
                return RedirectToAction(nameof(Index));
            }
            return View(quiz);
        }

        public IActionResult AddBlankQuestion(Quiz model)
        {
            Question question = new Question();
            //question.Answers.Add(new Answer() { QuestionId = question.Id, Content = "Salaaam Necesem" });
            return PartialView("EditorTemplates/Question", question);
        }
        public IActionResult AddBlankAnswer(Question model)
        {
            var newanswer = new Answer() { QuestionId = model.Id, Content = String.Empty };
            return PartialView("EditorTemplates/Answer", newanswer);
        } 
    }

I want to create a Quiz, add questions to the quiz, and add answers to the question. I bound all items with asp-for, serialize my form, and send it to the controller, but they don't bind.

CodePudding user response:

public ICollection Questions { get; set; }

You don't bind Content to your list ICollection<Question> Questions , so the Questions list is null.

You need to set name like name="Questions[0].Content" and name="Questions[1].Content".

  • Related