📜 ⬆️ ⬇️

Disable editing model properties in ASP.NET MVC

When developing complex business applications, one often encounters a situation where users need to restrict the rights to edit certain data. This article will consider an example of prohibiting changes to certain properties of a model in an application developed on ASP.NET MVC.


Task


Suppose that we have a client model that contains its identifier, name, and TIN.

public class ClientViewModel { public int Id { get; set; } public string Name { get; set; } public string Inn { get; set; } } 

Data arrives on the page as a model. Having performed the necessary actions, the user sends an HTTP request that contains the form field values ​​as parameters. Before the Action method that is responsible for processing the request is called, DefaultModelBinder associates the parameters obtained from the form with the data model. All changes made by the user are displayed in the properties of the resulting model.

But what if some properties need to be protected from being changed so that a user who does not have the right to do so, accidentally or with malicious intent, cannot violate the integrity of the data ?! To solve this problem, it is necessary to develop a mechanism that would prohibit the modification of some properties of the model to specific user roles.
')

Solution idea



Decision


Creating an attribute. In the Roles line, comma separated roles will be indicated:

 [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)] public class DenyWriteRolesAttribute : Attribute { public string Roles { get; set; } } 

The new model binding mechanism is implemented by inheriting from the standard class DefaultModelBinder. You must override the BindProperty method, which is responsible for binding specific properties. If the property has the DenyWriteRoles attribute, and at least one user role matches any of the roles specified in the attribute, then the binding does not occur:

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

The following is an example of installing CustomModelBinder as the default model binder in the Global.asax.cs file:

 protected void Application_Start() { AreaRegistration.RegisterAllAreas(); ModelBinders.Binders.DefaultBinder = new CustomModelBinder(); RegisterGlobalFilters(GlobalFilters.Filters); RegisterRoutes(RouteTable.Routes); } 

Now, in order to prevent users with the “user” role from changing the “Name” model property, it is enough to set the DenyWriteRoles attribute:

 public class ClientViewModel { public int Id { get; set; } [DenyWriteRoles(Roles = "user")] public string Name { get; set; } public string Inn { get; set; } } 


Result


The user, when working with the application, has the opportunity to see all the properties of the model, however, changes regarding the protected properties remain ignored.

Source: https://habr.com/ru/post/156285/


All Articles