Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between

I am creating a simple login page by email and password. I have a class LoginViewModel that will have a User class as a member variable inside it. The class contains the emailAddress. The password is inside the main LoginViewModel. My User class reference is like this:

public User User { get; set; }

when the user fills the email address and password and hit submit, the LoginViewModel correctly binds the field to the email address inside the User class from the view:

@Html.TextBoxFor(m => m.User.Email) // m is the LoginViewModel model

I want to know why it doesn't work if I had the code above looked like this instead:

public User User = new User();

It shows the email inside the User instance as null value. I know that the use of the constructor is probably better than both, but what is the difference between these two.

EDIT#1: On posting at the "Login" action method, this finds the value I entered for the email field in the model:

public User User { get; set; }

this one does NOT:

public User User = new User(); // --> because of this email field value shows up null
like image 773
user1019042 Avatar asked Sep 18 '26 05:09

user1019042


1 Answers

This is a feature of the DefaultModelBinder which will only bind properties with public getter/setters. If you explore the source code, the process includes initializing a new instance of your model and then attempting to set the value of its properties. The key part here is

protected virtual void SetProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, object value)
{
  ...
  if (!propertyDescriptor.IsReadOnly && !isNullValueOnNonNullableType)
  {
    ...
    propertyDescriptor.SetValue(bindingContext.Model, value) // this is where the value is set
    ...
  }
  ...
}

When you use public User User = new User(); you only creating a field and the IsReadOnly property of its PropertyDescriptor will return false so the code in the if block is never executed and the value of User.Email is null (the default value for string)