2010-05-25 2 views
0

В моем интерфейсе у меня есть список текстовых полей, что-то вроде этого: http://screencast.com/t/YjIxNjUyNmUASP.Net MVC 2 - ModelBinding и словарь <int, int>

Количество текстовых полей неизвестна, поскольку каждый из них связан с шаблоном. На моей странице необходимо связать номер с некоторыми из этих шаблонов.

Вот пример HTML код:

<% // loop on the templates 
    foreach(ITemplate template in templates) 
    { 
     // get the content from the input dictionary 
     int val; 
     content.TryGetValue(template.Id, out val); 
     // convert it as a string 
     string value = ((val > 0) ? val.ToString() : string.Empty); 

     // compute the element name/id (for dictionary binding) 
     string id = ?????????? 
     string name = ?????????????? 
%> 
     <label for="<%= name %>"><%= template.Name %></label> 
     <input type="text" id="<%= id %>" name="<%= name %>" value="<%= value %>" /> 
     <br /> 
<% } 
%> 

Что я ожидаю, в моем контроллере, чтобы получить IDictionary где первый ИНТ шаблон ID, а другой граф задается пользователем ,

Вот что я хочу:

public ActionResult Save(int? id, Dictionary<int, int> countByTemplate) 

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

Вопросы:

  • есть хороший Ressource о том, как работает modelbinding? Мне хотелось бы, чтобы исчерпывающий, я устал от блогов 84093043, которые говорят о конкретном конкретном примере.
  • как я могу построить свой HTML, используя для получения IDictionary (или даже IDictionary в действии моего контроллера?

Спасибо большое за помощь

ответ

1

Ok ... Благодаря Леви я был в состоянии получить на растворе. Не уборщик один, но он работает.

HTML, должно быть написано так:

<% 
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++); 
%> 
     <input type="hidden" name="<%= dictKey %>" value="<%= template.Id %>" /> 
     <input type="text" id="<%= id %>" name="<%= dictValue %>" value="<%= value %>" /> 
     <label for="<%= id %>"><%= template.Name %></label> 
     <br /> 
<% } 
%> 

мне пришлось добавить скрытое поле для хранения значения. Я представил счетчик «поддельных», чтобы перевернуть словарь, как хочет его ASP.Net MVC. В результате я получил словарь, заполненный моими значениями и «0», когда текстовое поле пуст.

Другая проблема: ModelState считался недействительным, так как «требуется значение». Я не хочу, чтобы мои значения требовались, но, глядя на код модели, я не нашел способ сообщить связующему, что значение НЕ требуется.

Так что я обманул ModelState в мой контроллер, удаляя все ошибки, например:

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

Ну ... я фактически получил решение, но HTML вроде некрасиво сейчас, и противоречит здравому смыслу (с использованием индекс для петли над неиндексированной коллекцией?). И мне нужно обмануть каждый раз, когда я буду использовать этот вид привязки, чтобы все это работало правильно.

Итак, теперь я открою новое сообщение, чтобы сделать словарь-переплет лучше. Вот оно: ASP.Net MVC 2 - better ModelBinding for Dictionary<int, int>

EDIT - Существует чистое решение, благодаря Павлу Chuchuva.

В коде контроллера используйте значение nullable для словаря. Немного больше кода для добавления, но гораздо чище.

public ActionResult Save(int? id, Dictionary<int, int?> cbts) 
{ 
    // this is our final dictionary<int, int> 
    Dictionary<int, int> cbtsFinal = new Dictionary<int, int>(); 
    // loop on the dicitonary with nullable values 
    foreach(var key in cbts.Keys) 
    { 
     // if we have a value 
     if(cbts[key].HasValue) 
      // then put it in the final dictionary 
      cbtsFinal.Add(key, cbts[key].Value); 
    } 
+0

Попробуйте 'общественное ActionResult Сохранить (INT? Идентификатор, словарь CBTs)' –

+0

Спасибо, это лучше! – Mose

Смежные вопросы