Я выполняю роли пользователя в MVC6 (используя EF7), и я думаю, что я просто что-то упустил, но в форме, используемой для определения ролей пользователя, я ничего не получаю в опубликованной обратной модели контроллерПолучение данных CheckList в сообщении MVC6
Это моя модель
public class UserRoleItem
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public IdentityUserRole<int> userRole { get; set; }
public bool HasRole { get; set; }
}
public class UsersRolesViewModel
{
public int UserId { get; set; }
public string FullName { get; internal set; }
public List<UserRoleItem> UserRoles;
}
Это мнение
@model Skill.ViewModels.Manage.UsersRolesViewModel
<br />
<h3>Set Roles for user - @Model.FullName</h3>
<form asp-action="ChangeUsersRoles" >
<div class="form-horizontal">
<hr />
<input type="hidden" asp-for="UserId" />
@foreach (var userRole in Model.UserRoles)
{
<input type="hidden" asp-for="@userRole.Id" />
<div class="form-group">
<div class="inline-block col-md-8">
<span class="col-md-1" align="center">
<input type="checkbox" asp-for="@userRole.HasRole" />
</span>
<div class="col-md-7">
@userRole.Name (@userRole.Description)
</div>
</div>
</div>
}
<hr />
<div class="form-group">
<div class="col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
</form>
Это контроллер
// GET: Users/ChangeUserRoles/5
public async Task<IActionResult> ChangeUserRoles(int? id)
{
if (id == null)
{
return HttpNotFound();
}
var model = new UsersRolesViewModel();
ApplicationUser appUser = await _context.ApplicationUsers.SingleAsync(m => m.Id == id);
if (appUser == null)
{
return HttpNotFound();
}
else
{
model.UserId = (int)id;
model.FullName = appUser.FullName;
var some = from r in _context.Roles
from ur in _context.UserRoles
.Where(inner => r.Id == inner.RoleId && inner.UserId == id)
.DefaultIfEmpty()
select new UserRoleItem
{
Id = (int)r.Id,
Name = r.Name,
Description = r.NormalizedName,
userRole = ur, // this is needed else it has a hissy fit
HasRole = (ur != null)
};
// get all of the Roles and then also link to the ones the user currently has
model.UserRoles = (some).ToList();
}
return View(model);
}
// POST: Users/ChangeUserRoles/5
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> ChangeUserRoles([Bind(include:"UserId,UserRoles")]UsersRolesViewModel userModel)
{
if (ModelState.IsValid)
{
// update based on the changes
// return RedirectToAction("Edit", new { userModel.UserId });
}
return View(userModel);
}
Так что, когда я получаю сообщение обратно в Save, список UserRoles имеет значение NULL, поэтому я предполагаю, что здесь просто отсутствует очевидная вещь?
Также еще одна небольшая проблема - заявление EF Linq. Если я удалю заявление
userRole = ur,
от Выбрать части запроса Linq, система имеет истерику и говорит моя схема устарела (что это не так). Я думаю, что это связанно со следующим утверждением, где я тестированием внешнего соединения значения,
HasRole = (ur != null)
Хотя это кажется вполне разумным и работает, если переменная Ур используются перед тестированием на нуль (или нет)
Вы не можете использовать цикл foreach для создания элементов управления формы для коллекции (если вы проверите html, вы увидите, что ваши входы имеют одинаковый атрибут name, который не имеет отношения к вам). Используйте цикл 'for' или' EditorTemplate' для 'UserRoleItem' для создания правильных атрибутов' name' с индексаторами. Для примера, использующего цикл 'for', см. [Этот ответ] (http://stackoverflow.com/questions/29542107/pass-list-of-checkboxes-into-view-and-pull-out-ienumerable/29554416# 29554416) –
Спасибо Стивен. После того, как я ввел проблему, я фактически изменил код для использования EditorTemplates, а затем массив данных был правильно сгенерирован. Может быть, я должен загрузить решение для потомков? –
Добавьте свой ответ и примите его, чтобы закрыть это. :) –