ASP.NET MVC: Что, если Вашей моделью является просто Словарь?

(Я плохо знаком с 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 preferrably, но пролитый некоторый свет, если бы это лучше обращено в 2,0, поскольку я все еще хотел бы знать)?


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

11
задан JPot 4 February 2010 в 05:17
поделиться

6 ответов

Связыватель модели по умолчанию в 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.

4
ответ дан 3 December 2019 в 11:52
поделиться

Установите тип данных «JSONP» для вызова $ .ajax () . Вы должны убедиться, что ответ правильно отформатирован, чтобы он работал. Википедия имеет хороший раздел на JSONP .

-121--4244654-

Я бы разбил программу в разных задачах.

Первый шаг состоит в том, чтобы иметь возможность считывать пару строк, первую строку, которая сообщает вам количество считываемых чисел, а затем вторую строку, чтобы считывать фактические числа. Для этого может быть полезна функция, называемая чем-то вроде read _ set . Он должен иметь возможность возвращать считанные числа и сигнальный конец файла, а также ошибки. Для этого мы можем определить структуру данных, такую как

struct numbers {
    long *data; /* or choose a type depending upon your needs */
    size_t len;
};

, и затем мы можем объявить нашу функцию с прототипом:

int read_set(FILE *fp, struct numbers *num);

Функция выделит память для num- > data , и установить num- > len в правильное значение. Он возвращает 0 за успех и набор условий ошибки в противном случае. Мы можем получить фантазии и использовать enum для возврата статусов позже. Пока допустим, что 0 = успех, 1 = конец файла, а все остальное - ошибка.

Затем вызывающий абонент вызывает read _ набор () в цикле:

struct numbers numbers;
int status;
while ((status = read_set(fp, &numbers)) == 0) {
    /* process numbers->data, and then free it */
}
if (status == 1) {
    /* hit end of file, everything is OK */
} else {
    /* handle error */
}

Для реализации read _ набор () он должен считывать две строки. Существует множество реализаций чтения полной строки в C , поэтому можно использовать любую из них, и сначала прочитать строку, затем sscanf () / strtoul () для одного числа (проверьте его возвращаемое значение!). После получения номера n можно прочитать следующую строку в памяти и сделать следующее:

num->data = malloc(n * sizeof *num->data);
num->len = n;

Затем можно повторно вызвать sscanf () или strtol () для сохранения номеров в num- > data . Необходимо поставить чеки, чтобы убедиться, что в этой строке точно n чисел.

Обратите внимание, что можно записать read _ набор () другими способами: считывать строки по символам и анализировать числа по мере их чтения. Это имеет преимущество, заключающееся в том, что данные переходят только один раз и не нуждаются в большом буфере для хранения всей входной линии в памяти, но недостаток состоит в том, что они сами выполняют низкоуровневые операции, и чтение данных по символам может быть медленным.

-121--3787426-

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

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

EDIT: Я не думаю, что метка/текстовое поле является правильным пользовательским интерфейсом для вашего сценария. Попробуйте создать сетку или список.

0
ответ дан 3 December 2019 в 11:52
поделиться

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

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

0
ответ дан 3 December 2019 в 11:52
поделиться

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

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

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

0
ответ дан 3 December 2019 в 11:52
поделиться

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

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

    публичный класс DefaultDictionaryBinder : DefaultModelBinder 
    { 
     //... 
    }
    
  2. Заменить папку по умолчанию в Application_Start

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

    публичного класса DictionaryFilter : ActionFilterAttribute 
    { 
     публичное переопределение пустого OnActionExecuting(ActionExecutingContext filterContext) 
     { 
     // Обработка filterContext.HttpContext.Request.InputStream здесь 
     } 
     //... 
    }
    
  4. Теперь применяйте фильтр к своему действию

    .
    [DictionaryFilter] 
    [AcceptVerbs(HttpVerbs.Post)] 
    public ActionResult Create(Dictionary valuesEntered) 
    { 
     //... 
    } 
    
  5. Наслаждайтесь своей работой :-)

0
ответ дан 3 December 2019 в 11:52
поделиться

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

Вы можете достичь того же результата, создав один объект 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
ответ дан 3 December 2019 в 11:52
поделиться
Другие вопросы по тегам:

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