Использование атрибута 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 может привести к проблемам (задачам), когда вы, например, собираетесь обновлять объект, а идентификатор вам очень важен.