24

これは一般的な設計の質問 です。ASP.NETMVCで動的(ランタイム生成)フォームをどのように実装しますか?

状況は次のとおりです。

  1. サイト管理者は、GUI(MVCビュー)を使用してフォームパラメーター(フィールド、フィールドのタイプ、検証)を定義できます。
  2. 必要に応じて、ランタイムは管理者構成に基づいてエンドユーザー用のフォームを生成します。このロジックはすべてコントローラーにあると思います。あるいは、拡張メソッドやアクションフィルターなどです。
  3. エンドユーザーがフォームに入力し、送信を押して、情報をデータベースにキャプチャします。

カスタマイズは、ネストされたコントロールやサードパーティのコントロールなどをサポートする必要はありませんが、非常にエレガントなデザインでそれが可能になると思います。ほとんどの場合、管理者が追加のフィールドをテキストボックス、チェックボックス、ラジオボタン、コンボボックスとして指定できるようにする必要があります。このデータをデータベースに保存するためのスペースを割り当てるためのアプリケーションも必要になりますが、その部分は理解できていると思います。

助けてくれてありがとう。

4

6 に答える 6

13

最近のプロジェクトでも同じ必要がありました。このためのクラス ライブラリを作成しました。ライブラリの新しいバージョンをリリースしました。

多分それはあなたを助けることができます: ASP.NET MVC 動的フォーム

于 2010-02-01T00:33:56.150 に答える
4

FormFactoryライブラリを使用すると、これを非常に簡単に行うことができます。

デフォルトでは、ビューモデルに反映されてPropertyVm[]配列が生成されますが、プログラムでプロパティを作成することもできるため、データベースから設定を読み込んで を作成できますPropertyVm

これは Linqpad スクリプトのスニペットです。

```

//import-package FormFactory
//import-package FormFactory.RazorGenerator


void Main()
{
    var properties = new[]{
        new PropertyVm(typeof(string), "username"){
            DisplayName = "Username",
            NotOptional = true,
        },
        new PropertyVm(typeof(string), "password"){
            DisplayName = "Password",
            NotOptional = true,
            GetCustomAttributes = () => new object[]{ new DataTypeAttribute(DataType.Password) }
        }
    };
    var html = FormFactory.RazorEngine.PropertyRenderExtension.Render(properties, new FormFactory.RazorEngine.RazorTemplateHtmlHelper());   

    Util.RawHtml(html.ToEncodedString()).Dump(); //Renders html for a username and password field.
}

```

設定できるさまざまな機能の例を含むデモ サイトがあります (例: ネストされたコレクション、オートコンプリート、日付ピッカーなど)

于 2016-07-11T14:18:55.003 に答える
3

もう1つのオプションは、非常に緩く結合されたデータベーススキーマを使用することです。

//これには、管理者ユーザーが設定するすべてのフィールドとタイプが含まれます
** ApplicationFields **
フィールド名
FieldType
..。

//これらはすべてParentObjectIDへのマッピングを持つすべての値です
** FormValues **
ParentObjectID
フィールド名
FieldValue

ランタイムで生成されたビューを(ApplicationFieldsから)送信するときは、FormCollectionをループして、更新する必要のあるParentObjectに設定してみてください。

public ActionResult MyForm(FormCollection form)
{{
    //これはすべてのフィールドを含むメインオブジェクトです
    var parentObject;

    foreach(フォームの文字列キー)
    {{
        parentObject.SetValue(key、form [key]);
    }
    ..。

次に、parentObjectは次のようになります...

パブリック部分クラスParentObject
{{
    IList _FormValues;

    public void SetValue(string key、string value)
    {{
        //この値がすでに存在するかどうかを確認してみてください
        FormValue v = _FormValues.SingleOrDefault(k => k.Key == key);

        //設定するだけの場合
        if(v!= null)
        {{
            v.Value=値;
            戻る;
        }

        //それ以外の場合、これは追加された新しいフォームフィールドである可能性があるため、新しい値を作成します
        v=新しいFormValue
        {{
            ParentObjectID = this.ID、
            キー=キー、
            値=値
        };

        _FormValues.Add(v);
    }
}
于 2009-05-29T17:30:46.823 に答える
1

ModelBinderこれを行う 1 つの方法は、生成されたフォームの中心となる独自のフォームを作成することです。モデルバインダーは、型付きの検証ModelStateと再構築を担当ViewDataModelします (ビューが型付きであると仮定します)。

DataAnnotationsモデル バインダーは、このカスタム モデル バインダーを使用してできることの良いリファレンスになる可能性があります。これは、属性の検証を記述する (および UI レンダリングのヒント) を介しAttributesて行うことができます。ViewDataModelただし、これはすべてコンパイル時に定義されたものですが、カスタム モデルバインダーの作成を開始するための優れたリファレンスとなります。

あなたの場合、モデルバインダーは実行時にxmlファイル/文字列からフィールドの検証を取得する必要があります。

次のようなルートがある場合:

routes.MapRoute(null, "Forms/{formName}/", new { action = "Index", controller = "Forms", formName = ""}),

次に、正しいフォーム xml を見つけてFormsController.Index(string formName)ビューに渡すことができます。

FormsModel、データを取得するために考えられるすべてのメソッドを保持する必要があります。FormsModelXmlは、リフレクションを使用して呼び出すことができる関数名 (場合によっては引数) にマップして、データをViewData入力または入力ViewDataModelすることができます。

フォーム インデックスのビューHtmlHelperは、XmlDocument.

次に、ユーザー (または asp.net mvc) がフォームをViewDataカスタム モデル バインダーにバインドすると、現在のコントローラー値を調べて formName を探し、すべての検証ルールを保持する対応する xml を検索できます。次に、実行時に定義されたエラーModelBinderを埋めます。ModelState

それは難しい作業ですが、成功した場合、私の見解ではそれだけの価値があります:)

David Liddleが示唆するように、モデルデータのより良い代替案を更新すると、非常に緩いデータベーススキーマになります。私はまだそれをxml(または他のシリアル化された形式)として保存し、それを使用してビューを生成し、カスタムの検証ルールを保持してModelBinder、各フィールドのレイアウトと検証をより詳細に制御できるようにするという問題を抱えています。

于 2009-05-29T17:04:17.967 に答える
0

cottsak の答えは非常に魅力的です。

少なくとも 2 つのクライアント側 XForms エンジンがあります。ここに1つあります:

https://community.emc.com/community/edn/xmltech

于 2009-07-30T18:29:26.307 に答える
-1

のようなモデルの「Web フォーム 2.0」コントロール リストを使用した HTML の単純な生成と比較して、HTML よりも XForms やその他の「抽象化」を生成することの大きな利点はわかりませんList<Tuple<Meta, Value>>。注: サーバー側では、結果を構造に合わせて手動で解析する必要があります。

「次のレイヤーの抽象化」を検索することは、迅速な開発に適していますが、「コードの生成」(実行時またはビルド時) には固有のものがあります。通常、「下位層」の生成コードは、「上位抽象層」のコードを生成するよりも優れたソリューションです。

したがって、@Foreach ループで Web 2 コントロールを生成するコードを記述してください。

于 2015-08-24T14:33:53.787 に答える