Вопрос

Я пытаюсь перейти на ASP.NET MVC 2 и решить некоторые проблемы. Вот один: мне нужно было напрямую связать Словарь как результат просмотра.

В 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 больше не является словарем <>, это IvalueProvider, который только позволяет получать значения, чье имя известно

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

Это действительно не круто, так как я не могу выполнить свой умный анализ ...

Вопрос :

  1. Есть ли другой способ получить все ключи?
  2. Знаете ли вы другой способ связать коллекцию HTML -элементов с словарем

Спасибо за ваши предложения

О.

Это было полезно?

Решение

Я не думаю, что вы сможете больше делать это в MVC 2.
В качестве альтернативы, вы можете расширить DefaultModelbinder и переопределить один из его виртуальных методов, таких как GetModelProperties, а затем изменить имя модели в модели BindingContext. Другим вариантом будет реализация пользовательского метадатапровдера для вашего типа словаря, вы также можете изменить имя модели там.

Другие советы

Хотя этот вопрос был отмечен «Ответ», я думаю, что следующее может быть полезным. У меня была такая же проблема, и я посмотрел на исходный код системы.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.
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top