Использование атрибута Bind в классе ViewModel в ASP.NET MVC

Почему разработчик может использовать атрибут Bind для объекта ViewModel в проекте ASP.NET MVC и может ли это иметь вредный эффект для приложения?

[Bind(Include = "Id,Name")]
[MetadataType(typeof (MyViewModelValidation))]
public class MyViewModel
{
    public string CustomerProductUserName { get; set; }

    [Display(Name = "Name")]
    public string Name { get; set; }

}

public class MyViewModelValidation
{
    [HiddenInput(DisplayValue = false)]
    public int Id { get; set; }

    [Required]
    public string Name{ get; set; }
}

Ответы

Ответ 1

Прежде всего, вам не нужно создавать класс MetadataType для ViewModel. Атрибуты аннотации данных можно использовать непосредственно в ViewModel. MetadataType используются для моделей, автоматически генерируемых EF или другими ORM, поэтому вы можете использовать атрибуты аннотации данных, не касаясь автоматически сгенерированного кода.

Атрибут Bind также не должен использоваться - если вы не хотите использовать свойства Include или Exclude атрибута Bind, чтобы включать или исключать свойства в вашей модели в или из привязки соответственно.

Например, в коде вашего вопроса будут отображаться только свойства Id и Name при отправке вашей модели из вашего представления. Даже если у вас есть вход в вашем представлении для CustomerProductUserName, когда вы отправляете свою форму, свойство всегда будет равно null. Это может быть полезно в таких случаях, когда вы не хотите, чтобы поле с автогенератором было включено в привязку.

Свойства, исключенные из привязки, также исключаются из проверки, поскольку проверка выполняется как часть привязки модели. Кроме того, вы можете использовать атрибут Bind по соображениям безопасности; например, когда вы хотите удостовериться, что ничего не происходит, кроме свойств в вашей модели.

Ответ 2

Цель использования атрибута bind заключается в том, чтобы запретить злоумышленнику присваивать значение свойства при отправке запроса или контролировать, какие свойства вы хотите привязать.

Предположим, у вас есть класс под названием Member и метод create, который сохраняет член. Но вы не хотите, чтобы пользователь посылал значение для свойства MemberType.

Class Member  
{  
    public int MemberId { get; set; }  
    public string FirstName { get; set; }  
    public string LastName { get; set; }  
    public string MemberType { get; set; }  
}  

[HttpPost]  
Public ActionResult Create(Member member)  
{  
    Save(member);  
}

Скажем, теперь вы предлагаете только обычный тип члена, который является значением по умолчанию. Вы можете подумать, что вы можете запретить пользователю отправлять значение для свойства MemberType, не допуская ввода для MemberType Property. Но когда пользователь отправляет объект-член, злоумышленник может перехватить запрос и отправить значение MemberType в запрос, так как MemberId=1&FirstName=Chandra&LastName=Malla&MemberType=Premium и сохраните член как член Премиум. Чтобы предотвратить это, вы можете украсить класс Member атрибутом Bind.

[Bind(Include="MemberId,FirstName,LastName")]  
Class Member  
{
    ...

или

[Bind(Exclude="MemberType")]  
Class Member  
{  
    ...

Теперь, если объект Member отправлен, значение свойства MemberType не будет опубликовано.

Если вы используете ViewModel, вам необязательно будет использовать атрибут bind, потому что вы можете опустить свойства MemberType в ViewModel.

Class Member  
{  
    public int MemberId { get; set; }  
    public string FirstName { get; set; }  
    public string LastName { get; set; }  
    public string MemberType { get; set; } 
}  

Class MemberViewModel  
{       
    public int MemberId { get; set; }   
    public string FirstName { get; set; }  
    public string LastName { get; set; }  
}  

[HttpPost]  
Public ActionResult Create(MemberViewModel memberviewmodel)  
{  
    Save(memberviewmodel);  
}

Если вы не хорошо проектируете свою модель и/или ViewModel и не используете атрибут связывания, чтобы избежать публикации свойства, которое вы не хотите, это может иметь пагубный эффект.

Ответ 3

Вы можете использовать атрибут Bind, чтобы управлять тем, как привязка модели преобразует запрос в объект. Наиболее распространенным способом использования атрибута Bind является исключить свойство Id из привязки. Например, таблица базы данных лиц включает столбец с именем Id это столбец Identity. Поскольку значение столбца Identity генерируется базы данных автоматически, вы не хотите связывать поле формы с этим свойством.

С другой стороны, представьте, что свойство модели особенно чувствительно, что вредоносный пользователь может просто добавить в URL-адрес при отправке формы. Если это было сделано, модельное связующее будет с радостью обнаруживать и использовать значение данных в процессе связывания. По атрибуту Bind вы можете защитить свое приложение от такого рода атак.

Использование атрибута Bind может привести к проблемам (задачам), когда вы, например, собираетесь обновлять объект, а идентификатор вам очень важен.