キー「MY KEY」を持つViewDataアイテムのタイプは「System.String」ですが、タイプは「IEnumerable <SelectListItem>」である必要があります


142

ASP.NET MVC 2を使用して、Linq-2-SQLでマップされたデータベースからドロップダウンリストを作成しようとしていますが、このエラーが発生し続けます。

IEnumerable<SelectListItem>2行目で型の変数を宣言しているのでとても混乱していますが、エラーが原因でそうではないと思います。これは非常にシンプルなはずですが、苦労しています。どんな助けでもありがたいです。

これが私のコントローラーの興味深いビットです:

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は2010

6
受け入れられた回答の概要:コントローラーのgetアクションとpostアクションの両方にリストを入力してください。これを忘れることは簡単であり、その後、より複雑なバグの検索に時間を浪費することになります。
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に何もないため、そのリストを見つけただけです。
マーティン

1
+1実際にHtml.Actionを別のアクションメソッドに呼び出すときに、IndexメソッドでViewBagを設定していたためです。
SwampyFox 2013年

ありがとう。保存されているだけでいいのですが、MVCの「道」ではないと思います。
ケーシー

モデルが無効になっている場合、ユーザーが送信したデータはデータベースに保存されますか?私も同じ問題に直面しています。私は初心者です。私が間違っている場合は修正してください。
Koushik Saha 2014

87

SelectListがnullの場合、このエラーが発生します。


3
はい、これは、GETでSelectListを設定し、(当然)POSTアクションにポストバックするときに一般的なエラー/見落としです。ModelState.IsValid==falseそのため、モデルを返しreturn View(model) ますが、POSTから戻る前にSelectListソースを再入力しません。ViewState ala WebFormsがないため、@Html.DropDownヘルパーが選択を再構築するためのソースはありません。GETだけでなく、クライアントにビューを返すたびに、そのソースリストにデータを入力する必要があります。
Rism

うん、これは私の問題でした。get呼び出しでselectListに入力するのを忘れました。非常に誤解を招くエラー。素晴らしいポスト。
マット


1

今後の読者のために、かみそりを使用している場合は、selectlistアイテムのタイプをListから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>

「簡単な修正」の例のコードを使用してみましたが、同じエラーが発生しました。ドロップダウンリストは[OK]に表示されることを述べたはずですが、フォームを送信するとこのエラーが発生します。
JBibbs 2010

フォームの送信を処理するコントローラーアクションのコードを投稿できますか?
イゴールゼバカ2010

もちろん、元の投稿に追加します。これまでのご協力に感謝します。
JBibbs

0

Html.DropDownList()メソッドを使用する場合-@Petoが回答したように、ViewData / Viewbagアイテムが設定されていない場合、同じエラーが発生する可能性があります。

ただし、コントローラー設定項目の場合は正しく設定されない可能性がありますが、メインビューでは、新しいViewDataDictionary値で部分的なviw呼び出しを使用します。

あなたが持っている場合は@Html.Partial("Partianame", Model,new ViewDataDictionary() { /* ... */ })、あなたの部分的なビューが表示されませんViewDataし、ViewBagデータ、削除new ViewDataDictionary()パラメータ


0

今後の読者の皆様へ

今日問題に遭遇し、それを修正することができませんでした。結局のところ、それは本当にシンプルになりました。テーブルとビューを使用して作業していました。テーブルを更新したとき(いくつかの列を追加した)、ビューを更新(ドロップして再作成)するのを忘れたため、問題が発生しました。それが誰かを助けることを願っています。


0

今日も同じエラーが発生しました。私の解決策は、モデルを「有効」にすることです。

私の場合、ユーザーが「保存」をクリックして送信した後、モデルの状態を取得しました。ユーザーのキー入力が「0」の場合は無効ですが、ユーザーのキー入力が「0.0」の場合はモデルの状態が有効になります。

したがって、「IsValid」メソッドをオーバーライドして、ユーザーキー入力「0」でもtrueを返します。

それが役に立てば幸い。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.