Use BindProperty Attribute for Model Binding to Properties
Model binding allows you map request parameters to actions. This means action
methods will have one or more parameters and those parameters will receive their
values from the model binding framework. Model binding can be performed to
simple types as well as complex types. In ASP.NET Core 2.0 you can perform model
binding to properties in addition to action parameters. This article explains
how.
Consider the following <form> from an ASP.NET Core view :
<form asp-action="Process"
asp-controller="Home" method="post">
<input name="Name" />
<input name="Age" />
<button type="submit">Submit</button>
</form>
Above form is POSTed to the Process() action of HomeController. It contains
two textboxes - Name and Age - for entering the respective values. In order to
grab the values entered by the user using model binding you can write the
Process() action like this :
public IActionResult Process(string name, int age)
{
ViewBag.Name = name;
ViewBag.Age = age;
return View();
}
Here you used model binding with simple types (string and int).
If you want you can wrap the Name and Age into a class :
public class Person
{
public string Name { get; set; }
public string Age { get; set; }
}
And then modify Process() action to use the Person type :
public IActionResult Process(Person p)
{
ViewBag.Name = p.Name;
ViewBag.Age = p.Age;
return View();
}
If you output the Name and Age ViewBag properties on the Process view you
will get the textbox values as expected.
So far so good. Now imagine that your HomeController takes this form :
public class HomeController : Controller
{
public string Name { get; set; }
public string Age { get; set; }
public IActionResult Index()
{
return View();
}
public IActionResult Process()
{
...
...
return View();
}
}
In this case the HomeController has two properties - Name and Age. And the
Process() no longer takes any parameter. You wish to fill these properties
through model binding.
If you run the application in its current form and observe the Name and Age
properties after the form submission you will see this :

As you can see both the properties are null. This means model binding hasn't
filled them by default.
Now change the HomeController as shown below :
public class HomeController : Controller
{
[BindProperty]
public string Name { get; set; }
[BindProperty]
public string Age { get; set; }
...
...
}
As you can see, the Name and Age properties are now decorated with [BindProperty]
attribute. The [BindProperty] is an instruction to the model binding framework
to bind the underlying property with the matching request parameter. If you run
the application this time you will see this :

This time model binding did its job and filled the controller properties with
the textbox values.
Once model binding to properties is in place, you can change Process() like
this :
public IActionResult Process()
{
ViewBag.Name = this.Name;
ViewBag.Age = this.Age;
return View();
}
Process() no longer takes any parameters and you directly use the Name and
Age properties.
You can also use [BindProperty] with complex types. Consider the following
code :
public class HomeController : Controller
{
[BindProperty]
public Person PersonData { get; set; }
...
...
}
The PersonData property is of type Person (the class you created earlier) and
is decorated with [BindProperty] attribute. In this case Name and Age properties
of Person will be filled with the textbox values.

And now your Process() will look like this :
public IActionResult Process()
{
ViewBag.Name = this.PersonData.Name;
ViewBag.Age = this.PersonData.Age;
return View();
}
Properties of BindPropertyAttribute class
There are a couple of properties of [BindProperty] attribute that are useful
in certain cases - Name and SupportsGet.
By default the model binding logic maps the form field names and the property
names. If their is no match found the property doesn't get assigned any value.
For example, a textbox named Name should have a property named Name for model
binding to work as expected. If the property name is different than the form
field name you can use the Name property of [BindProperty]. Here is an example :
[BindProperty(Name ="Name123")]
The above usage ensures that a textbox named Name123 is bound with the Name
property of HomeController.
By default model binding works for POST requests. If you are using GET for
submitting a form, you can use the SupportsGet property. Here is how you can use
it :
[BindProperty(SupportsGet = true)]
[BindProperty] in Razor Pages
In the above example you used [BindProperty] with ASP.NET Core MVC
application. You can also use [BindProperty] with Razor Pages. In fact [BindProperty]
is more commonly used in Razor Pages to bind form values to page model
properties. Let's see how.
Suppose you have two Razor pages - Index.cshtml and Process.cshtml. The
<form> housed in the Index.cshtml looks like this :
<form asp-page="Process" method="post">
<input name="Name" />
<input name="Age" />
<button type="submit">Submit</button>
</form>
Notice the use of asp-page attribute to post the values to Process.cshtml.
The code-behind of Process.cshtml will house the ProcessModel class. This
class is shown below :
public class ProcessModel : PageModel
{
[BindProperty]
public string Name { get; set; }
[BindProperty]
public string Age { get; set; }
public IActionResult OnPost()
{
ViewData["Name"] = this.Name;
ViewData["Age"] = this.Age;
return Page();
}
}
The ProcessModel class has two properties Name and Age that are model bound
using [BindProperty] attribute. The OnPost() method then uses the Name and Age
properties to fill the ViewData dictionary.
If you want to use Person complex type the ProcessModel will look like this :
public class ProcessModel : PageModel
{
[BindProperty]
public Person PersonData { get; set; }
public IActionResult OnPost()
{
ViewData["Name"] = this.PersonData.Name;
ViewData["Age"] = this.PersonData.Age;
return Page();
}
}
Here you used PersonData property and decorated it with [BindProperty]. The
OnPost() method now uses PersonData to fill the ViewData dictionary.
That's it for now! Keep coding !!