【问题标题】:MVC: Displaying Roles in a list of checkboxes, then saving themMVC:在复选框列表中显示角色,然后保存它们
【发布时间】:2011-01-05 21:11:11
【问题描述】:

我有一个页面,其中角色显示在复选框列表中,您可以选择希望用户拥有的角色,然后单击按钮进行保存。

这是我的模型:

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()

【问题讨论】:

    标签: c# asp.net asp.net-mvc


    【解决方案1】:

    首先,当您获取页面时,您不会将模型传递给视图。这导致空引用异常。应该是:

    [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
      //....
    }
    

    【讨论】:

      【解决方案2】:

      你可以做类似的事情(有一段时间没做过了,全凭记忆):

      <% 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);
      }
      

      现在,对于每个选中的复选框,您将在数组中获得一个值。

      【讨论】:

        【解决方案3】:

        这只是部分答案,但我可以解释一下空引用异常位。

        您尚未创建 RegisterModel 类的实例。您的视图需要一个 WebUI.Models.RegisterModel,但您尚未在此代码中提供一个。

        试试:

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

        或将您的 Roles 属性设为静态:

        public static string[] Roles

        并以这种方式在您的视图中访问:

        foreach(string role in RegisterModel.Roles)

        【讨论】:

          【解决方案4】:

          为了可测试性和合理性,我会将您的模型更改为不直接尝试获取角色,而是在构造函数中获取角色列表。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2020-11-20
            • 1970-01-01
            • 2016-03-23
            • 2015-03-09
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多