2011-01-05 115 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. 我是否通过我的模型正确地传递角色?还是应该通过我的Controller动作将角色作为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); 
} 

现在每个检查复选框,你会在数组中获得一个值。

0

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

您还没有创建RegisterModel类的实例。您的视图期待WebUI.Models.RegisterModel,但您在此代码中没有提供。

尝试之一:

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

或让你的角色属性静态:

public static string[] Roles

并且在视图的访问是这样的:

foreach(string role in RegisterModel.Roles)

0

可测性和理智,我会改变你的模型不伸手试图抓住直接的作用,而是采取在构造函数中角色的列表。

相关问题