Unable to bind ViewData to a dropdown list

419 views Asked by At

I am working on an asp.net mvc 4 application where I am trying to add delete a user functionality for an admin where I should be able to select a user from dropdown list and delete him.

private static IEnumerable<SelectListItem> getUsers()
        {
            WhiteBoardAppContext db = new WhiteBoardAppContext();
            IEnumerable<SelectListItem> numbers = (from i in db.UserProfiles                           
                           select new SelectListItem
                           { Text= i.UserName,
                           Value=i.UserId.ToString()
                           });
            return numbers.ToList();
        }


        [Authorize(Roles = "Admin")]
        public ActionResult DeleteUser()
        {
          var list = (IEnumerable<SelectListItem>)ViewData["UserList"];
           list = getUsers();          

            return View();
        }

 [HttpPost]
        [ValidateAntiForgeryToken]
        [Authorize(Roles = "Admin")]
        public ActionResult DeleteUser(UserProfile model)
        {



            if (ModelState.IsValid)
            {

                try
                {
                    if (model.UserName == null)
                    {
                        TempData["ErrorMessage"] = "Username required.";
                        return RedirectToAction("Register", "Account");
                    }
                    else
                    {

                        var user = Membership.GetUser(model.UserName);
                        if (user == null)
                        {
                            TempData["ErrorMessage"] = "User Does Not exist.";
                            return RedirectToAction("Register", "Account");
                        }
                        else
                        {
                            Membership.DeleteUser(model.UserName);

                        }
                        return RedirectToAction("Register", "Account");
                    }
                }
                catch (MembershipCreateUserException e)
                {
                    ModelState.AddModelError("", ErrorCodeToString(e.StatusCode));
                }
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }

DeleteUser.cshtml

@model WhiteBoardApp.Models.UserProfile


@using (Html.BeginForm("DeleteUser", "Account"))
{
    @Html.AntiForgeryToken()
    @Html.ValidationSummary()

    <fieldset>
        <div class="container-fluid">
            <ol>
                <li>

                    @Html.LabelFor(m => m.UserName)
                     @Html.DropDownList("UserList", (IEnumerable<SelectListItem>)ViewData["UserList"])
                    <span style="color:red;">@TempData["ErrorMessage"]</span>
                </li>

            </ol>
            <input type="submit" value="Delete User" />
            </div>
</fieldset>
}

But, the above code threw me There is no ViewData item of type 'IEnumerable<SelectListItem>' that has the key 'UserList'.

May I know where I was wrong?

1

There are 1 answers

1
Alex Art. On

You need to add your users to the ViewData dictionary:

[Authorize(Roles = "Admin")]
public ActionResult DeleteUser()
{
     ViewData["UserList"] = getUsers();       
     return View();
}

Also your usage of DropDownList helper is wrong since the first parameter should be a name of input that is going to contain selected user and not a select list itself.

in your case var list = (IEnumerable<SelectListItem>)ViewData["UserList"]; will return null so there is no actual assignment.

But in general I would advise you not to use ViewData but create a VieModel and put all the required data there:

public class DeleteUserViewModel
{
    public IList<SelectListItem> UserList {get;set;}

    public int SelectedUserId {get;set;}
} 

Controller :

[Authorize(Roles = "Admin")]
[HttpGet]
public ActionResult DeleteUser()
{
     var model = new DeleteUserViewModel{
        UserList = getUsers()
     };      
     return View(model);
}

[HttpPost]
public ActionResult DeleteUser(DeleteUserViewModel model)
{
     int userToDelete = model.SelectedUserId;
     //delete user logic here
}

View:

@model WhiteBoardApp.Models.DeleteUserViewModel


@using (Html.BeginForm("DeleteUser", "Account"))
{
@Html.AntiForgeryToken()
@Html.ValidationSummary()

<fieldset>
    <div class="container-fluid">
        <ol>
            <li>

                @Html.LabelFor(m => m.UserName)
                @Html.DropDownListFor(m=>m.SelectedUserId, Model.UserList )
                <span style="color:red;">@TempData["ErrorMessage"]</span>
            </li>

        </ol>
        <input type="submit" value="Delete User" />
        </div>
</fieldset>
}