【问题标题】:Difference between之间的区别
【发布时间】:2014-11-22 15:30:06
【问题描述】:

我正在通过电子邮件和密码创建一个简单的登录页面。我有一个类 LoginViewModel ,其中将有一个 User 类作为成员变量。该类包含电子邮件地址。密码在主 LoginViewModel 中。我的用户类参考是这样的:

public User User { get; set; }

当用户填写电子邮件地址和密码并点击提交时,LoginViewModel 将字段正确绑定到视图中 User 类中的电子邮件地址:

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

如果我让上面的代码看起来像这样,我想知道为什么它不起作用:

public User User = new User();

它将用户实例中的电子邮件显示为空值。我知道使用构造函数可能比两者都好,但是这两者有什么区别。

编辑#1: 在“登录”操作方法中发布时,会找到我为模型中的电子邮件字段输入的值:

public User User { get; set; }

这个没有:

public User User = new User(); // --> because of this email field value shows up null

【问题讨论】:

  • @GrantWinney 我认为 OP 意味着在表达式映射中使用公共字段,而不是属性。
  • 您的编辑确实表明我的答案不是您想要的。我已将其删除:我不知道如何将其编辑为可以回答您问题的表单,并且当问题显示没有很好的答案时,其他人更有可能自己尝试。

标签: c# asp.net-mvc model-binding


【解决方案1】:

这是DefaultModelBinder 的一个功能,它只会将属性与公共getter/setter 绑定。如果您浏览源代码,该过程包括初始化模型的新实例,然后尝试设置其属性的值。这里的关键部分是

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
    ...
  }
  ...
}

当您使用public User User = new User(); 时,您只创建一个字段,其PropertyDescriptorIsReadOnly 属性将返回false,因此if 块中的代码永远不会执行,User.Email 的值是nullstring 的默认值)

【讨论】:

  • 这正是我一直在寻找的……很高兴参与你的突破 10K 大关!
【解决方案2】:
I want to know why it doesn't work if I had the code above looked like this instead:

public User User = new User();

因为基础架构会查找 set 方法。它需要是具有公共设置器的属性。

@Stephen 提供的代码平静并没有描述问题的核心。 这是DefaultModelBinder 尝试绑定模型属性的方法。

private void BindProperties(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
     IEnumerable<PropertyDescriptor> properties = GetFilteredModelProperties(controllerContext, bindingContext);
     foreach (PropertyDescriptor property in properties)
     {
          BindProperty(controllerContext, bindingContext, property);
     }
}

在这里我们看到GetFilteredModelProperties 试图通过方法调用链获得PropertyDescriptor,最终通过方法调用TypeDescriptor.GetProperties 返回类型的属性而不是字段。

【讨论】:

  • 哇...,cmets 在哪里?
  • 我不同意这个评级;这个答案实际上可能有用。你能详细说明你的答案@hamlet吗?谁的基础设施? C# 还是 MVC?
  • 我不同意这一点。如果一个字段应该是公共的,它实际上并不需要set。不过,我知道使用 { get; set; } 方法并创建属性是一个好习惯。
  • @ZikO,你的直觉不重要!你试过了吗?
  • @user1019042,ASP.NET MVC。
猜你喜欢
  • 1970-01-01
  • 2021-12-25
  • 2020-05-10
  • 2014-09-20
  • 2010-10-28
  • 2015-10-04
  • 2012-08-12
  • 2011-02-18
  • 2019-12-21
相关资源
最近更新 更多