在某些特殊情況下,您需要一個文本框列表(處理n-n個關聯),其編號在運行時不知道。 這樣的事情:http://screencast.com/t/YjIxNjUyNmUASP.Net MVC 2 - 更好的ModelBinding for Dictionary <int, int>
在這個特定的示例中,我期待將計數與我的一些「模板」相關聯。
在ASP.Net MVC 1我編寫了一個Dictionary 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);
%>
<input type="text" id="<%= id %>" name="<%= id %>" value="<%= value %>" />
<label for="<%= id %>"><%= template.Name %></label>
<br />
這裏是粘合劑的代碼:
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;
}
當傳遞到ASP.Net MVC 2,問題是ValueProvider是不是一個字典了。沒有辦法通過循環值來按照我的方式解析它們。
我沒有找到任何其他方式這樣做(如果你知道的話,告訴我)。
我終於切換到綁定字典的'標準'方式,但是HTML很醜陋,違反直覺(使用counter來循環非索引集合??)並且所有的值都是必需的,不像行爲I需要(並且在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++);
%>
<input type="hidden" name="<%= dictKey %>" value="<%= template.Id %>" />
<input type="text" id="<%= id %>" name="<%= dictValue %>" value="<%= value %>" />
<label for="<%= id %>"><%= template.Name %></label>
<br />
在控制器我需要欺騙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();
這是太棘手。 我很快就需要多次使用這種綁定,並且可能在應用程序中有一些開發人員的工作。
問:
- 你知道一種方法,使其更好?
我需要什麼,國際海事組織,是一個ModelBinder字典,允許更好的HTML,並沒有考慮到所有的值都是必需的。
感謝您的建議。有時回到基礎是關鍵,而且很明顯你看不到它...... – Mose 2010-05-27 08:03:59