'MY KEY' anahtarına sahip ViewData öğesi 'System.String' türünde, ancak 'IEnumerable <SelectListItem>' türünde olmalıdır


142

ASP.NET MVC 2 kullanarak Linq-2-SQL ile eşlenen bir veritabanından bir açılan liste doldurmaya çalışıyorum ve bu hatayı almaya devam ediyorum.

Çok karışık çünkü IEnumerable<SelectListItem>ikinci satırda bir değişken türü bildiriyorum , ama hata bana böyle olmadığını düşündürüyor. Bunun çok basit olması gerektiğini hissediyorum, ama mücadele ediyorum. Herhangi bir yardım takdir.

İşte denetleyicimin ilginç parçaları:

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();
}

Ve benim görüşüme göre ilginç parçalar:

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

Formu gönderirken POST işlemi

// 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);
    }
}

Teşekkürler.


1
Açılır liste görünümde gayet iyi görünür. Veritabanından olması gerektiği gibi doldurur, ancak bu hataları aldığım formu gönderirim.
JBibbs

6
Kabul edilen yanıtın özeti: Listeyi, denetleyicinizin hem alma hem de gönderme işlemlerinde doldurduğunuzdan emin olun. Bunu yapmayı unutmak ve daha karmaşık bir hatayı aramak için zaman harcamak kolaydır.
Adam Tolley

Yanıtlar:


208

Aynı problemim vardı ve sonunda cevabı aldım ...

Sorun, POST eyleminde, formu gönderdikten sonra ModelState'in geçerli olmaması veya try / catch'da bir hata yakalamasıdır, bu nedenle Görünüm döndürülür. Ancak bu kez Görünüm ViewData["basetype"]doğru şekilde ayarlanmamış.

Muhtemelen daha önce kullanılan kodla tekrar doldurmanız gerekir, bu yüzden tekrarlayın:

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

daha önce return View(meal)de [HttpPost]bir yöntem.

tam olarak bu sorununuzu çözecektir:

[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);
    }
}

Bu sorunun çok eski olduğunu biliyorum, ama bugün buraya aynı problemle geldim, bu yüzden başkaları buraya daha sonra gelebilir ...


8
"Tekrar doldur" için +1 ... Görünüm modellerimi oluşturmak için oldukça sağlam bir sistemim var, ancak tamamen aramayı unutmuştum. Böylece, özellik doldurulmuş değildi ve ne denemek olursa olsun bu (oldukça belirsiz) mesajı aldı.
Tim Medora

8
bunu bir gönderi ÖNCE alırsanız, bunun nedeni SelectList'te hiçbir şey bulunmamasıdır.
Martin

1
+1 Çünkü gerçekten bir Html.Action başka bir Eylem Yöntemi çağrılırken dizin yönteminde ViewBag ayarlıyordum!
SwampyFox

Teşekkürler. Sadece korunmuş olsaydı güzel olurdu ama MVC "yolu" olmayacağını düşünüyorum.
Casey

eğer modeli alınıyor geçersiz ise o zaman ben kullanıcı tarafından gönderilen veri db kaydedilecek gelir? Ben de aynı sorunla karşı karşıyayım. ben bir acemiyim. Eğer Yanlışsam beni düzelt.
Koushik Saha

87

Seçim Listesi boşsa bu hatayı alırsınız.


3
Evet, bu, bir GET'te SelectList'i ayarladıktan sonra ModelState.IsValid==falsemodeli olan return View(model) ancak POST'tan geri dönmeden önce SelectList kaynağınızı doldurmamanız gereken bir POST eylemine (açıkçası) geri dönüş yaptığınızda yaygın bir hata / gözetimdir . ViewState ala WebForms olmadığından, @Html.DropDownyardımcıyla seçimi yeniden oluşturacak kaynak yoktur . Görünümü GET'te değil istemciye her döndürdüğünüzde bu kaynak listesini doldurmanız gerekir.
rism

evet bu benim sorunumdu. Get çağrısında selectList'i doldurmayı unuttum. Çok yanıltıcı hata. Harika gönderi.
Matt


1

Gelecekteki okuyucular için, ustura kullanıyorsanız, seçim listesi öğesinin türünü Liste'den IEnumerable olarak değiştirmeye çalışın.

itibaren

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

için

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

0

İlk parametre olarak açılır listenizin adı için bir dize eklemeyi deneyin ve öğeyi görünüm verilerinizden çıkarın:

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

Ayrıca, açılır listenin diğer denetimlerinizi nasıl yaptığınıza benzer bir şekilde ayarlanması için kullanabileceğiniz bir uzantı yöntemi:

        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);
    }

Örneğin

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

0

Koleksiyonu ViewData sözlüğünde bir öğe olarak ayarlıyorsunuz ve modelde özellik olarak almaya çalışıyorsunuz. Basit bir düzeltme, ayarladığınız şekilde başvurmak olacaktır:

    <%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>

Alternatif olarak, aşağıdaki kod güçlü yazılan bir görünüm kullanır:

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 });
    }

Ardından, güçlü bir şekilde yazdığınız görünümde:

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

Ben "basit düzeltme" örnek kodu kullanarak denedim ve aynı hatayı aldım. Görünümde açılır listenin doldurulduğunu söylemeliydim, ancak formu gönderdiğimde bu hatayı alıyorum.
JBibbs

Form gönderimini işleyen Controller Action kodunu gönderebilir misiniz?
Igor Zevaka

Tabii, orijinal gönderiye ekleyeceğim. Şimdilik yardımlarınız için teşekkürler.
JBibbs

0

Html.DropDownList()Yöntem kullanırsanız , ViewData / Viewbag öğeniz @Peto'nun yanıtladığı gibi ayarlanmadıysa aynı hata oluşabilir.

Ancak, denetleyici ayar öğesi doğru şekilde ayarlanmamış olabilir, ancak ana görünümde yeni ViewDataDictionary değerleriyle kısmi viw çağrısı kullanırsınız.

Eğer varsa @Html.Partial("Partianame", Model,new ViewDataDictionary() { /* ... */ })o zaman kısmi görünümü görmez ViewDatave ViewBagveri kaldırma new ViewDataDictionary()parametresi


0

Gelecekteki okuyuculara,

Bugün sorunla karşılaştım ve düzeltemedim. Sonuçta gerçekten basitti. Bir tablo + görünüm ile çalışıyordum. Tabloyu güncellediğimde (birkaç sütun ekledim), benim için soruna neden olan görünümü güncellemeyi (bırakıp yeniden oluşturmayı) unuttum. Umarım birine yardımcı olur.


0

Bugün aynı hatayı aldım ve benim çözümüm modeli "geçerli" yapmak.

Benim durumumda, kullanıcı "kaydet" i tıkladıktan sonra gönderdikten sonra, model durumu var: kullanıcı "0" girerse geçersiz, ancak kullanıcı durumu "0.0" ise model durumu geçerli olacaktır.

Bu yüzden "0" doğru kullanıcı anahtarını döndürmek için "IsValid" yöntemini geçersiz kıldım.

Umarım yardımcı olur.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.