Задать вопрос
@Plasmat1x
Зеленый программист/системный администратор

Как из View передать в котроллер коллецию на пост запрос?

View
@{

}

@model IEnumerable<UserRoleViewModel>

<div>
    <h1>@Model.First().UserName</h1>

    <div>
        <form asp-area="admin" asp-controller="Users" asp-action="AddRole" asp-route-id="@Model.First().Id" method="post">

            @foreach(var entt in Model)
            {
                <div asp-for="@entt">
                    <input type="hidden" asp-for="@Model.First().Id">
                    <input type="hidden" asp-for="@Model.First().UserName">
                    <input type="hidden" asp-for="@Model.First().RoleName">
                    <label asp-for="@entt.RoleName">@entt.RoleName</label>
                    <input type="checkbox" asp-for="@entt.IsSelected" />
                </div>
            }
            <input type="submit" value="Accept" />
        </form>
    </div>
</div>


Controller

public async Task<IActionResult> AddRole(Guid id, CancellationToken ct)
        {
            var user = await userMgr.FindByIdAsync(id.ToString());

            List<UserRoleViewModel> model = new List<UserRoleViewModel>();

            foreach (var role in roleMgr.Roles)
            {
                if (await userMgr.IsInRoleAsync(user, role.Name))
                {
                    model.Add(new UserRoleViewModel { Id = id, UserName = user.UserName, RoleName = role.Name, IsSelected = true });
                }
                else
                {
                    model.Add(new UserRoleViewModel { Id = id, UserName = user.UserName, RoleName = role.Name, IsSelected = false });
                }
            }

            return await Task.Run(() => View(model), ct);
        }

        [HttpPost]
        public async Task<IActionResult> AddRole(IEnumerable<UserRoleViewModel> model, Guid id, CancellationToken ct)
        {

            var user = await userMgr.FindByIdAsync(id.ToString());

            if (ModelState.IsValid)
            {
                List<string> inroles = new List<string>();
                List<string> exroles = new List<string>();

                foreach (var entt in model)
                {
                    if (entt.IsSelected)
                        inroles.Append(entt.RoleName);
                    else
                        exroles.Append(entt.RoleName);
                }

                var exres = await userMgr.RemoveFromRolesAsync(user, exroles);
                var inres = await userMgr.AddToRolesAsync(user, inroles);

                if (exres.Succeeded && inres.Succeeded)
                {
                    return RedirectToAction(nameof(UsersController.User), nameof(UsersController).CutController(), new { area = "Admin", Id = id });
                }
            }

            return await Task.Run(() => View(model), ct);
        }


Model
public class UserRoleViewModel
    {
        [Required]
        public Guid Id { get; set; }

        [Required]
        [Display(Name = "User")]
        public string UserName { get; set; }

        [Required]
        [Display(Name = "Role")]
        public string RoleName { get; set; }

        [Required]
        public bool IsSelected { get; set; }
    }


по кнопке передает ID но коллекция пустая.

P.S. поменял view, исключения нет но и изменения не приходят
  • Вопрос задан
  • 91 просмотр
Подписаться 2 Средний 3 комментария
Решения вопроса 1
@Plasmat1x Автор вопроса
Зеленый программист/системный администратор
Решение:
@model UserRolesViewModel

@{

}

<div>
    <h1>@Model.UserName</h1>

    <div>
        <form asp-area="admin" asp-controller="Users" asp-action="AddRole" method="post" enctype="multipart/form-data">
            <input type="hidden" asp-for="@Model.Id" />
            <input type="hidden" asp-for="@Model.UserName" />

            @foreach (var key in Model.RoleChecked.Keys)
            {
                <div>
                    <label asp-for="RoleChecked[key]">@key</label>
                    <input type="checkbox" asp-for="RoleChecked[key]"/>
                </div>
            }
            <input type="submit" value="Accept" />
        </form>
    </div>
</div>


public async Task<IActionResult> AddRole(Guid id, CancellationToken ct)
        {
            var user = await userMgr.FindByIdAsync(id.ToString());

            var model = new UserRolesViewModel();

            model.Id = id;
            model.UserName = user.UserName;
            model.RoleChecked = new Dictionary<string, bool>();

            foreach (var role in roleMgr.Roles)
            {
                if (await userMgr.IsInRoleAsync(user, role.Name))
                {
                    model.RoleChecked[role.Name] = true;
                }
                else
                {
                    model.RoleChecked[role.Name] = false;
                }
            }

            return await Task.Run(() => View(model), ct);
        }

        [HttpPost]
        public async Task<IActionResult> AddRole(UserRolesViewModel model, CancellationToken ct)
        {
            var user = await userMgr.FindByIdAsync(model.Id.ToString());

            if (ModelState.IsValid)
            {
                var inroles = new List<string>();
                var exroles = new List<string>();

                foreach (var rc in model.RoleChecked)
                {
                    if (rc.Value == false)
                        exroles.Add(rc.Key);
                    else
                        inroles.Add(rc.Key);
                }

                foreach (var role in exroles)
                {
                    await userMgr.RemoveFromRoleAsync(user, role);
                }
                foreach (var role in inroles)
                {
                    await userMgr.AddToRoleAsync(user, role);
                }

                return RedirectToAction(nameof(UsersController.User), nameof(UsersController).CutController(), new { area = "Admin", Id = user.Id });
            }

            return await Task.Run(() => View(model), ct);
        }


public class UserRolesViewModel
    {
        [Required]
        [Display(Name = "Id")]
        public Guid Id { get; set; }

        [Required]
        [Display(Name = "User")]
        public string UserName { get; set; }

        [Required]
        [Display(Name = "Role")]
        public Dictionary<string, bool> RoleChecked { get; set; }
    }


Поменял Модель теперь чисто модель а не коллекция передается, во вьюшке так и не понял в чем прикол решение нашел подобной задачи и вишенка на торте оказывается что в айдентити скопом добовлять не работает пришлось по одному добавлять\удалять.

P.S. Обожаю ставить вопросы и отвечать на них самому 10/10 фич интеренета
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы