'MY KEY'키가있는 ViewData 항목은 'System.String'유형이지만 'IEnumerable <SelectListItem>'유형이어야합니다.


142

ASP.NET MVC 2를 사용하여 Linq-2-SQL로 매핑 된 데이터베이스에서 드롭 다운 목록을 채우려 고하는데이 오류가 계속 발생합니다.

IEnumerable<SelectListItem>두 번째 줄 에 유형 변수를 선언했기 때문에 혼란 스럽지만 오류로 인해 이것이 사실이 아니라고 생각합니다. 나는 이것이 매우 간단해야한다고 생각하지만 어려움을 겪고 있습니다. 도움을 주시면 감사하겠습니다.

내 컨트롤러의 흥미로운 부분은 다음과 같습니다.

public ActionResult Create()
{
    var db = new DB();
    IEnumerable<SelectListItem> basetypes = db.Basetypes.Select(
        b => new SelectListItem { Value = b.basetype, Text = b.basetype });
    ViewData["basetype"] = basetypes;
    return View();
}

그리고 여기 내 흥미로운 부분이 있습니다.

<div class="editor-label">
   <%: Html.LabelFor(model => model.basetype) %>
</div>
<div class="editor-field">
   <%: Html.DropDownList("basetype") %>
   <%: Html.ValidationMessageFor(model => model.basetype) %>
</div>

다음은 양식을 제출할 때 POST 조치입니다.

// POST: /Meals/Create
[HttpPost]
public ActionResult Create(Meal meal)
{
    if (ModelState.IsValid)
    {
        try
        {
            // TODO: Add insert logic here
            var db = new DB();
            db.Meals.InsertOnSubmit(meal);
            db.SubmitChanges();
            return RedirectToAction("Index");
        }
        catch
        {
            return View(meal);
        }
    }
    else
    {
        return View(meal);
    }
}

감사.


1
드롭 다운 목록이보기에 잘 나타납니다. 데이터베이스에서 원하는대로 채워지지만 양식을 게시 할 때 이러한 오류가 발생합니다.
JBibbs

6
허용 된 답변 요약 : 컨트롤러의 가져 오기 및 게시 작업에서 목록을 채워야합니다. 이 작업을 잊어 버리면 더 복잡한 버그를 찾는 데 시간을 낭비하게됩니다.
Adam Tolley

답변:


208

나는 같은 문제가 있었고 마침내 대답을 얻었습니다 ...

문제는 POST 조치에서 양식을 제출 한 후 ModelState가 유효하지 않거나 try / catch에서 오류를 발견하여보기가 리턴된다는 것입니다. 그러나 이번에는보기가 ViewData["basetype"]올바르게 설정 되지 않았습니다 .

이전에 사용한 것과 동일한 코드로 다시 채워야하므로이를 반복하십시오.

var db = new DB();
IEnumerable<SelectListItem> basetypes = db.Basetypes.Select(
    b => new SelectListItem { Value = b.basetype, Text = b.basetype });
ViewData["basetype"] = basetypes;

전과 return View(meal)[HttpPost]방법.

정확히 이것은 당신의 문제를 해결할 것입니다 :

[HttpPost]
public ActionResult Create(Meal meal)
{
    if (ModelState.IsValid)
    {
        try
        {
            // TODO: Add insert logic here
            var db = new DB();
            db.Meals.InsertOnSubmit(meal);
            db.SubmitChanges();
            return RedirectToAction("Index");
        }
        catch
        {
            var db = new DB();
            IEnumerable<SelectListItem> basetypes = db.Basetypes.Select(
               b => new SelectListItem { Value = b.basetype, Text = b.basetype });
            ViewData["basetype"] = basetypes;
            return View(meal);
        }
    }
    else
    {
        var db = new DB();
        IEnumerable<SelectListItem> basetypes = db.Basetypes.Select(
            b => new SelectListItem { Value = b.basetype, Text = b.basetype });
        ViewData["basetype"] = basetypes;
        return View(meal);
    }
}

나는이 질문이 매우 오래되었다는 것을 알고 있지만 오늘 같은 문제로 여기에 왔으므로 나중에 다른 사람들이 여기에 올 수 있습니다 ...


8
"다시 입력"으로 +1 ... 뷰 모델을 작성하기위한 상당히 강력한 시스템이 있지만 호출하는 것을 완전히 잊어 버렸습니다. 따라서 속성이 채워지지 않았으며 시도한 내용에 관계 없이이 메시지가 모호합니다.
Tim Medora

8
게시물 전에이 정보를 얻으면 SelectList에 아무것도 없으므로 해당 게시물을 찾았 기 때문입니다.
Martin

1
+1 실제로 Html.Action을 다른 액션 메서드로 호출 할 때 Index 메서드에서 ViewBag를 설정했기 때문에 !!
SwampyFox

감사. 그것이 단지 보존된다면 좋을 것이지만 MVC가 "길"이 아닐 것이라고 생각합니다.
Casey

모델이 무효화되면 사용자가 제출 한 데이터가 db에 저장됩니까? 나는 또한 같은 문제에 직면하고 있습니다. 나는 초보자입니다. 내가 틀렸다면 나를 바로 잡으십시오.
Koushik Saha

87

SelectList가 null 인 경우이 오류가 발생합니다.


3
그렇습니다 .GET에서 SelectList를 설정 한 다음 POST 동작으로 다시 ModelState.IsValid==false되돌릴 때 (분명히) 모델을 반환 return View(model)하지만 POST에서 돌아 오기 전에 SelectList 소스를 다시 채우지 않는 경우 일반적인 오류 / 감시 입니다. ViewState ala WebForms가 없으므로 @Html.DropDown헬퍼가 select를 다시 빌드 할 소스가 없습니다 . GET뿐만 아니라 클라이언트에게보기를 리턴 할 때마다 해당 소스 목록을 채워야합니다.
rism

그렇습니다. 이것은 나의 문제였습니다. get call에서 selectList를 채우는 것을 잊었습니다. 매우 잘못된 오류입니다. 좋은 포스트.
Matt


1

향후 독자를 위해 면도기를 사용하는 경우 선택 목록 항목 유형을 목록에서 IEnumerable로 변경하십시오.

에서

@Html.DropDownListFor(m => m.id, ViewBag.SomeList as List<SelectListItem>)

@Html.DropDownListFor(m => m.id, ViewBag.SomeList as IEnumerable<SelectListItem>)

0

드롭 다운 목록의 이름에 대한 문자열을 첫 번째 매개 변수로 추가하고 항목을 뷰 데이터에서 가져옵니다.

 <%= Html.DropDownList("SomeDropdownName", (IEnumerable<SelectListItem>)ViewData["basetype"]) %>

다음은 또한 사용할 수있는 확장 방법이므로 드롭 다운 목록은 다른 컨트롤을 수행 한 방법과 유사한 스타일로 설정됩니다.

        public static string DropDownList<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList, string optionLabel)
        where TModel : class
    {
        string inputName = ExpressionHelper.GetInputName(expression);
        return htmlHelper.DropDownList(inputName, selectList, optionLabel);
    }

예를 들어

<%= Html.DropDownList(x => x.BaseType, (IEnumerable<SelectListItem>)ViewData["basetype"], "")%>

0

컬렉션을 ViewData 사전의 항목으로 설정하고 모델의 속성으로 검색하려고합니다. 간단한 수정은 설정 한 것과 같은 방식으로 참조하는 것입니다.

    <%var basetype = ViewData["basetype"] as IEnumerable<SelectListItem>;%>
    <div class="editor-label">
        <%: Html.Label("basetype") %>
    </div>
    <div class="editor-field">
        <%: Html.DropDownList("basetype", basetype) %>
        <%: Html.ValidationMessage("basetype") %>
    </div>

또는 아래 코드는 강력한 형식의 뷰를 사용합니다.

public class ViewModel {
   //Model properties
   public IEnumerable<SelectListItem> basetype {get;set;}
}

public ActionResult Create()
    {
        var db = new DB();
        IEnumerable<SelectListItem> basetypes = db.Basetypes.Select(b => new SelectListItem { Value = b.basetype, Text = b.basetype });
        return View(new ViewModel { basetype=basetypes });
    }

그런 다음 강력하게 입력 한 관점에서 :

    <div class="editor-label">
        <%: Html.LabelFor(model => model.basetype) %>
    </div>
    <div class="editor-field">
        <%: Html.DropDownListFor(model=>model.basetype) %>
        <%: Html.ValidationMessageFor(model => model.basetype) %>
    </div>

"간단한 수정"예제에서 코드를 사용해 보았는데 같은 오류가 발생했습니다. 드롭 다운 목록이 View ok에 채워 진다고 언급했지만 양식을 제출하면이 오류가 발생합니다.
JBibbs

양식 제출을 처리하는 컨트롤러 작업에 대한 코드를 게시 할 수 있습니까?
Igor Zevaka

물론 원래 게시물에 추가하겠습니다. 지금까지 도와 주셔서 감사합니다.
JBibbs

0

Html.DropDownList()메소드 를 사용 하는 경우 @Peto가 응답 한 것처럼 ViewData / Viewbag 항목이 설정되지 않은 경우 동일한 오류가 발생할 수 있습니다.

그러나 컨트롤러 설정 항목의 경우 올바르게 설정되지 않을 수 있지만 주보기에서는 새로운 ViewDataDictionary 값으로 부분 viw 호출을 사용합니다.

당신이있는 경우 @Html.Partial("Partianame", Model,new ViewDataDictionary() { /* ... */ })다음 부분보기가 표시되지 않습니다 ViewDataViewBag데이터 제거 new ViewDataDictionary()매개 변수


0

미래의 독자들에게

나는 오늘 문제를 겪었고 그것을 고칠 수 없었다. 결국 정말 단순 해졌습니다. 테이블 +보기로 작업하고있었습니다. 테이블을 업데이트 할 때 (몇 개의 열 추가)보기를 업데이트 (삭제 및 다시 작성)하는 것을 잊어 버렸습니다. 이로 인해 문제가 발생했습니다. 누군가에게 도움이되기를 바랍니다.


0

오늘 같은 오류가 발생했으며 솔루션은 "유효한"모델을 만드는 것입니다.

필자의 경우 "저장"을 클릭하여 사용자를 제출 한 후 모델 상태 : 사용자가 "0"을 입력하면 유효하지 않지만 사용자가 "0.0"을 입력하면 모델 상태가 유효합니다.

따라서 "IsValid"메서드를 재정 의하여 사용자 키 입력 "0"도 true로 반환합니다.

도움이 되길 바랍니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.