이것이 팀이 수정해야하는 버그라고 생각하지 않는다면 MSDN은 문서를 개선해야합니다. 혼란스러운 것은 이것에 대한 잘못된 문서에서 비롯됩니다. MSDN 에서는 매개 변수 이름을 다음 과 같이 설명합니다 .
Type: System.String
The name of the form field to return.
이것은 생성하는 최종 html이 해당 매개 변수를 선택 입력의 이름으로 사용함을 의미합니다. 하지만 실제로는 그 이상을 의미합니다.
디자이너는 사용자가보기 모델을 사용하여 드롭 다운 목록을 표시하고 동일한 보기 모델로 다시 게시 할 것이라고 가정합니다 . 그러나 많은 경우에 우리는 그 가정을 실제로 따르지 않습니다.
위의 예를 사용하십시오.
public class Person {
public int Id { get; set; }
public string Name { get; set; }
}
가정을 따르면이 드롭 다운 목록 관련 뷰에 대한 뷰 모델을 정의해야합니다.
public class PersonsSelectViewModel{
public string SelectedPersonId,
public List<SelectListItem> Persons;
}
다시 게시 할 때 선택한 값만 다시 게시되므로 모델의 속성 SelectedPersonId에 다시 게시해야한다고 가정합니다. 즉, Html.DropDownList의 첫 번째 매개 변수 이름 은 'SelectedPersonId'여야합니다. 따라서 디자이너는 뷰에 모델 뷰를 표시 할 때 모델의 속성 SelectedPersonId가 해당 드롭 다운 목록의 기본값을 유지해야한다고 생각합니다. List <SelectListItem> Persons가 이미 Selected 플래그를 설정하여 선택 / 기본값을 표시한다고 생각하더라도 tml.DropDownList는 실제로이를 무시하고 고유 한 IEnumerable <SelectListItem>을 다시 빌드하고 이름에 따라 기본 / 선택된 항목을 설정합니다.
다음은 asp.net mvc의 코드입니다.
private static MvcHtmlString SelectInternal(this HtmlHelper htmlHelper, ModelMetadata metadata,
string optionLabel, string name, IEnumerable<SelectListItem> selectList, bool allowMultiple,
IDictionary<string, object> htmlAttributes)
{
...
bool usedViewData = false;
// If we got a null selectList, try to use ViewData to get the list of items.
if (selectList == null)
{
selectList = htmlHelper.GetSelectData(name);
usedViewData = true;
}
object defaultValue = (allowMultiple) ? htmlHelper.GetModelStateValue(fullName, typeof(string[])) : htmlHelper.GetModelStateValue(fullName, typeof(string));
// If we haven't already used ViewData to get the entire list of items then we need to
// use the ViewData-supplied value before using the parameter-supplied value.
if (defaultValue == null && !String.IsNullOrEmpty(name))
{
if (!usedViewData)
{
defaultValue = htmlHelper.ViewData.Eval(name);
}
else if (metadata != null)
{
defaultValue = metadata.Model;
}
}
if (defaultValue != null)
{
selectList = GetSelectListWithDefaultValue(selectList, defaultValue, allowMultiple);
}
...
return tagBuilder.ToMvcHtmlString(TagRenderMode.Normal);
}
따라서 코드는 실제로 더 나아갔습니다. 모델에서 이름을 조회 할뿐만 아니라 뷰 데이터에서도 이름을 찾으면 selectList를 다시 빌드하고 원래 Selected를 무시합니다.
문제는 많은 경우에 우리는 실제로 그렇게 사용하지 않는다는 것입니다. 우리는 하나 / 여러 항목이 선택된 selectList를 true로 설정하기를 원합니다.
물론 솔루션은 간단합니다. 모델이나 뷰 데이터에없는 이름을 사용하십시오. 일치하는 항목을 찾을 수없는 경우 원래 selectList를 사용하고 원래 Selected가 적용됩니다.
하지만 여전히 mvc가 조건을 하나 더 추가하여 개선해야한다고 생각합니다.
if ((defaultValue != null) && (!selectList.Any(i=>i.Selected)))
{
selectList = GetSelectListWithDefaultValue(selectList, defaultValue, allowMultiple);
}
원래 selectList에 이미 하나의 Selected가있는 경우이를 무시하는 이유는 무엇입니까?
내 생각뿐입니다.