没有类型&#39; IEnumerable <selectlistitem>&#39;的ViewData项目。具有键&#39; CategoryID </selectlistitem>

时间:2014-03-17 08:12:19

标签: asp.net-mvc

我在这个问题上发现了很多类似的线程。但无论我做什么,它都不适合我。

我现在想要实现的唯一的事情是在局部视图中填充包含数据库值的下拉列表,这是在局部视图中。这就是全部,这让我绝对疯狂。用户应该能够在下拉列表中选择类别名称。

这是我的控制器类:

public class AttributeController : Controller
{
    private readonly IRepository<ClassLibrary.Entities.Attribute> _aRepository;
    private readonly IRepository<Category> _cRepository;

    public AttributeController() : this(new Repository<ClassLibrary.Entities.Attribute>(), new Repository<Category>())
    { 
    }

    public AttributeController(IRepository<ClassLibrary.Entities.Attribute> repo, IRepository<Category> repository)
    {
        _aRepository = repo;
        _cRepository = repository;
    }

    //
    // GET: /Attribute/
    public ActionResult Index()
    {
        var attributes = _aRepository.GetAll();
        var attributeViewModels = new List<AttributeViewModel>();

        foreach (ClassLibrary.Entities.Attribute attribute in attributes)
        {
            var viewModel = new AttributeViewModel();
            viewModel.Id = attribute.Id;
            viewModel.AttributeName = attribute.Name;
            attributeViewModels.Add(viewModel);
        }



        return View(attributeViewModels);
    }

    //
    // GET: /Attribute/Details/5
    public ActionResult Details(int id)
    {
        return View();
    }

    //
    // GET: /Attribute/Create
    public ActionResult Create()
    {
        ViewData["CategoryID"] = new SelectList(_cRepository.GetAll().ToList(), "Category_id", "Category");
        IEnumerable<SelectListItem> items = _cRepository.GetAll().Select(c => new SelectListItem
                                            {
                                                Value = c.Id.ToString(),
                                                Text = c.Name
                                            });

        ViewData["CategoryID"] = items;

        return View();
    }

    //
    // POST: /Attribute/Create
    [HttpPost]
    public ActionResult Create(FormCollection collection)
    {
        try
        {
            // TODO: Add insert logic here

            return RedirectToAction("Index");
        }
        catch
        {
            return View();
        }
    }

这是索引视图:

@model IEnumerable<GUI.Models.AttributeViewModel>

@{
  ViewBag.Title = "Attributes";
 }

<div>
@Html.Partial("~/Views/Attribute/Create.cshtml", new GUI.Models.AttributeViewModel())
</div>

<h2>All existing Attributes</h2>



<table class="table">
<tr>
    <th>
        @Html.DisplayNameFor(model => model.AttributeName)
    </th>
    <th></th>
 </tr>

@if(Model != null)
{ 
  foreach (var item in Model) {
<tr>
    <td>
        @Html.DisplayFor(modelItem => item.AttributeName)
    </td>
    <td>
        @Html.ActionLink("Edit", "Edit", new { id=item.Id }) |
        @Html.ActionLink("Details", "Details", new { id=item.Id }) |
        @Html.ActionLink("Delete", "Delete", new { id=item.Id })
    </td>
</tr>
}
}

</table>

这是索引视图中的部分视图:

@model GUI.Models.AttributeViewModel


@using (Html.BeginForm()) 
{
@Html.AntiForgeryToken()

<div class="form-horizontal">
    <h4>Create an attribute for this Category</h4>
    <hr />
    @Html.ValidationSummary(true)

    <div class="form-group">
        @Html.Partial("~/Views/Attribute/CategoryPartial.cshtml", new  GUI.Models.CategoryViewModel())
    <div class="form-group">
        @Html.LabelFor(model => model.AttributeName, new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.AttributeName)
            @Html.ValidationMessageFor(model => model.AttributeName)
        </div>
    </div>


    </div>
    </div>
  }


  @section Scripts {
  @Scripts.Render("~/bundles/jqueryval")
  }

最后在部分视图中的CategoryPartialView将包含DropDown List,其中用户应该能够选择类别名称。

@model GUI.Models.CategoryViewModel
@using GUI.Controllers

@using System.Collections.Generic
@{
//var categories = (IEnumerable<GUI.Models.CategoryViewModel>)ViewData["categories"];
 }


@using (Html.BeginForm()) 
{
@Html.AntiForgeryToken()



    <hr />
    @Html.ValidationSummary(true)

    <div class="form-group">
        @Html.LabelFor(model => model.Name, new { @class = "control-label col-md-2" })
        <div class="col-md-10">
          @Html.DropDownList("CategoryID", (IEnumerable<SelectListItem>)ViewData["CategoryID"])
        </div>
    </div>     


   }

异常总是在我调试应用程序时发生,它指向@ Html.DropDownList部分。声称“没有类型'IEnumerable'的ViewData项具有'CategoryID'键。

@Html.DropDownList("CategoryID", (IEnumerable<SelectListItem>)ViewData["CategoryID"]

我很抱歉发布了这么多代码块。但是我真的很想解决这个问题。我已经沮丧地把头撞到墙上几个小时了,任何帮助都会非常感激。

2 个答案:

答案 0 :(得分:1)

使用@Html.Partial("~/Views/Attribute/CategoryPartial.cshtml", new GUI.Models.CategoryViewModel())时,您将直接实例化部分视图。控制器不会被调用,也不负责生成HTML标记字符串。此外,您正在传递一个空视图模型(new GUI.Models.CategoryViewModel())。由于控制器未被调用,因此它不会获取下拉列表的数据,显然不会将其保存在ViewData中。

改为使用@Html.Action助手:

<div class="form-group">
    @Html.Action("Create", "Attribute")
<div class="form-group">

像这样更改Create操作:

//
// GET: /Attribute/Create
public ActionResult Create()
{
    ViewData["CategoryID"] = new SelectList(_cRepository.GetAll().ToList(), "Category_id", "Category");
    IEnumerable<SelectListItem> items = _cRepository.GetAll().Select(c => new SelectListItem
                                        {
                                            Value = c.Id.ToString(),
                                            Text = c.Name
                                        });

    ViewData["CategoryID"] = items;

    return PartialView("CategoryPartial", new GUI.Models.CategoryViewModel());
}

注意:我不了解您的整个结构,但我最好使用此方法并返回Lis<SelectListItem>模型。

答案 1 :(得分:0)

致电时:

@Html.Partial("~/Views/Attribute/Create.cshtml", new GUI.Models.AttributeViewModel())

你直接调用视图而没有通过抛出控制器,所以你在那里的模型是一个空模型!

尝试传递控制器来创建你的模型并将其作为视图发回:

@Html.RenderPartial("YOUR CONTROLLER",model);