ASP.NET MVC 3 - ViewModel&刷新 - 问题

时间:2011-03-09 17:34:51

标签: jquery asp.net-mvc asp.net-mvc-3 refresh viewmodel

我被困在ViewModel绑定和刷新场景中。

方案: 作为管理员,我想创建用户帐户,并根据DropDownList刷新FORM中的选定角色,通过复选框选择与Role连接的特定访问(bool)。

因此,用户可以拥有一个具有默认访问权限列表的角色,管理员在创建帐户时可以对其进行修改。

我的ViewModel:

public class CreateViewModel
{
    public User User { get; set; }
    public IEnumerable<Role> Roles { get; set; }
    public IEnumerable<RoleAccess> RoleAcceses { get; set; }
    public Role SelectedRole { get; set; }


    public void Refresh()
    {
        User.UserAccesses.Clear();
        foreach (var item in RoleAcceses.Where(x => x.RoleId == SelectedRole.Id))
        {
            User.UserAccesses.Add(new UserAccess { UserId = User.Id, Access = item.Access, AccessId = item.AccessId, Value = item.Value });
        }
    }
}

正如您在上面的代码中看到的,我有RoleAccess集合,其中包含特定Role的默认值。 Refresh方法清除实际的UserAccess集合并为SelectedRole重新填充它。

我的问题是:

  1. 没有jQuery可以做到这一点吗?你有什么看法?
  2. 如果可以在没有jQuery的情况下刷新FORM而不放弃Admin输入的Binded值? 在这里我不能添加其他的@BeginForm,因为我会丢失实际的数据上下文吗?
  3. 如果jQuery只是解决方案如何编写将检查jQuery过滤的Controller Action?
  4. jQuery函数应该如何将Binded替换为ViewModel复选框?
  5. 我的courrent控制器动作:

    public class AccountController : Controller
    {
        IAccountService accountService;
    
        public AccountController()
        {
            accountService = new AccountService();
        }
    
        [HttpGet]
        public ActionResult Create(int role = 1)
        {
            IEnumerable<RoleAccess> roleAccesses = null;
            IEnumerable<Role> roles = null;
    
            roleAccesses = accountService.GetRoleAcgesses();
            roles = accountService.GetRoles();
    
            var createViewModel = new CreateViewModel();
            createViewModel.RoleAcceses = accountService.GetRoleAccesses();
            createViewModel.Roles = accountService.GetRoles();
            createViewModel.SelectedRole = createViewModel.Roles.FirstOrDefault(x => x.Id == role);
            createViewModel.Refresh();
    
            return View(createViewModel);
        }
    
        public ActionResult Refresh(int role)
        {
            return RedirectToAction("Create", "Account", new { role });
        }
    
        [HttpPost]
        public ActionResult Create([Bind(Prefix = "User")] Models.User user, FormCollection formsCollection)
        {
            var viewModel = new CreateViewModel();
            UpdateModel<CreateViewModel>(viewModel, new[] { "User.Login", "User.Password", "User.FirstName", "User.LastName" });
    
            viewModel.User.RoleId = Convert.ToInt32(formsCollection["Role"]);
    
            if (ModelState.IsValid)
            {
                bool result = accountService.CreateAccount(viewModel.User);
    
                if (!result)
                {
                    // SEND INFO ABOUT FAILURE
                }
                else
                {
                    return RedirectToAction("list");
                }
            }
    
            return View();
        }
    
        [HttpGet]
        public ActionResult List()
        {
            var accounts = accountService.GetAccounts();
            var viewModel = new ListViewModel() { Accounts = accounts };
            return View(viewModel);
        }
    }
    

    我的观点:

    @model VDOT.Web.AccountViewModels.CreateViewModel
    @{
        ViewBag.Title = "Create";
    }
    <h2>Create</h2>
    <script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
    
    @using (Html.BeginForm("create", "account"))
    {
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>CreateViewModel</legend>
        <fieldset>
            <div class="editor-label">
                @Html.LabelFor(model => model.User.Login)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.User.Login)
                @Html.ValidationMessageFor(model => model.User.Login)
            </div>
            <div class="editor-label">
                @Html.LabelFor(model => model.User.Password)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.User.Password)
                @Html.ValidationMessageFor(model => model.User.Password)
            </div>
            <div class="editor-label">
                @Html.LabelFor(model => model.User.FirstName)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.User.FirstName)
                @Html.ValidationMessageFor(model => model.User.FirstName)
            </div>
            <div class="editor-label">
                @Html.LabelFor(model => model.User.LastName)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.User.LastName)
                @Html.ValidationMessageFor(model => model.User.LastName)
            </div>
            <div class="editor-field">
                <select id="paging" onchange="location.href=this.value">
                    @foreach (var item in Model.Roles)
                    {
                        <option value="@Url.Action("create", "account", new { role = item.Id })">
                            @item.Name
                        </option>
                    }
                </select>
            </div>
            <div class="editor-field">
                @foreach (var item in Model.User.UserAccesses)
                {
                    @Html.CheckBox(item.Access.Name, item.Value);
                    <br />
                }
            </div>
        </fieldset>
    </fieldset>
    <fieldset>
        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
    }
    

    感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

我认为您正在寻找一种将用户访问集合绑定到用户视图模型的方法。有了这个,你的完整模型将在post post上持久化,允许你在没有脚本的情况下实现所需的任何功能(尽管你可以使用jQuery,如果可用的话)来增强页面以获得“更流畅”的功能。

Steven Sanderson's blog, here上提供了一种创建模型列表属性绑定的好方法。