需要具有Bind属性的MVC操作方法的指南

时间:2013-10-21 08:59:49

标签: c# asp.net-mvc asp.net-mvc-3

我正在浏览一个动作方法代码,我看到有一个属性在那里使用,但我真的不明白使用。这是代码

public ActionResult User([Bind(Include = "Username,FullName,Email")]User user)
{
   if (!ModelState.IsValid()) return View(user);

   try
   {
     user.save()
     // return the view again or redirect the user to another page
   }
   catch(Exception e)
   {
     ViewData["Message"] = e.Message;
     return View(user)
   }
}

([Bind(Include = "Username,FullName,Email")]User user)

我只是不明白上面的行Bind include etc

所以请帮助我理解这种使用的属性&当人们在mvc中编写这种代码时。如果有人让我理解他们将使用此Bind attribute的示例小代码,这将是非常好的帮助。

更新 假设我有表单,用户只能输入FirstName,LastName&性别然后我的行动方法看起来像

public ActionResult Edit(string FirstName,string LastName,string Gender)
{
    // ...
}

我认为这会奏效。那么为什么我应该使用绑定属性,因为我的上述操作方法将正常工作。

3 个答案:

答案 0 :(得分:83)

Bind属性允许您“微调”某个参数Type的模型绑定过程,而无需注册特定于Type的自定义ModelBinder

例如,假设您的Action期望Person参数定义如下:

public class Person
{
    public Person(string firstName, string lastName, Gender gender)
    {
        this.FirstName = firstName;
        this.LastName = lastName;

        if (gender == Gender.Male)
            this.FullName = "Mr. " + this.FirstName + " " + this.LastName;
        else
            this.FullName = "Mrs. " + this.FirstName + " " + this.LastName;
    }

    public string FirstName { get; set; }
    public string LastName { get; set; }
    public Gender Gender { get; set; }

    // 'FullName' is a computed column:
    public string FullName { get; set; }
}

动作:

public ActionResult Edit(Person person)
{
    ...
}

现在,如果有人发布了以下JSON:

{
    "FirstName":"John",
    "LastName":"Smith",
    "Gender":"Male",
    "FullName":"Mrs. John Smith"
}

您的行动现在将person错误FullName('太太'代替'先生')。

要避免此类行为,您可以使用Bind属性并在绑定过程中明确排除FullName属性('黑名单'):

public ActionResult Edit([Bind(Exclude="FullName")] Person person)
{
    ...
}

或者,您可以使用Include忽略('黑名单')所有属性,并仅包含('白名单')指定的属性:

public ActionResult Edit([Bind(Include="FirstName,LastName,Gender")] Person person)
{
    ...
}

有关MSDN的更多信息。

答案 1 :(得分:16)

执行此操作时,MVC模型绑定器将使用请求参数填充user参数的属性,您可能已经知道。但是,Bind属性告诉模型绑定器填充指定名称的属性。

因此,在这种情况下,只会填充UsernameFullNameEmail属性。所有其他人都将被忽略。

请点击此处了解详情:http://ittecture.wordpress.com/2009/05/01/tip-of-the-day-199-asp-net-mvc-defining-model-binding-explicitly/

答案 2 :(得分:2)

Bind属性是防止创建方案中过度发布的一种方法。例如,假设学生实体包含您不希望设置此网页的“秘密”属性。

public class Student
{
  public int ID { get; set; }
  public string LastName { get; set; }
  public string FirstMidName { get; set; }
  public DateTime EnrollmentDate { get; set; }
  public string Secret { get; set; }

  public virtual ICollection<Enrollment> Enrollments { get; set; }
}

即使您在网页上没有Secret字段,黑客也可以使用fiddler等工具或编写一些JavaScript来发布Secret表单值。如果没有Bind属性限制模型绑定器在创建Student实例时使用的字段,则模型绑定器将获取该Secret表单值并使用它来创建Student实体实例。然后,黑客为Secret表单字段指定的任何值都将在您的数据库中更新。下图显示了fiddler工具将Secret字段(值为#34; OverPost&#34;)添加到已发布的表单值。 价值&#34; OverPost&#34;然后将成功添加到插入行的Secret属性,尽管您从未打算该网页能够设置该属性。

将Include参数与Bind属性一起用于白名单字段是一种安全性最佳做法。也可以使用Exclude参数将要排除的字段列入黑名单。包含更安全的原因是,当您向实体添加新属性时,新字段不会被排除列表自动保护。