0

データベース内のいくつかのメタデータ テーブルに基づいて動的に生成されるフォームに取り組んでいます。setting_1、setting_53、setting_22 のような名前の入力タグを作成します。数字はメタデータの主キーです。コンテンツは動的であるため、FormCollection を POST 要求の唯一のパラメーターとして使用しています。

質問 1: GET 要求用の FormCollection のようなクラスはありますか? クエリ パラメータに直接アクセスしたい。

質問 2: これらのクエリ パラメータを渡す必要がある場合、URL を作成する簡単で安全な方法はありますか?

私の大きな懸念の 1 つは、一部の設定が OAuth 経由で入力されるため、ユーザーが外部ページにリダイレクトされることです。ユーザーが戻ったら回復する必要がある「状態」としてクエリ文字列を渡す必要があります。この状態を使用して、ユーザーがフォーム入力プロセスで中断した場所を取得する必要があります。クエリパラメータを渡すための非常に簡単なメカニズムが必要な理由はなおさらです。

このような動的ページを扱った人はいますか? これらのページをやり取りするための適切なパターンとプラクティスはありますか?

4

1 に答える 1

1

さて、あなたは確かにRequest.QueryStringコントローラーアクションの内部を見ることができます。

しかし、それが私である場合は、代わりにカスタムモデルバインダーを作成します。

これがサンプルモデルバインダーです。私はこれをテストしていません!

public class MyModelBinder: DefaultModelBinder
{
    private static void BindSettingProperty(
        ControllerContext controllerContext, 
        ModelBindingContext bindingContext, 
        PropertyDescriptor propertyDescriptor)
    {
        if (propertyDescriptor.PropertyType != typeof(IDictionary<string, string>))
        {
            throw new InvalidOperationException("This binder is for setting dictionaries only.");
        }
        var originalValue = propertyDescriptor.GetValue(bindingContext.Model) as IDictionary<string, string>;
        var value = originalValue ?? new Dictionary<string, string>();
        var settingKeys = controllerContext.HttpContext.Request.QueryString.AllKeys.Where(k => k.StartsWith("setting_", StringComparison.OrdinalIgnoreCase));
        foreach (var settingKey in settingKeys)
        {
            var key = settingKey.Substring(8);
            value.Add(key, bindingContext.ValueProvider.GetValue(settingKey).AttemptedValue);
        }
        if (value.Any() && (originalValue == null))
        {
            propertyDescriptor.SetValue(bindingContext.Model, value);
        }
    }

    protected override void BindProperty(
        ControllerContext controllerContext, 
        ModelBindingContext bindingContext, 
        PropertyDescriptor propertyDescriptor)
    {
        if (propertyDescriptor.Name.StartsWith("setting_", StringComparison.OrdinalIgnoreCase)
        {
            BindSettingProperty(controllerContext, bindingContext, propertyDescriptor);
        }
        else
        {
            base.BindProperty(controllerContext, bindingContext, propertyDescriptor);
        }
    }
}
于 2012-01-19T18:13:43.053 に答える