ASP.NET MVC: что если ваша модель - это просто словарь? - PullRequest
11 голосов
/ 04 февраля 2010

(я новичок в MVC).

В моем приложении у меня нет модели в смысле класса со свойствами. О, нет, это намного проще: мои пользователи в основном заполняют кучу строковых значений для различных ключей, установленных в других местах системы (ключи произвольны и не известны заранее, поэтому нет предварительно кодированного класса) 1 .

Моя "модель", таким образом, просто:

Dictionary<string, string>

Довольно просто.

Насколько я понимаю, привязка модели, html-помощники, состояние модели, итоги проверки основаны на отражении произвольного класса свойства . Но могут ли они просто использовать ключ / значения в моем словаре вместо этого?

Например, могу ли я иметь:

<label for="Name">Name:</label>
<%= Html.TextBox("Name") %>
<%= Html.ValidationMessage("Name", "*") %>

и

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(Dictionary<string, string> valuesEntered)
{            
    // ...
}

и MVC использует ключ / значение "Name", как указано в моей Dictionary<string, string> "модели", чтобы сделать всю свою закулисную магию? (MVC 1.0 желательно, но, пожалуйста, пролите немного света, если это лучше решать в 2.0, как я все еще хотел бы знать)?


1: звучит глупо, я уверен. Это приложение для отчетов, где «ключи» - это имена параметров отчета, а «значения» - значения, с которыми будет запускаться отчет.

Ответы [ 6 ]

4 голосов
/ 18 февраля 2010

Связыватель модели по умолчанию в MVC 1.0 может связываться со словарем, если он использует идентификаторы поля магической формы 'dictionaryName [index] .key' и 'dictionaryName [index] .value', где dictionaryName - имя вашего параметр словаря, а индекс представляет собой порядковый номер на основе 0 . Обычно значением ключа является скрытое поле, а значением является ваше текстовое поле. В вашем примере:

<%= Html.Hidden("valuesEntered[0].key", "Name") %>
<%= Html.TextBox("valuesEntered[0].value") %>
<%= Html.ValidationMessage("valuesEntered[0].value", "*") %>

Насколько я понимаю, привязка к словарям отличается в MVC 2.

0 голосов
/ 05 февраля 2010

Другой альтернативой может быть цикл по словарю для генерации полей с использованием ключа в качестве имени поля. В этом случае, однако, этикетку, возможно, придется извлечь из другого места.

Перед отправкой формы используйте jquery.form.js, чтобы объединить публикуемые данные обратно в строковое представление json для словаря, а затем используйте JavaScriptSerializer для преобразования json strin в словарь. Может быть, есть даже поддержка для этого автоматически.

Для проверки вы также можете переключиться на проверку на стороне клиента, например, используя jquery.validate.js и автоматически создать java-сценарий.

0 голосов
/ 05 февраля 2010

Создание связующего пользовательской модели является хорошим предложением, однако я вижу одну большую проблему с использованием словаря для предоставления значений: как модель на основе словаря получает ключи?Согласно вашему комментарию, вы планируете дать вашим элементам управления те же имена, что и вашим ключам.Итак, если вы уже знаете имена своих ключей, зачем вам создавать словарь?

Вы можете достичь того же результата, создав один объект ViewModel, который содержит все параметры, которые вы будете использовать дляваши отчеты как свойства.Заполните нужные значения, игнорируйте те, которые вам не нужны.

Например:

public class ReportParameterViewModel
{
    public DateTime OrderRangeBegin { get; set; }
    public DateTime OrderRangeEnd { get; set; }
    public string Department { get; set; }
    public int Customer_Number { get; set; }
    public double Commission_Rate { get; set; }
    public int Page_Start { get; set; }
    public int Page_End { get; set; }
    public bool IsExecutiveVersion { get; set; }
    //
    // ...and so on...
    //
}

Убедитесь, что все методы действий вашего контроллера, отвечающие за генерацию отчетов, могут принять экземпляр ReportParameterViewModel и убедитесь, что все ваши представления отчетов наследуются от ReportParameterViewModel.Идея словаря звучит как большая работа, чем необходимо, учитывая тот факт, что представления для ваших отчетов, скорее всего, будут статичными.

0 голосов
/ 05 февраля 2010

В соответствии с архитектурой ASP.NET MVC вам необходимо выполнить следующие шаги:

  1. Создайте свой собственный переплет (подходящий пример, который я нашел здесь )

    public class DefaultDictionaryBinder : DefaultModelBinder  
    {  
        //...  
    }
    
  2. Заменить связующее по умолчанию в Application_Start

    ModelBinders.Binders.DefaultBinder = new DefaultDictionaryBinder();
    
  3. Создать фильтр действий

    public class DictionaryFilter : ActionFilterAttribute  
    {  
        public override void OnActionExecuting(ActionExecutingContext filterContext)  
        {  
            // Process filterContext.HttpContext.Request.InputStream here  
        }    
        //...  
    }
    
  4. Теперь примените фильтр к вашему действию

    [DictionaryFilter]  
    [AcceptVerbs(HttpVerbs.Post)]  
    public ActionResult Create(Dictionary<string, string> valuesEntered)  
    {  
        //...  
    }  
    
  5. Приятной работы: -)

0 голосов
/ 04 февраля 2010

Я бы предложил создать модель для пары имя-значение отчета, а затем использовать метод, подобный описанному в this (см. Обсуждение вспомогательного HTML-кода BeginCollectionItem), чтобы добиться связывания их коллекции.

После этого валидация может быть вставлена ​​в модель пары имя-значение в зависимости от правил для конкретного экземпляра.

0 голосов
/ 04 февраля 2010

Правда, модель может быть такой же простой, как набор пар имя / значение. Вы можете пойти по этому пути, но я бы предложил, по крайней мере, обернуть ваш словарь в класс и, по крайней мере, использовать свойства или методы получения, чтобы позволить себе некоторую гибкость в будущем.

И да, вы можете связывать коллекции, но только в сценариях типа list / grid / combobox. Например. Элементы управления пользовательского интерфейса, предназначенные для хранения коллекций. Вы не можете использовать отражение для произвольного связывания с данным значением в коллекции.

РЕДАКТИРОВАТЬ: Я не думаю, что метка / текстовое поле является правильным интерфейсом для вашего сценария. Попробуйте сетку или список.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...