ASP.Net MVC 2 - лучший ModelBinding для Словаря <интервал, интервал>

В некоторых особых случаях Вам будет нужен список текстовых полей (для контакта с n - n ассоциации), чей идентификатор не, знают перед временем выполнения. Что-то вроде этого: http://screencast.com/t/YjIxNjUyNmU

В том конкретном образце я надеюсь связывать количество к некоторым моим 'шаблонам'.

в ASP.Net MVC 1 я кодировал Словарь ModelBinder, чтобы иметь чистый и интуитивный HTML. Это позволило вещи как это:

// loop on the templates
foreach(ITemplate template in templates)
{
        // get the value as text
        int val;
        content.TryGetValue(template.Id, out val);
        var value = ((val > 0) ? val.ToString() : string.Empty);

        // compute the element name (for dictionary binding)
        string id = "cbts_{0}".FormatMe(template.Id);
%>
        
        
        

Вот код редактора связей:

public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
    IDictionary retour = new Dictionary();

    // 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;
}

При передаче ASP.Net MVC 2 проблемой является ValueProvider, больше не словарь. Нет никакого способа циклично выполниться через значения для парсинга их способ, которым я сделал.

И я не нашел никакой другой способ сделать так (Если Вы знаете один, говорите мне).

Я наконец переключился на 'стандартный' способ связать словарь, но HTML ужасен, парадоксален (использующие счетчики для цикличного выполнения по неиндексируемому набору??) и все значения требуются, в отличие от поведения, в котором я нуждаюсь (и это работало отлично в ASP.Net MVC 1).

Это похоже на это:

int counter= 0;
// loop on the templates
foreach(ITemplate template in templates)
{
        // get the value as text
        int val;
        content.TryGetValue(template.Id, out val);
        var value = ((val > 0) ? val.ToString() : string.Empty);

        // compute the element name (for dictionary binding)
        string id = "cbts_{0}".FormatMe(template.Id);
        string dictKey = "cbts[{0}].Key".FormatMe(counter);
        string dictValue = "cbts[{0}].Value".FormatMe(counter++);
%>
        
        
        
        

В контроллере я должен обмануть ModelState избегать 'значения требуется' ошибки:

public ActionResult Save(int? id, Dictionary cbts)
{
    // clear all errors from the modelstate
    foreach(var value in this.ModelState.Values)
        value.Errors.Clear();

Это слишком хитро. Я должен буду скоро использовать этот вид привязки много раз и возможно иметь некоторую работу разработчика уровней над приложением.

Вопрос:

  • Вы знаете способ сделать его лучше?

То, в чем я нуждаюсь, IMO, является ModelBinder для словаря, которые позволяют лучший HTML, и это делает не полагают, что все значения требуются.

1
задан Russ Clarke 26 May 2010 в 08:22
поделиться

1 ответ

Вы можете продолжать использовать связыватель модели MVC 1 в MVC 2. Самое большое изменение, которое вам придется сделать, это то, что связующее устройство модели не должно противоречить IValueProvider, но должно вместо этого идите прямо против Request.Form. Вы можете перечислить эту коллекцию и выполнить любую логику, необходимую для вашего конкретного сценария.

Назначение интерфейса IValueProvider - предоставить абстракцию о том, откуда берутся данные, и предназначен для универсального связывателя (например, DefaultModelBinder). Поскольку перечисление данных не гарантируется, сам IValueProvider не может быть IEnumerable. Но в вашем конкретном случае, когда у вас есть конкретное связующее для определенного сценария и вы уже знаете, что данные поступают из формы, абстракция не нужна.

2
ответ дан 3 September 2019 в 00:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: