ASP MVCで論理編集フォームの動作をしようとしています

現在、asp net mvcの小さなプロジェクトに取り組んでいます。 期限は非常に短いため、結果はできるだけ早く必要であるため、機能をスケッチし、美しいインターフェイス(govnokodit)を作成し始めました。 時間が経つと、それを見るのが難しくなり、修正が長くなり、顧客がアプリケーションをテストしている間に、このコードシートで何ができるかを考える時間があります(以前に考える時間はありませんでした)。



私は、長期にわたる文書編集カードの問題を解決する方法について考え始めています。 システムにはいくつかのタイプのドキュメントがあり、ドキュメントの役割とステータスに応じて、ユーザーが編集できるフィールドがあります。



この段階で私たちが持っているものの例を挙げます。





コード例:



@if (User.IsInRole(RolesEnum.Executor.GetDescription())) { @Html.TextBoxFor(model => model.RegNumber) } else { @Html.TextBoxFor(model => model.RegNumber, new { @readonly = "readonly" }) }
      
      







実際には、これがすべての問題ではありません。一部の場所では、問題をより迅速に解決するために、誰かが編集可能なフィールドをビューに残します。 これらはすべて、自分自身の生活を送る部分的な表現によって悪化し、それらはすべて異なった方法で行われ、いくつかの場所ではディスプレイテンプレートが使用されます。



改善しようとしています。



データモデルに表示ルールを設定し、属性を設定する方法でルールを設定することが可能であると判断しました。



属性クラスとルールの例:



  /// <summary> ///       /// </summary> public class PropertyPermission { public RolesEnum Role { get; set; } public int[] Satuses { get; set; } public bool IsReadOnly { get; set; } public PropertyPermission(RolesEnum role, int[] statuses) { this.Role = role; this.Satuses = statuses; } } /// <summary> ///       /// </summary> public class PropertyPermissionAttribute : Attribute { public PropertyPermission[] Permissons { get; private set; } public PropertyPermissionAttribute(PropertyPermission[] permissons) { this.Permissons = permissons; } public PropertyPermissionAttribute(RolesEnum role, params int[] statuses) { this.Permissons = new PropertyPermission[] { new PropertyPermission(role, statuses) }; } }
      
      







ここでは、フィールドの編集に使用できるロールとステータスのルールを設定し、他のすべてのユーザーに対して読み取り専用モードを終了するだけで十分だと思います。 したがって、アプリケーションでは、1つのフィールドが主に1つのロールのみで編集され、ドキュメントの特定のステータスで編集されます。これに関連して、ほとんどの場合、1つのルールに従ってモデルプロパティを登録する必要があります。 属性を作成するには、コンストラクターを呼び出し、ユーザーロールと読み取りモードが無効になる一連のステータスを渡します。



さまざまなクラスのオブジェクトのルールをチェックするには、ポリモーフィズムが必要です(現在のところ、関連クラスはありません)。ここでは、インターフェイスを宣言し、ドキュメントクラスに実装して、ドキュメントのステータスとロールが一貫しているかどうかを確認できますが、すべてのドキュメントの役割はロールとステータスのみに依存し、すべてのドキュメントにステータスプロパティがあります。次に、基本クラスを作成し、モデルプロパティの属性を設定します。



  public class BaseDocumentModel { [DisplayName("ID")] public int ID { get; set; } [DisplayName("")] public int? Status { get; set; } [PropertyPermission(RolesEnum.Executor, (int)StatusComplaint.ToWork)] [DisplayName(" №")] public string RegNumber { get; set; } }
      
      







この場合、「ToWork」ステータスの「Executor」ロールを持つユーザーがRegNumberフィールドを使用できるようにします。 ルールを実現するために、ヘルパーを作成する必要があります。 ヘルパーを使用して編集フィールドを表示します。



  public static class ProertyExtensions { public static MvcHtmlString RegistratorEditorFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression) { return RegistratorEditorFor(html, expression, null); } public static MvcHtmlString RegistratorEditorFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, object htmlAttributes) { return RegistratorEditorFor(html, expression, new RouteValueDictionary(htmlAttributes)); } public static MvcHtmlString RegistratorEditorFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, IDictionary<string, object> htmlAttributes) { var member = (expression.Body as MemberExpression).Member; if (html.ViewData.Model is BaseDocumentModel) { if (IsReadOnly(member as PropertyInfo, html.ViewData.Model as BaseDocumentModel)) { return html.TextBoxFor(expression, new { @readonly = "readonly" }); } } return html.EditorFor(expression); } static bool IsReadOnly(System.Reflection.PropertyInfo property, BaseDocumentModel document) { var attr = property.GetCustomAttributes(typeof(PropertyPermissionAttribute), false); bool result = true; foreach (PropertyPermissionAttribute a in attr) { foreach (var p in a.Permissons) { if (HttpContext.Current.User.IsInRole(p.Role.GetDescription()) && ((document.Status != null && p.Satuses.Contains((int)document.Status)) || p.Satuses.Length == 0)) { result = p.IsReadOnly; } } } return result; } }
      
      







IsReadOnlyは、同じクラスのルールをチェックするロジックを残し、フィールドの属性をチェックして決定を行います。 ヘルパー自体はEditorForを使用してフィールドを表示し、必要に応じて出力htmlを修正して読み取り専用フィールドを作成します。



メソッドを呼び出すためにすべてがビューに残ります:



  @Html.RegistratorEditorFor(model => model.RegNumber)
      
      







だから私は自分の問題を解決しようとしました。 私は何が正しくないのか知りたいです。



All Articles