Need guide line for MVC action method with Bind attribute

C#asp.net Mvcasp.net Mvc-3

C# Problem Overview


I was going through a action method code and i saw one attribute was used there but i really did not understand the use. here is the code

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)

i just do not understand the above line Bind include etc

so please help me to understand this kind of attribute used & when people write this kind of code in mvc. it will be really good help if some one make me understand with sample small code where they will use this Bind attribute.

Update: Suppose i have form from where user can enter only FirstName,LastName & Gender then my action method looks like

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

this will work i think. then why i should use a Bind Attribute because my above action method will works fine.

C# Solutions


Solution 1 - C#

Bind attribute lets you "fine-tune" the model-binding process of certain parameter Type, without registering a custom ModelBinder specific to the Type.

For example, assume your Action is expecting a Person parameter defined as follows:

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

And the Action:

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

Now, if someone is posting the following JSON:

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

Your Action will now have a person with the wrong FullName ('Mrs' instead of 'Mr').

To avoid such behavior you can use the Bind attribute and explicitly exclude the FullName property from the binding process ('Black-list'):

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

Alternatively, you can use Include to ignore ('Black-list') all properties and only include ('White-list') the specified properties:

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

More info on MSDN.

Solution 2 - C#

When this action is executed the MVC model binder will use the request parameters to populate the user parameter's properties, as you may already know. However, the Bind attribute tells the model binder to only populate properties with names specified.

So in this case only the Username, FullName and Email properties will be populated. All others will be ignored.

See here for more details: http://ittecture.wordpress.com/2009/05/01/tip-of-the-day-199-asp-net-mvc-defining-model-binding-explicitly/

Solution 3 - C#

The Bind attribute is one way to protect against over-posting in create scenarios. For example, suppose the Student entity includes a Secret property that you don't want this web page to set.

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

Even if you don't have a Secret field on the web page, a hacker could use a tool such as fiddler, or write some JavaScript, to post a Secret form value. Without the Bind attribute limiting the fields that the model binder uses when it creates a Student instance, the model binder would pick up that Secret form value and use it to create the Student entity instance. Then whatever value the hacker specified for the Secret form field would be updated in your database. The following image shows the fiddler tool adding the Secret field (with the value "OverPost") to the posted form values. The value "OverPost" would then be successfully added to the Secret property of the inserted row, although you never intended that the web page be able to set that property.

It's a security best practice to use the Include parameter with the Bind attribute to whitelist fields. It's also possible to use the Exclude parameter to blacklist fields you want to exclude. The reason Include is more secure is that when you add a new property to the entity, the new field is not automatically protected by an Exclude list.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionThomasView Question on Stackoverflow
Solution 1 - C#haim770View Answer on Stackoverflow
Solution 2 - C#greg84View Answer on Stackoverflow
Solution 3 - C#user5967438View Answer on Stackoverflow