Регистрационная форма с ролями MVC3, ошибка: элемент ViewData имеет тип "system.sting" должен быть "IEnumerable <selectlistitem> - PullRequest
0 голосов
/ 05 января 2012

Я использую MVC3 с бритвой, и я хочу создать регистрационную форму, где я могу выбрать роль с помощью раскрывающегося списка.

Я получаю роли в раскрывающемся списке и все такое, но когда я нажимаю кнопку "Отправить",:

Элемент ViewData, имеющий ключ 'Роль', имеет тип System.String, но должен иметь тип IEnumerable<SelectListItem>.

Мой код

Модель:

[Required]
    [Display(Name = "Select role: ")]
    public String Role { get; set; }

Мой контроллер:

public ActionResult Register()
    {
        List<SelectListItem> list = new List<SelectListItem>();
        SelectListItem item;
        foreach (String role in Roles.GetAllRoles())
        {
            item = new SelectListItem{ Text = role, Value = role};
            list.Add(item);
        }

        ViewBag.roleList = (IEnumerable<SelectListItem>)list;
        return View();
    }

Мой почтовый контроллер:

[HttpPost]
    public ActionResult Register(RegisterModel model)
    {
        if (ModelState.IsValid)
        {
            // Attempt to register the user
            MembershipCreateStatus createStatus;
            Membership.CreateUser(model.UserName, model.Password, model.Email, null, null, true, null, out createStatus);

            if (createStatus == MembershipCreateStatus.Success)
            {
                Roles.AddUserToRole(model.UserName, model.Role);
                return RedirectToAction("Index", "Home");
            }
            else
            {
                ModelState.AddModelError("", ErrorCodeToString(createStatus));
            }
        }

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

Мой взгляд:

<div class="editor-label">
            @Html.LabelFor(m => m.Role)
        </div>
        <div class="editor-field">
            @Html.DropDownListFor(m => m.Role, ViewBag.roleList as IEnumerable<SelectListItem>)
            @Html.ValidationMessageFor(m => m.Role)

        </div>

Когда я используюотладчик для проверки моего кода, в контроллере, когда я смотрю на модель параметров и на model.Role я вижу правильную строку.Кто-нибудь знает решение моей проблемы?

1 Ответ

3 голосов
/ 06 января 2012

В вашем действии POST вы не заполняете roleList в ViewBag в случае, когда вы повторно отображаете представление:

...
// If we got this far, something failed, redisplay form

// but before redisplaying the form ensure that we have populated the 
// ViewBag.roleList that this form depends on
ViewBag.roleList = ... same stuff as your GET action
return View(model);

При этом я бы порекомендовал вам избавиться от ViewBag и добавить свойство RoleList в модель представления:

public class RegisterModel
{
    [Required]
    [Display(Name = "Select role: ")]
    public string Role { get; set; }

    public IEnumerable<SelectListItem> RoleList
    {
        get
        {
            return Roles
                .GetAllRoles()
                .Select(x => new SelectListItem
                {
                    Value = x,
                    Text = x
                })
                .ToList();
        }
    }
}

и затем:

public ActionResult Register()
{
    var model = new RegisterModel();
    return View(model);
}

[HttpPost]
public ActionResult Register(RegisterModel model)
{
    if (ModelState.IsValid)
    {
        // Attempt to register the user
        MembershipCreateStatus createStatus;
        Membership.CreateUser(model.UserName, model.Password, model.Email, null, null, true, null, out createStatus);
        if (createStatus == MembershipCreateStatus.Success)
        {
            Roles.AddUserToRole(model.UserName, model.Role);
            return RedirectToAction("Index", "Home");
        }
        else
        {
            ModelState.AddModelError("", ErrorCodeToString(createStatus));
        }
    }

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

и в вашем строго типизированном виде:

@model RegisterModel
...

<div class="editor-label">
    @Html.LabelFor(m => m.Role)
</div>
<div class="editor-field">
    @Html.DropDownListFor(m => m.Role, Model.RoleList)
    @Html.ValidationMessageFor(m => m.Role)
</div>

Нет больше ViewBag => нет проблем.

...