2012-10-02 5 views
0

MVC 응용 프로그램에서 일부 DropDownLists가 있습니다. 내 컨트롤러에서 IEnumerable<SelectListItem>을 만들고이를 내보기로 전송합니다. 불행히도 유효성 검사 오류가 있으면 해당 목록을 다시 만들어야합니다. 그렇지 않으면보기 렌더링이 실패합니다. 컨트롤러 액션 메소드에서 SelectListItem 목록은 어디서 가야합니까?

내가하고 있어요 :

var possibilities = _repo.Objects.Select(o=>new SelectListItem(...)); 
viewmodel.Possibilities = possibilities; 
return View(viewmodel); 

뷰 모델은 다음과 같이 정의 된 가능성 속성이 있습니다

IEnumerable<SelectListItem> Possibilities { get; set; } 

을 그리고 내보기에 나는 그것을 액세스 :

@Html.DropDownListFor(vm=>vm.ThePossibility, vm.Possibilities) 

문제는 양식 게시 작업 메서드가 호출 될 때 뷰 모델이 그것은 Possibilities에 대한 널 (null)을 가지고, 내가 전화 할 때 :

if(!ModelState.IsValid) 
    return View(model); 

을보기는 렌더링되지 않습니다.

나는 포스트 엑션 방법에서 프로 폴리가 null 인 이유를 알고 있지만 이것을 고치는 가장 좋은 방법은 무엇입니까? 나는 그 목록을 다시 초기화하지 않을 것입니다.

감사합니다.

답변

1

목록을 다시 초기화하지 않으려면 세션 등 어딘가에 캐시해야합니다.

솔직히 대부분의 경우 다시 작성하는 것이 더 간단합니다. 매번 다시 할당해야합니다.

+0

예, 감각을 만드는, 내가 그 생각을해야합니다. 이 일이 자동으로 일어나게하려면 어떤 종류의 뷰 상태를 다시 도입해야합니다. 감사. – zmbq

1

Post-Redirect-Get pattern을 사용해보아야합니다. this blog post에 설명 된 속성 쌍이 ASP.Net MVC에서이 작업을 매우 쉽게 만듭니다.

+0

블로그 게시물 # 13을 언급하는 경우 여기에 해당되지 않습니다. 그것은 SelectList 드롭 다운을 포함하지 않는 ModelState에 관한 것입니다. 또한 사용자가 TempData 페이지가 새로 고쳐지면서 ModelState도 새로 고칠 때 TempData 방식에 큰 문제가 있습니다. 메시지에는 적합하지만 필요한 실제 상태에는 적합하지 않습니다. –

+0

@Mystere - 올바른 - ModelState가 지속되지만 "Get"요청으로 다시 리디렉션하면 원래 드롭 다운 목록 옵션을 채운 메소드가 다시이 작업을 수행합니다. 그리고 ModelState를 잃어 버리는 페이지 리로딩까지, 그것은 제가 (그리고 대부분의 다른 사람들이 믿는) 행동입니다. –

1

일반적으로 어딘가에 캐시를 저장하거나 공용 목록을 가져 오기 위해 정적 클래스를 제공합니다. 그런 다음 게터를 사용하여 모델에서 이들에 대한 액세스를 제공 할 수 있습니다. 예를 들어

:

IEnumerable<SelectListItem> _possibilities 
IEnumerable<SelectListItem> Possibilities 
{ 
    get 
    { 
     if (_possibilities == null) 
      _possibilities = CommonLists.Possibilities(); 

     return possibilities; 
    } 
} 
0

Accessors 및 JSON (NetwonSoft는) 당신의 친구입니다. 당신이 set 모델의 IEnumerable<SelectListItem> 속성, 공공 문자열 속성에 직렬화 간단히 말해서

  1. 에서

    . 모델의 IEnumerable<SelectListItem> 재산 직렬화 문자열 속성 (예를 들어, 널 (null))

  2. 는 공개 문자열 속성은 set되는 경우, 그리고 IEnumerable<SelectListItem>가 정의되어 있지 않습니다.
  3. 보기에서 직렬화 된 문자열을 서버에 게시간에 유지되도록 포함하십시오. (예 :@Html.HiddenFor(...))

모델

public class MyViewModel 
{ 
    public IEnumerable<SelectListItem> Selections 
    { 
     get 
     { 
      return selections; 
     } 
     set 
     { 
      selections= value; 
      // serialize SelectListItems to a json string 
      SerializedSelections = Newtonsoft.Json.JsonConvert.SerializeObject(value); 
     } 
    } 
    IEnumerable<SelectListItem> selections; 

    public string SerializedSelections 
    { 
     get 
     { 
      return serializedSelections; 
     } 
     set 
     { 
      serializedSelections = value; 
      if(Selections == null) 
      { 
       // SelectListItems aren't defined. Deserialize the string to the list 
       Selections = Newtonsoft.Json.JsonConvert.DeserializeObject<IEnumerable<SelectListItem>>(value); 
      } 
     } 
    } 
    string serializedSelections; 
} 

면도기보기

<form> 
... 
@Html.HiddenFor(m => m.SerializedSelections) 
... 
@Html.DropDownListFor(m => m.SomeProperty, Model.Selections) 
</form> 
관련 문제