0

This is my first time posting and I'm a total beginner to coding and MVC.

I'm trying to create a filtering system to filter the user's posts. My logic is to allow the user to search for a keyword, by username and by category name. The user can use a keyword and/or username and/or category name. The keyword is a simple TextBoxFor and the username and category are DropDownLists. When I'm running the code with only the keyword TextBoxFor and only one DropDownList everything is working fine, however when I use the other DropDownList I will get this error.

The ViewData item that has the key 'UserID' is of type 'System.String' but must be of type 'IEnumerable'.

I've made a bit of research and I've came to the conclusion that the UserID DropDownList is giving a null value. The only thing I could think of is maybe giving the UserID a default value, however I couldn't manage to do it. Is there a better way to do it instead of giving it a default value? If no, how can I manage to do it?

Thanks , bobdbuider

My ViewModel:

public class DTOSearchModel
    {

        #region Properties
        public string Keyword { get; set; }

        [Display(Name = "Username")]
        public string UserID { get; set; }

        [Display(Name = "Category Name")]
        public int CategoryID { get; set; }

        public List<Models.PostTable> PostResults { get; set; }
        #endregion

        public DTOSearchModel()
        {

            Keyword = "";
            UserID = "Select a Username";
            CategoryID = 0;

            PostResults = new List<Models.PostTable>();

        }

    }
}

My Controller:

//POST Search
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Index(DTOSearchModel model)
        {
            if (ModelState.IsValid)
            {
                var postTables = db.PostTables.Include(p => p.AspNetUser).Include(p => p.CategoryTable).Include(p => p.StatusTable);
                var posts = postTables.ToList();

                //CategoryID
               if (model.CategoryID !=0)
                    {
                    ViewBag.CategoryID = new SelectList(db.CategoryTables, "CategoryID", "CategoryName");
                    posts = posts.Where(k => k.CategoryID.Equals(model.CategoryID)).ToList();
                }

               //UserID


                    ViewBag.UserID = new SelectList(db.AspNetUsers, "Id", "Email" ,"Select");
                    posts = posts.Where(k => k.UserID.Equals(model.UserID)).ToList();



                //Keyword
                if  (!String.IsNullOrEmpty(model.Keyword))
                {
                    posts = posts.Where(k => k.Title.ToLower().Contains(model.Keyword.ToLower()) || k.Body.ToLower().Contains(model.Keyword.ToLower())).ToList();

                }

                model.PostResults = posts;

            }

            return View(model);

        }
    }
}

My View:

<div class="col-md-3">
                    @Html.LabelFor(model => model.Keyword)
                    @Html.TextBoxFor(model => model.Keyword, htmlAttributes: new { @class = "form-control" })
                </div>


                <div class="col-md-4">
                    @Html.LabelFor(model => model.UserID)
                    @Html.DropDownList("UserID", null, htmlAttributes: new { @class = "form-control" })
                </div>


                <div class="col-md-4">
                    @Html.LabelFor(model => model.CategoryID)
                    @Html.DropDownList("CategoryID" , null, "Select a Category Name", htmlAttributes: new { @class = "form-control" })
                </div>

1 Answers1

1

You should not use the same property name in the ViewBag and your model. You have a UserID property of type string in your model and you also have a UserID of type SelectList in the ViewBag. Your view is using the one from your model which is of type string but DropDownList requires an IEnumerable so you are getting this error:

The ViewData item that has the key 'UserID' is of type 'System.String' but must be of type 'IEnumerable'.

You should try and not use ViewBag but instead create a model specifically for your view which has everything your view requires and then use it in your view. Please see this answer for more details.

Community
  • 1
  • 1
CodingYoshi
  • 25,467
  • 4
  • 62
  • 64
  • Thanks for the fast and detailed answer. I've changed UserID in my view model to Username , so they will be different. I've also tried changing CategoryID in my view model, however it gave me an error so I've kept it as CategoryID. The problem now is that I'm always getting that I have 0 posts that match with the username and/or category. I've also tested the User filter alone and it is not working as well, so the problem is with the change I made to the Viewmodel. – bobdbuilder May 20 '17 at 17:42
  • Did you see the code in the link I refered you to? There is a fiddle which shows how to create dropdown. Please go study that code closely and it will help your resolve the issue you are having. – CodingYoshi May 20 '17 at 17:51
  • Yes , I've took a look at the Fiddle. I'm just asking this question because I was told otherwise. Isn't it bad practice to give the values yourself instead of letting the ViewBag getting them from the database? For example: If I want to add a category or username , I need to add the entry myself in the newSelectListItem. – bobdbuilder May 20 '17 at 17:54
  • No you can create a property of type IEnumerable or SelectList in a model and then fill it from the database. Then use the property in your view. See [this](http://odetocode.com/blogs/scott/archive/2013/03/11/dropdownlistfor-with-asp-net-mvc.aspx) – CodingYoshi May 20 '17 at 18:05