Search code examples
c#asp.net-corerazorrazor-pages

BindProperty returning NULL OnPost


I am getting a null return for a BindProperty on a List I am using. I trimmed down my code to only what is relevant. when I call the OnPost method updatedData is null.

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using ProfileMaker.Classes;
using System.Security.Claims;

namespace ProfileMaker.Pages
{
    public class AdminBranchDetailsModel : PageModel
    {
        public List<BranchInfo> BranchContactDetails { get; set; } = new List<BranchInfo>();
        [BindProperty]
        public List<BranchInfo> updatedData { get; set; } = new List<BranchInfo>();
        [BindProperty]
        public BranchInfo newBranch { get; set; } = new BranchInfo();

        public void OnGet()
        {
            BranchContactDetails = SetBranchData();
            updatedData = BranchContactDetails;
            Console.WriteLine(updatedData.Count());
        }
        public IActionResult OnPostAddBranch() 
        {
            Console.WriteLine(updatedData.Count());
            return RedirectToPage();
        }
    }
}

As well, here is my BranchInfo class:

using Microsoft.EntityFrameworkCore;

namespace ProfileMaker.Classes
{
    public class BranchInfo 
    {
        public string whsNumber;
        public string whsName;
        public string whsAddress;
        public string whsCity;
        public string whsState;
        public string whsZip;
        public string whsDivision;
        public string whsGM;
        public string whsCountry;
        public string whsTimeZone;
        public int Index;
    }
}

Ah! Also the cshtml file as suggested:

@page
@model ProfileMaker.Pages.AdminBranchDetailsModel
@{
    @if(Model.bIsAdmin)
    {
        <form method="post">
            <table>
                <tr>
                    <td>Warehouse Number</td>
                    <td>Warehouse Address</td>
                    <td>Warehouse City</td>
                    <td>Warehouse State/Province</td>
                    <td>Warehouse Zip/Postal</td>
                    <td>Warehouse Division</td>
                    <td>Warehouse General Manager</td>
                    <td>Warehouse Country</td>
                    <td>Warehouse Timezone</td>
                </tr>
                @for (int i = 0; i < Model.updatedData.Count(); i++)
                {
                <tr>
                    <td><input type="text" asp-for="updatedData[i].whsNumber"/></td>
                    <td><input type="text" asp-for="updatedData[i].whsAddress" /></td>
                    <td><input type="text" asp-for="updatedData[i].whsCity"/></td>
                    <td><input type="text" asp-for="updatedData[i].whsState"/></td>
                    <td><input type="text" asp-for="updatedData[i].whsZip"/></td>
                    <td><input type="text" asp-for="updatedData[i].whsDivision"/></td>
                    <td><input type="text" asp-for="updatedData[i].whsGM"/></td>
                    <td><input type="text" asp-for="updatedData[i].whsCountry"/></td>
                    <td><input type="text" asp-for="updatedData[i].whsTimeZone"/></td>
                    <td><button asp-page-handler="RemoveBranch" asp-route-index="@i">Remove</button></td>
                </tr>
                }
                <tr>
                    <td><input type="text" value="Num" asp-for="newBranch.whsNumber" /></td>
                    <td><input type="text" value="Address" asp-for="newBranch.whsAddress" /></td>
                    <td><input type="text" value="City" asp-for="newBranch.whsCity" /></td>
                    <td><input type="text" value="State/Prov" asp-for="newBranch.whsState" /></td>
                    <td><input type="text" value="Zip/Postal" asp-for="newBranch.whsZip" /></td>
                    <td><input type="text" value="Div" asp-for="newBranch.whsDivision" /></td>
                    <td><input type="text" value="GM" asp-for="newBranch.whsGM" /></td>
                    <td><input type="text" value="Country" asp-for="newBranch.whsCountry" /></td>
                    <td><input type="text" value="Time Zone" asp-for="newBranch.whsTimeZone" /></td>
                    <td><button asp-page-handler="AddBranch">Add</button></td>
                </tr>
                <tr>
                    <td><button asp-page-handler="UpdateBranch">Update</button></td>
                </tr>
            </table>
        </form>
    }
    else
    {
        <h1>You do not have Admin permissions</h1>
    }
}

It successfully iterates through 23 entries and displays them correctly.


Solution

  • Please use properties instead of fields.

    public class BranchInfo
    {
        public string whsNumber { get; set; }
        public string whsName { get; set; }
        public string whsAddress { get; set; }
        public string whsCity { get; set; }
        public string whsState { get; set; }
        public string whsZip { get; set; }
        public string whsDivision { get; set; }
        public string whsGM { get; set; }
        public string whsCountry { get; set; }
        public string whsTimeZone { get; set; }
        public int Index { get; set; }
    }
    

    Demo

    enter image description here

    Targets | Model Binding in ASP.NET Core

    Model binding tries to find values for the following kinds of targets:

    • Public properties of a controller or PageModel class, if specified by attributes.