ASP.NET MVCでモデルプロパティを編集できないようにする

複雑なビジネスアプリケーションを開発する場合、多くの場合、ユーザーが一部のデータの編集権限を制限する必要がある状況に対処する必要があります。 この記事では、ASP.NET MVCで開発されたアプリケーションでモデルの特定のプロパティの変更を禁止する例を説明します。





挑戦する



識別子、名前、TINを含む顧客モデルがあるとします。



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





データはモデルの形式でページに届きます。 必要なアクションを完了すると、ユーザーはパラメーターとしてフォームフィールド値を含むHTTPリクエストを送信します。 要求の処理を行うActionメソッドが呼び出される前に、DefaultModelBinderはフォームから受け取ったパラメーターをデータモデルに関連付けます。 ユーザーが行ったすべての変更は、結果のモデルのプロパティに表示されます。



しかし、誤ってまたは悪意を持ってそうする権利を持たないユーザーがデータの整合性を侵害できないように、一部のプロパティを変更から保護する必要がある場合はどうでしょうか?! この問題を解決するには、モデルの一部のプロパティを特定のユーザーロールに変更できないようにするメカニズムを開発する必要があります。



ソリューションのアイデア





解決策



属性を作成します。 Roles行には、禁止されているロールがカンマで区切られて表示されます。



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





新しいモデルバインディングメカニズムは、標準のDefaultModelBinderクラスから継承することにより実装されます。 特定のプロパティをバインドするBindPropertyメソッドをオーバーライドする必要があります。 プロパティにDenyWriteRoles属性があり、少なくとも1つのユーザーロールが属性で指定されたロールのいずれかに一致する場合、バインドは発生しません。



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





ここで、「user」ロールを持つユーザーが「Name」モデルプロパティを変更できないようにするには、DenyWriteRoles属性を設定するだけで十分です。



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







結果



アプリケーションで作業する場合、ユーザーはモデルのすべてのプロパティを表示できますが、保護されたプロパティに関する変更は無視されます。








All Articles