2010-05-25 6 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 /> 
<% } 
%> 

, 내 컨트롤러, 첫 번째 INT는 템플릿 ID입니다 IDictionary를 얻을 수이고, 다른 하나는 사용자에 의해 주어진 수입니다 . 여기

내가 원하는 것입니다 :

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

나는 많은 것들을 시도했지만 아무것도 작동하지 않습니다. 나는 근원을 읽는 것을 시도했다 그러나 미로이고, 나는 모형 바인딩에 관하여 정보를 얻는 것을 시도해 headhache를 얻고있다.

질문 :

  • 가 modelbinding 작동 방법에 대한 좋은 ressource가? 나는 철저히 조사하고 싶다. 주어진 예제에 관해 이야기하는 84093043 블로그에 질려있다.
  • 는 어떻게 내 컨트롤러의 행동에 IDictionary (심지어 IDictionary를 얻기 위해 사용하는, 내 HTML을 구축 할 수 있습니다?

고마워요 당신의 도움에 대한 입력 요소를 작성하는 방법에 대한

답변

1

좋아요 ... 감사합니다 나는 해결책을 얻을 수있었습니다. 없음 하나 청소기,하지만 작동합니다.

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가 원했던 방식으로 사전에 반복하는 'fake'카운터를 소개했습니다. 결과적으로 텍스트 상자가 비어있을 때 사전에 값이 입력되고 '0'이 표시됩니다.

또 다른 문제가 나타났습니다. 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은 지금 가지 추한이며, 직관에 반하는 :

그래서 나는이 같은 모든 오류를 제거 내 컨트롤러에 ModelState을 속였다 인덱스가없는 콜렉션을 루프하는 인덱스 ??). 그리고 매번 이런 종류의 바인딩을 사용하여 매번 제대로 작동하도록 트릭을해야합니다.

그래서 이제는 더 나은 사전을 만들기위한 새로운 글을 열 것입니다. 는 여기있다 : ASP.Net MVC 2 - better ModelBinding for Dictionary<int, int>

편집 - 파벨 Chuchuva에 청소기 솔루션, 감사 있습니다.

컨트롤러 코드에서 Null int를 사전 값으로 사용하십시오. 추가 할 코드가 많지만 청소기가 많습니다.

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