При разработке сложных бизнес-приложений часто приходится сталкиваться с ситуацией, когда пользователям необходимо ограничить права на редактирование определенных данных.
В этой статье будет рассмотрен пример запрета изменения определенных свойств модели в приложении, разработанном в ASP.NET MVC.
Задача
Допустим, у нас есть модель клиента, содержащая его идентификатор, имя и идентификационный номер налогоплательщика.
Данные поступают на страницу в виде модели.public class ClientViewModel { public int Id { get; set; } public string Name { get; set; } public string Inn { get; set; } }
Выполнив необходимые действия, пользователь отправляет HTTP-запрос, который в качестве параметров содержит значения полей формы.
Перед вызовом метода Action, отвечающего за обработку запроса, DefaultModelBinder привязывает полученные из формы параметры к модели данных.
Все изменения, внесенные пользователем, отражаются в свойствах полученной модели.
А что, если некоторые свойства необходимо защитить от модификации, чтобы пользователь, не имеющий на это прав, случайно или со злым умыслом не смог нарушить целостность данных?! Для решения этой проблемы необходимо разработать механизм, который позволил бы определенным ролям пользователей запрещать изменение определенных свойств модели.
Идея решения
- Создайте новый атрибут. Там указаны роли, редактирование которых запрещено.
Этот атрибут используется для обозначения определенных свойств модели.
- Переопределите DefaultModelBinder по умолчанию, чтобы игнорировать запрещенные привязки свойств, если пользователь принадлежит хотя бы к одной из ролей, указанных в атрибуте.
Решение
Создание атрибута.
В строке Роли через запятую будут указаны запрещенные роли: [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class DenyWriteRolesAttribute : Attribute
{
public string Roles { get; set; }
}
Новый механизм привязки модели реализован путем наследования от стандартного класса DefaultModelBinder. Необходимо переопределить метод BindProperty, отвечающий за привязку конкретных свойств.
Если свойство имеет атрибут DenyWriteRoles и хотя бы одна роль пользователя соответствует любой из ролей, указанных в атрибуте, то привязка не происходит: public class CustomModelBinder : DefaultModelBinder
{
protected override void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, System.ComponentModel.PropertyDescriptor propertyDescriptor)
{
var a = propertyDescriptor.Attributes.OfType<DenyWriteRolesAttribute>().
FirstOrDefault(); if (a != null && a.Roles.Split(',').
Any(r => controllerContext.HttpContext.User.IsInRole(r)))
return;
base.BindProperty(controllerContext, bindingContext, propertyDescriptor);
}
}
Ниже приведен пример установки CustomModelBinder в качестве связывателя модели по умолчанию в файле Global.asax.cs: protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
ModelBinders.Binders.DefaultBinder = new CustomModelBinder();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
Теперь, чтобы запретить пользователям с ролью «пользователь» изменять свойство модели «Имя», просто установите атрибут DenyWriteRoles: public class ClientViewModel
{
public int Id { get; set; }
[DenyWriteRoles(Roles = "user")]
public string Name { get; set; }
public string Inn { get; set; }
}
Результат
Пользователь при работе с приложением имеет возможность видеть все свойства модели, однако изменения, касающиеся защищенных свойств, остаются игнорируемыми.
Теги: #asp.net mvc #C++ #.
NET #C++
-
Термиты
19 Oct, 24 -
Слухи: У Iphone Будет Две Батареи
19 Oct, 24 -
Вышел Mozilla Firefox 3.6.3
19 Oct, 24 -
Оживит Ли Олег Куваев Масяню?
19 Oct, 24