Use a class without instantiation in ASP. Net Razor Pages

Shervan360 1,661 Reputation points
2023-07-30T03:47:49.7033333+00:00

Hello,

I saw the following code in GitHub. Could you please explain how did use input variable without instantiation in the view file and page model? The country is OK because it was instantiated in OnPost method. I expected we would get the following error:

Object reference not set to an instance of an object.

<div>
     <form method="post">
          <label for="Input.CountryName">County Name: </label> 
          <input name="Input.CountyName" /> <br /> // used Input.CountryName without instantiation in PageModel

          <label for="Input.CountryCode">County Code: </label>
          <input name="Input.CountryCode" /> <br /> // used Input.CountryCode without instantiation in PageModel
          <input type="submit" value="Create" />
     </form>
</div>
namespace CityBreaks.Models
{
    public class Country
    {
        public string CountryName { get; set; }
        public string CountryCode { get; set; }
    }

}

using CityBreaks.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace CityBreaks.Pages.CountryManager
{
     public class CreateModel : PageModel
     {
          [BindProperty]
          public InputModel Input { get; set; }
          public Country Country { get; set; }

     
          public void OnPost()
          {
               Country = new Country
               {
                    CountryName = Input.CountryName, // use Input.CountryName without instantiation
                    CountryCode = Input.CountryCode // use Input.CountryName without instantiation
               };
          }

          public class InputModel
          {
               public string CountryName { get; set; }
               public string CountryCode { get; set; }
          }

     }
}

Developer technologies ASP.NET ASP.NET Core
{count} votes

Accepted answer
  1. AgaveJoe 1,510 Reputation points
    2023-07-31T11:27:55.06+00:00

    but in the following example I have List<int> and why should I instantiate with new List<int>()? Why doesn't the model binder instantiate the SelectedCities here?

    Model binding occurs when values are submitted to the Razor Page. It is not clear from your code sample if values are submitted to the City Razor Page.

    I can only assume the GitHub code you are reviewing, fetches the selected IDs from a database. Since model binding is not taking place in this scenario, the List<T> must be instantiated before populating List<T> elements.

    The model binder certainly has the ability to populate a List<T> when a collection is submitted as the example below illustrates.

        public class CityModel : PageModel
        {
            [BindProperty]
            public List<int> SelectedCities { set; get; }
    
            public List<City> Cities = new List<City>
              {
                 new City{ Id = 1, Name = "London"},
                 new City{ Id = 2, Name = "Paris" },
                 new City{ Id = 3, Name = "New York" },
                 new City{ Id = 4, Name = "Rome" },
                 new City{ Id = 5, Name = "Dublin" }
              };
    
            public void OnGet()
            {
            }
            public void OnPost()
            {
    
            }
        }
    
    @page
    @model RazorPagesDemo.Pages.CityModel
    
    <form method="post">
        <div>
            <select asp-for="SelectedCities" asp-items="@(new SelectList(Model.Cities, "Id", "Name"))" multiple>
                </select>
        </div>
        <div>
            <input type="submit" value="submit" />
        </div>
    </form>
    
    @{
    }
    
    1 person found this answer helpful.
    0 comments No comments

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.