2011-01-05 5 views
3

У меня есть страница, где роли отображаются в списке флажков, вы можете выбрать роли, которые хотите, чтобы пользователь имел, а затем нажмите кнопку, чтобы сохранить Это.MVC: отображение ролей в списке флажков, а затем их сохранение

Вот моя модель:

public class RegisterModel 
{ 
    [DisplayName("Roles")] 
    public string[] Roles 
    { 
     get 
     { 
      return System.Web.Security.Roles.GetAllRoles(); 
     } 
     set { } 
    } 
} 

Мое мнение:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<WebUI.Models.RegisterModel>" %> 

<% using (Html.BeginForm()) { %> 
    <% foreach(string role in Model.Roles) { %> 
     <input type="checkbox" value="<%: role %>" /> <%: role %> 
    <% } %> 

    <p> 
     <input type="submit" value="Register" /> 
    </p> 
<% } %> 

И функции из моего контроллера:

public ActionResult Register() 
{ 
    return View(); 
} 

[HttpPost] 
public ActionResult Register(RegisterModel model) 
{ 
    if (ModelState.IsValid) 
    { 
     //save roles 
     return RedirectToAction("Index", "Home"); 
    } 

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

Когда я пытаюсь просматривать мою страницу, я получаю Ошибка «Ссылка на объект не установлена ​​на экземпляр объекта» в инструкции foreach, означающая, что Model.Roles пуст.

  1. Я правильно передаю Роли через свою модель? Или я должен передавать роли как ViewData через действие моего контроллера?
  2. Если я передаю роли как ViewData, а не через мою модель, как я могу получить доступ к выбранным элементам при отправке формы, чтобы я мог позвонить Roles.AddUsersToRoles()?

ответ

3

Прежде всего, вы не передаете свою модель в представление, когда получаете страницу. Это вызывает исключение нулевой ссылки. Оно должно быть:

[HttpGet] 
public ActionResult Register() { 

    //create an instance of your model however you are doing that 
    var model = new RegisterModel(); 

    //pass your model instance to your view 
    return View(model); 
} 

Во-вторых, вам нужно добавить атрибут name ваших входов для того, чтобы модель MVC связывания для передачи данных, когда форма размещена.

<% foreach(string role in Model.Roles) { %> 
    <input type="checkbox" name="Roles" value="<%: role %>" /> <%: role %> 
    <% } %> 

Однако, как ваше Roles свойство появляется не иметь сеттер вы, вероятно, следует создать модель представления, содержащий роли так, что ваш код должен выглядеть следующим образом:

Посмотреть модель

public class RegisterViewModel { 
    public string[] Roles { get; set; } 
    //...other properties 
} 

Просмотр

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<WebUI.ViewModels.RegisterViewModel>" %> 

<% using (Html.BeginForm()) { %> 
    <% foreach(string role in Model.Roles) { %> 
    <input type="checkbox" name="Roles" value="<%: role %>" /> <%: role %> 
    <% } %> 

    <p><input type="submit" value="Register" /></p> 
<% } %> 

Контролер

[HttpGet] 
public ViewResult Index() { 
    var model = new RegisterViewModel(); 
    model.Roles = System.Web.Security.Roles.GetAllRoles(); //or however you populate your roles 
    return View(model); 
} 

[HttpPost] 
public ActionResult Index(RegisterViewModel model) { 
    string[] roles = model.Roles //the selected roles are here 
    //.... 
} 
0

Вы можете сделать что-то подобное (не сделал это в то время, все из памяти):

<% foreach(string role in Model.Roles) { %> 
    <input type="checkbox" name="roles" value="<%: role %>" /> <%: role %> 
<% } %> 

И в контроллере:

[HttpPost] 
public ActionResult Register(string[] roles) 
{ 
    if (ModelState.IsValid) 
    { 
     //save roles 
     return RedirectToAction("Index", "Home"); 
    } 

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

И теперь для каждого проверяемого checkbox вы получите значение в массиве.

0

Это лишь частичный ответ, но я могу объяснить бит исключающего исключения.

Вы не создали экземпляр своего класса RegisterModel. Ваше мнение ожидает WebUI.Models.RegisterModel, но вы не указали его в этом коде.

Попробуйте также:

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

или сделать вашу собственность Роли статические:

public static string[] Roles

и доступ на ваш взгляд, таким образом:

foreach(string role in RegisterModel.Roles)

0

Для проверки и здравомыслия я бы изменил вашу модель, чтобы не протянуть руку и не попытаться захватить роли напрямую, а скорее взять список ролей в конструкторе.

Смежные вопросы