5

ASP.Net MVC 2 に移行していくつかの問題を解決しようとしています。ここに 1 つあります。ビュー ポストの結果として、 Dictionaryを直接バインドする必要がありました。

ASP.Net MVC 1 では、カスタムIModelBinderを使用して完全に機能しました。

/// <summary>
/// Bind Dictionary<int, int>
/// 
/// convention : <elm name="modelName_key" value="value"></elm>
/// </summary>
public class DictionaryModelBinder : IModelBinder
{
    #region IModelBinder Members

    /// <summary>
    /// Mandatory
    /// </summary>
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        IDictionary<int, int> retour = new Dictionary<int, int>();

        // get the values
        var values = bindingContext.ValueProvider;
        // get the model name
        string modelname = bindingContext.ModelName + '_';
        int skip = modelname.Length;

        // loop on the keys
        foreach(string keyStr in values.Keys)
        {
            // if an element has been identified
            if(keyStr.StartsWith(modelname))
            {
                // get that key
                int key;
                if(Int32.TryParse(keyStr.Substring(skip), out key))
                {
                    int value;
                    if(Int32.TryParse(values[keyStr].AttemptedValue, out value))
                        retour.Add(key, value);
                }
            }
        }
        return retour;
    }

    #endregion
}

データの辞書を表示するいくつかのスマートな HtmlBuilder とペアで動作しました。

私が今直面している問題は、ValueProviderが Dictionary<> ではなく、名前がわかっている値のみを取得できる IValueProvider であることです。

public interface IValueProvider
{
    bool ContainsPrefix(string prefix);
    ValueProviderResult GetValue(string key);
}

スマートな解析を実行できないため、これは本当にクールではありません...

質問 :

  1. すべてのキーを取得する別の方法はありますか?
  2. HTML 要素のコレクションを Dictionary にバインドする別の方法を知っていますか?

ご提案いただきありがとうございます

O.

4

2 に答える 2

2

この質問は「回答済み」とマークされていますが、以下が役立つと思います。私は同じ問題を抱えていて、System.Web.Mvc.DefaultValueProvider のソース コードを調べました。RouteData、クエリ文字列、またはリクエスト フォームの送信から (正確な順序で) 値を取得します。すべてのキーを収集するために (これは最初の質問で求めているものです)、次のヘルパー メソッドを作成しました。

private static IEnumerable<string> GetKeys(ControllerContext context)
{
    List<string> keys = new List<string>();
    HttpRequestBase request = context.HttpContext.Request;
    keys.AddRange(((IDictionary<string,
        object>)context.RouteData.Values).Keys.Cast<string>());
    keys.AddRange(request.QueryString.Keys.Cast<string>());
    keys.AddRange(request.Form.Keys.Cast<string>());
    return keys;
}

このメソッドを使用して、キーを列挙できます。

foreach (string key in GetKeys(controllerContext))
{
    // Do something with the key value.
}
于 2012-01-18T06:44:14.227 に答える
1

MVC 2 ではこの方法はもうできないと思います。
別の方法として、DefaultModelBinder を拡張し、GetModelProperties などの仮想メソッドの 1 つをオーバーライドしてから、ModelBindingContext 内の ModelName を変更することもできます。別のオプションは、Dictionary タイプのカスタム MetadataProvider を実装することです。そこでモデル名を変更することもできます。

于 2010-02-26T02:20:17.297 に答える