2

I'm new to ASP .Net Core 1.0 and I'm trying to bind a view to a model that contains a collection of same object. The main model is a questionnaire and may contain any count of questions with different types. But my problem is inside the ActionResult method, my List property is always null during post.

This is the form:

<form id="mainForm" asp-controller="Default" asp-action="PersonalDetails" asp-route-sectionTypeCode="@Model.SectionTypeCode" asp-route-sectionNumber="@Model.SectionNumber" method="post" asp-anti-forgery="false">
        @{
            for (Int32 i = 0; i < Model.Questions.Count; i++)
            {
                string spacerValue = "";
                if (i == Model.Questions.Count - 1)
                {
                    spacerValue = "extraLargeSpacerBottom";
                }
                <div class="form-group @spacerValue">
                    <label>@Model.Questions[i].QuestionTitle</label>
                    @{
                        switch (Model.Questions[i].QuestionTypeCode)
                        {
                            case 1:
                                <input asp-for="Questions[i].Value" class="form-control appInput" type="text">
                                break;

                            case 2:
                                <input asp-for="Questions[i].Value" class="form-control appInput" type="number">
                                break;

                            case 3:
                                <select asp-for="Questions[i].Value" class="form-control appInput" asp-items="Model.Questions[i].QuestionOptions"></select>
                                break;

                            case 4:
                                <input asp-for="Questions[i].Value" class="form-control appInput" type="date">
                                break;

                            case 5:
                                <div>
                                    <label class="radio-inline">
                                        <input asp-for="Questions[i].Value" value="true" type="radio"><span class="radioSpace">Yes</span>
                                    </label>
                                    <label class="radio-inline">
                                        <input asp-for="Questions[i].Value" value="false" type="radio"><span class="radioSpace">No</span>
                                    </label>
                                </div>
                                break;

                            case 6:
                                <input asp-for="Questions[i].Value" class="form-control appInput" type="number">
                                break;
                        }
                    }
                </div>
            }
        }
    </form>

And this is the _Question class:

public class _Question
{
    #region Properties
    public string QuestionTitle { get; private set; }
    public string QuestionHelp { get; private set; }
    public Int32 QuestionTypeCode { get; private set; }
    public string ValidationMessage { get; private set; }
    public List<SelectListItem> QuestionOptions { get; private set; }

    public dynamic Value { get; set; }
    #endregion

    public _Question() { }

    public _Question(Int32 questionTypeCode, string questionTitle, string questionHelp, List<SelectListItem> options = null)
    {
        QuestionTypeCode = questionTypeCode;
        QuestionTitle = questionTitle;
        QuestionHelp = questionHelp;
        QuestionOptions = options;

        switch (questionTypeCode)
        {
            case 1:
                ValidationMessage = "Please enter a text value";
                break;

            case 2:
                ValidationMessage = "Please enter a numeric value";
                break;

            case 4:
                ValidationMessage = "Please enter a date value";
                break;

            case 6:
                ValidationMessage = "Please enter a currency value";
                break;
        }
    }
}

The main model contains a list of _Question objects that are being generated at runtime from a database.

Can anybody please help me about my null result?

1
  • Have you find your answer? if yes please mark accordingly Commented Jul 13, 2017 at 9:59

2 Answers 2

1

How is your controller set up? From what I've done with model binding, the controller needs to be set up a certain way to coincide with a model (or view model) to accept the post data. Basically you want to make sure everything in the model lines up exactly in name with the post data.

For example:

View Model:

public class ExampleCustomerViewModel
{
    public string[] CustomerTypes { get; set; }
    public bool Address { get; set; }
    public bool City { get; set; }
    public bool County { get; set; }
    public bool ProvinceState { get; set; }
    public bool Country { get; set; }
    public bool PostalZip { get; set; }
}

And then the controller:

    [HttpPost]
    public IActionResult ExampleAction(ExampleCustomerViewModel viewModel)
    {
        if (!ModelState.IsValid)
            return BadRequest();

        viewModel.DoWhatever();

        return PartialView("~/Sites/ExampleCustomer.cshtml", viewModel);
    }

And then I used some jQuery:

     function performCustomerInitialization() {

    //Dummy code where I am get the values I want from the form into JSON. 
                formParameters = {
                    CustomerTypes: customerTypes,
                    Address: $("#Address").prop("checked") === true,
                    City: $("#City").prop("checked") === true,
                    County: $("#County").prop("checked") === true,
                    ProvinceState: $("#ProvinceState").prop("checked") === true,
                    Country: $("#Country").prop("checked") === true,
                    PostalZip: $("#PostalZip").prop("checked") === true

                };

            $.ajax({
                url: "ExampleAction",
                type: "POST",
                async: true,
                data: formParameters,
                dataType: "html",
                success: function (results) {
                    $(resultsDiv).empty().append(results);
                    console.log(formParameters);
                },
                error: function () {
                    $(resultsDiv).empty().append("<div class='box-body'><br/><p><em>An error occurred.</em></p><br/></div></div>");
                }
            });
        }

Hopefully that helps point you in the right direction!

Sign up to request clarification or add additional context in comments.

Comments

1

Model binding does not work with private set. Setter must be public so that MVC can set the values in the postback

public class _Question
{
    #region Properties
    public string QuestionTitle { get; private set; }
    public string QuestionHelp { get; private set; }
    public Int32 QuestionTypeCode { get; private set; }
    public string ValidationMessage { get; private set; }
    public List<SelectListItem> QuestionOptions { get; private set; }
    //...
}

You can find more details about the model binding here

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.