Search code examples
javascriptjqueryasp.net-corerazor

Model not binding razor page .net 6


This is my code in the view:

<p class="lead">Les invités</p>
        <div class="d-flex justify-content-end mb-1">
            <button id="addRow" type="button" class="btn btn-outline-dark ms-auto">Ajouter une personne</button>
        </div>
        <table class="w-100 mb-5" id="newRow">
            <tr>
                <th>Prénom</th>
                <th>Nom de famille</th>
                <th></th>
            </tr>
            <tr>
                <td>
                    <input type="text" class="form-control d-table-cell" asp-for="Participation.Participants[0].Prenom" />
                    <span class="text-danger" asp-validation-for="Participation.Participants[0].Prenom"></span>
                </td>
                <td>
                    <input type="text" class="form-control d-table-cellead" asp-for="Participation.Participants[0].Nom" />
                    <span class="text-danger" asp-validation-for="Participation.Participants[0].Nom"></span>
                </td>
                <td></td>
            </tr>
        </table>

The script:

@section Scripts
    {
    <script>
        var rowCount = 1;

        function updateDeleteButtons() {
            $('#newRow tr').each(function (index) {
                if (index === rowCount) {
                    $(this).find('#removeRow').show();
                } else {
                    $(this).find('#removeRow').hide();
                }
            });
        }

        $("#addRow").click(function () {
            var html = '';
            html += '<tr id="inputRow">';
            html += '<td>';
            html += '<input type="text" class="form-control d-table-cell" asp-for="Participation.Participants[' + (rowCount) + '].Prenom" />';
            html += '<span class="text-danger" asp-validation-for="Participation.Participants[' + (rowCount) + '].Prenom"></span>';
            html += '</td>';
            html += '<td>';
            html += '<input type="text" class="form-control d-table-cell" asp-for="Participation.Participants[' + (rowCount) + '].Nom" />';
            html += '<span class="text-danger" asp-validation-for="Participation.Participants[' + (rowCount) + '].Nom"></span>';
            html += '</td>';
            html += '<td>';
            html += '<button id="removeRow" type="button" class="btn btn-danger">Supprimer</button>';
            html += '</td>';
            html += '</tr>';

            $('#newRow').append(html);
            rowCount++;
            updateDeleteButtons();
        });

        $(document).on('click', '#removeRow', function () {
            $(this).closest('#inputRow').remove();
            rowCount--;
            updateDeleteButtons();
        });
    </script>
} 

My model:

[BindProperty]
public AjouterParticipationRequete Participation { get; set; }

And the definition:

public class AjouterParticipationRequete
{
    [Required(ErrorMessage = "Vous devez identifier votre famille dans «Participants» (1 membre minimum).")]
    public List<ParticipantDto> Participants { get; set; }
    public List<SelectionMenuDto>? SelectionMenu { get; set; }
    public string? IndicationAllergies { get; set; }
    public string? Commentaire { get; set; }
}

My problem is that when I add a new Participant (guest), It doesn't work. It is like the Participation.Participants[0] is working but when I add new like Participation.Participants[1], it is not binding the value.

Do you know wheree is my error?


Solution

  • html += '<input type="text" class="form-control d-table-cell" asp-for="Participation.Participants[' + (rowCount) + '].Prenom" />';
    

    You can't just use JavaScript to add tag helpers like asp-for, asp-validation-for in html.

    When you use asp-for="xx" in your razor page, asp-for="xx" will be translated to name="xx" and id="xx" in html. It also sets the value of the input element if there is already a value within the model passed to the view. In your case, If you just use js to add asp-for="xx" in html directly, It will not be translated to name="xx", id="xx", Model Binding based on the name of property, So it will not bind value successfully.

    You need to add name instead of asp-for property to bind the value in javascript, change your code like:

    html += '<input type="text" class="form-control d-table-cell" name="Participation.Participants[' + (rowCount) + '].Prenom" />';