Я попал в сценарий привязки ViewModel и обновления.
Сценарий:
Как администратор я хочу создать учетную запись пользователя и на основе выбранной роли из DropDownList обновить ФОРМУ, чтобы выбрать с помощью флажков определенные доступы (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 со значениями по умолчанию для конкретной роли. Метод Refresh очищает фактическую коллекцию UserAccess и повторно заполняет ее для SelectedRole.
Мои вопросы:
- Возможно ли сделать это без jQuery? Каково ваше мнение?
- Если возможно обновить FORM без jQuery, как опубликовать его без потери значений, введенных администратором?
Здесь я не могу добавить другой @BeginForm, потому что я потеряю фактический контекст данных, верно?
- Если jQuery - единственное решение, как написать действие контроллера, которое проверяет фильтрацию jQuery?
- Как должна выглядеть функция jQuery для замены флажков Binded to ViewModel?
Мой Куррент-контроллер Действие:
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);
}
}
My View:
@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>
}
Спасибо за любую помощь!