Форум программистов, компьютерный форум, киберфорум
C#: ASP.NET MVC
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.73/11: Рейтинг темы: голосов - 11, средняя оценка - 4.73
0 / 0 / 0
Регистрация: 30.07.2020
Сообщений: 27

Управление ролями пользователей с помощью Identity в ASP.NET CORE MVC

04.11.2023, 15:19. Показов 3155. Ответов 20
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Я изучаю как работает Identyity в C# MVC и опираюсь на книгу "Фриман А. - ASP.NET Core MVC 2 с примерами на C# для профессионалов - 2019", то есть беру примеры из этой книги и переписываю в своё приложение.
В главе 29 описывается аутентификация пользователей, у меня проблема с функционалом управления ролями (стр. 922 этой книги).
При переходе по адресу https://localhost:7174/RoleAdmin вылетает ошибка SQL, сообщающая что я пытаюсь выполнить одновременно два запроса одновременно через один контекст:
NpgsqlOperationInProgressException: A command is already in progress: SELECT a."Id", a."ConcurrencyStamp", a."Name", a."NormalizedName" FROM "AspNetRoles" AS a
Npgsql.Internal.NpgsqlConnector.<StartUs erAction>g__DoStartUserAction|278_0(Conn ectorState newState, NpgsqlCommand command, ref <>c__DisplayClass278_0 )
Npgsql.Internal.NpgsqlConnector.StartUse rAction(ConnectorState newState, NpgsqlCommand command, CancellationToken cancellationToken, bool attemptPgCancellation)
Npgsql.NpgsqlCommand.ExecuteReader(Comma ndBehavior behavior, bool async, CancellationToken cancellationToken)
Npgsql.NpgsqlCommand.ExecuteReader(Comma ndBehavior behavior, bool async, CancellationToken cancellationToken)
Npgsql.NpgsqlCommand.ExecuteDbDataReader Async(CommandBehavior behavior, CancellationToken cancellationToken)
Microsoft.EntityFrameworkCore.Storage.Re lationalCommand.ExecuteReaderAsync(Relat ionalCommandParameterObject parameterObject, CancellationToken cancellationToken)
Microsoft.EntityFrameworkCore.Storage.Re lationalCommand.ExecuteReaderAsync(Relat ionalCommandParameterObject parameterObject, CancellationToken cancellationToken)
Microsoft.EntityFrameworkCore.Query.Inte rnal.SingleQueryingEnumerable<T>+AsyncEn umerator.InitializeReaderAsync(AsyncEnum erator enumerator, CancellationToken cancellationToken)
Npgsql.EntityFrameworkCore.PostgreSQL.St orage.Internal.NpgsqlExecutionStrategy.E xecuteAsync<TState, TResult>(TState state, Func<DbContext, TState, CancellationToken, Task<TResult>> operation, Func<DbContext, TState, CancellationToken, Task<ExecutionResult<TResult>>> verifySucceeded, CancellationToken cancellationToken)
Microsoft.EntityFrameworkCore.Query.Inte rnal.SingleQueryingEnumerable<T>+AsyncEn umerator.MoveNextAsync()
Microsoft.EntityFrameworkCore.Query.Shap edQueryCompilingExpressionVisitor.Single OrDefaultAsync<TSource>(IAsyncEnumerable <TSource> asyncEnumerable, CancellationToken cancellationToken)
Microsoft.EntityFrameworkCore.Query.Shap edQueryCompilingExpressionVisitor.Single OrDefaultAsync<TSource>(IAsyncEnumerable <TSource> asyncEnumerable, CancellationToken cancellationToken)
ServerMVC.Infrastructure.RoleUsersTagHel per.ProcessAsync(TagHelperContext context, TagHelperOutput output) in RoleUsersTagHelper.cs
+ IdentityRole role = await roleManager.FindByIdAsync(Role);
Microsoft.AspNetCore.Razor.Runtime.TagHe lpers.TagHelperRunner.<RunAsync>g__Await ed|0_0(Task task, TagHelperExecutionContext executionContext, int i, int count)
AspNetCore._Views_RoleAdmin_Index.Execut eAsync() in Index.cshtml
+ <td identity-role="@role.Id"></td>
Я не понимаю почему происходит такая ошибка, потому что с функционалом добавления и удаления роли проблем не было, я раз заново 5 переписывал код из книги, и абсолютно не могу понять из-за чего может возникать эта ошибка.

Мой код контроллера Controllers/RoleAdminController.cs выглядит следующим образом:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.AspNetCore.Mvc;
using ServerMVC.Models;
using System.ComponentModel.DataAnnotations;
 
namespace ServerMVC.Controllers
{
    public class RoleAdminController : Controller
    {
        private RoleManager<IdentityRole> roleManager;
        private UserManager<AppUser> userManager;
 
        public RoleAdminController(RoleManager<IdentityRole> roleMgr,
                                   UserManager<AppUser> userMrg)
        {
            roleManager = roleMgr;
            userManager = userMrg;
        }
 
        public ViewResult Index() => View(roleManager.Roles);
 
        public IActionResult Create() => View();
 
        [HttpPost]
        public async Task<IActionResult> Create([Required] string name)
        {
            if (ModelState.IsValid)
            {
                IdentityResult result
                    = await roleManager.CreateAsync(new IdentityRole(name));
                if (result.Succeeded)
                {
                    return RedirectToAction("Index");
                }
                else
                {
                    AddErrorsFromResult(result);
                }
            }
            return View(name);
        }
 
        [HttpPost]
        public async Task<IActionResult> Delete(string id)
        {
            IdentityRole role = await roleManager.FindByIdAsync(id);
            if (role != null)
            {
                IdentityResult result = await roleManager.DeleteAsync(role);
                if (result.Succeeded)
                {
                    return RedirectToAction("Index");
                }
                else
                {
                    AddErrorsFromResult(result);
                }
            }
            else
            {
                ModelState.AddModelError("", "No role found");
            }
            return View("Index", roleManager.Roles);
        }
        public async Task<IActionResult> Edit(string id)
        {
 
            IdentityRole role = await roleManager.FindByIdAsync(id);
            List<AppUser> members = new List<AppUser>();
            List<AppUser> nonMembers = new List<AppUser>();
            foreach (AppUser user in userManager.Users)
            {
                var list = await userManager.IsInRoleAsync(user, role.Name)
                    ? members : nonMembers;
                list.Add(user);
            }
            return View(new RoleEditModel
            {
                Role = role,
                Members = members,
                NonMembers = nonMembers
            });
        }
 
        [HttpPost]
        public async Task<IActionResult> Edit(RoleModificationModel model)
        {
            IdentityResult result;
            if (ModelState.IsValid)
            {
                foreach (string userId in model.IdsToAdd ?? new string[] { })
                {
                    AppUser user = await userManager.FindByIdAsync(userId);
                    if (user != null)
                    {
                        result = await userManager.AddToRoleAsync(user,
                            model.RoleName);
                        if (!result.Succeeded)
                        {
                            AddErrorsFromResult(result);
                        }
                    }
                }
                foreach (string userId in model.IdsToDelete ?? new string[] { })
                {
                    AppUser user = await userManager.FindByIdAsync(userId);
                    if (user != null)
                    {
                        result = await userManager.RemoveFromRoleAsync(user,
                            model.RoleName);
                        if (!result.Succeeded)
                        {
                            AddErrorsFromResult(result);
                        }
                    }
                }
            }
 
            if (ModelState.IsValid)
            {
                return RedirectToAction(nameof(Index));
            }
            else
            {
                return await Edit(model.RoleId);
            }
        }
        private void AddErrorsFromResult(IdentityResult result)
        {
            foreach (IdentityError error in result.Errors)
            {
                ModelState.AddModelError("", error.Description);
            }
        }
    }
}
Самописный tag-helper Infrastructure/RoleUsersTagHelper.cs:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.AspNetCore.Razor.TagHelpers;
using ServerMVC.Models;
 
namespace ServerMVC.Infrastructure
{
    [HtmlTargetElement("td", Attributes = "identity-role")]
    public class RoleUsersTagHelper : TagHelper
    {
        private UserManager<AppUser> userManager;
        private RoleManager<IdentityRole> roleManager;
 
        public RoleUsersTagHelper(UserManager<AppUser> usermgr,
                                  RoleManager<IdentityRole> rolemgr)
        {
            userManager = usermgr;
            roleManager = rolemgr;
        }
 
        [HtmlAttributeName("identity-role")]
        public string Role { get; set; }
 
        public override async Task ProcessAsync(TagHelperContext context,
                TagHelperOutput output)
        {
 
            List<string> names = new List<string>();
            IdentityRole role = await roleManager.FindByIdAsync(Role);
            if (role != null)
            {
                foreach (var user in userManager.Users)
                {
                    if (user != null
                        && await userManager.IsInRoleAsync(user, role.Name))
                    {
                        names.Add(user.UserName);
                    }
                }
            }
 
            output.Content.SetContent(names.Count == 0 ?
                "No Users" : string.Join(", ", names));
        }
    }
}
Views/_ViewsImports.cshtml:
C#
1
2
3
4
@using ServerMVC.Models
@using Microsoft.AspNetCore.Identity
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper ServerMVC.Infrastructure.RoleUsersTagHelper, ServerMVC
Файл Views/RoleAdmin/Index.cshtml
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@model IEnumerable<AppUser>
 
<div class="bg-primary m-1 p-1 text-white"><h4>User Accounts</h4></div>
<div class="text-danger" asp-validation-summary="ModelOnly"></div>
<table class="table table-sm table-bordered">
    <tr><th>ID</th><th>UserName</th><th>Email</th></tr>
    @if (Model.Count() == 0)
    {
        <tr><td colspan="3" class="text-center">No User Accounts</td></tr>
    }
    else
    {
        foreach (AppUser user in Model)
        {
            <tr>
                <td>@user.Id</td><td>@user.UserName</td><td>@user.Email</td>
                <td>
                    <form asp-action="Delete" asp-route-id="@user.Id" method="post">
                        <a class="btn btn-sm btn-primary" asp-action="Edit" asp-route-id="@user.Id">Edit</a>
                        <button type="submit" class="btn btn-sm btn-danger">Delete</button>
                    </form>
                </td>
            </tr>
        }
    }
</table>
<a class="btn btn-primary" asp-action="Create">Create</a>
Файл Views/RoleAdmin/Edit.cshtml
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
@model RoleEditModel
 
<div class="bg-primary m-1 p-1 text-white"><h4>Edit Role</h4></div>
 
<div asp-validation-summary="All" class="text-danger"></div>
 
<form asp-action="Edit" method="post">
    <input type="hidden" name="roleName" value="@Model.Role.Name" />
    <input type="hidden" name="roleId" value="@Model.Role.Id" />
 
    <h6 class="bg-info p-1 text-white">Add To @Model.Role.Name</h6>
    <table class="table table-bordered table-sm">
        @if (Model.NonMembers.Count() == 0)
        {
            <tr><td colspan="2">All Users Are Members</td></tr>
        }
        else
        {
            @foreach (AppUser user in Model.NonMembers)
            {
                <tr>
                    <td>@user.UserName</td>
                    <td>
                        <input type="checkbox" name="IdsToAdd" value="@user.Id">
                    </td>
                </tr>
            }
        }
    </table>
 
    <h6 class="bg-info p-1 text-white">Remove From @Model.Role.Name</h6>
    <table class="table table-bordered table-sm">
        @if (Model.Members.Count() == 0)
        {
            <tr><td colspan="2">No Users Are Members</td></tr>
        }
        else
        {
            @foreach (AppUser user in Model.Members)
            {
                <tr>
                    <td>@user.UserName</td>
                    <td>
                        <input type="checkbox" name="IdsToDelete" value="@user.Id">
                    </td>
                </tr>
            }
        }
    </table>
    <button type="submit" class="btn btn-primary">Save</button>
    <a asp-action="Index" class="btn btn-secondary">Cancel</a>
</form>
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
04.11.2023, 15:19
Ответы с готовыми решениями:

Проблема с ролями в Asp net Identity
Здравствуйте. Начал изучать Asp Net Identity. И решил сделать следующее. У меня есть список ролей, которые можно пополнять, и я хочу менять...

Разница между ASP.NET Core 2, ASP.NET Core MVC, ASP.NET MVC 5 и ASP.NET WEBAPI 2
Здравствуйте. Я в бекенд разработке полный ноль. В чем разница между вышеперечисленными технологиями? Есть ли в них что-то общее - могу ли...

Где находится контроллер регистрации в стандартном шаблоне Visual Studio asp net core mvc + identity
Добрый день, являюсь новичком в asp net core mvc + identity. В стандартном шаблоне asp net core mvc + identity на сайте есть раздел...

20
403 / 265 / 69
Регистрация: 12.04.2020
Сообщений: 1,404
04.11.2023, 16:54
Цитата Сообщение от kradun Посмотреть сообщение
public ViewResult Index() => View(roleManager.Roles);
C#
1
public async Task<IActionResult> Index() => View(_roleManager.Roles.ToListAsync().ConfigureAwait(false));
1
0 / 0 / 0
Регистрация: 30.07.2020
Сообщений: 27
04.11.2023, 17:44  [ТС]
Цитата Сообщение от Dr9vik Посмотреть сообщение
public async Task<IActionResult> Index() => View(_roleManager.Roles.ToListAsync().Co nfigureAwait(false));
Теперь пишет
InvalidOperationException: The model item passed into the ViewDataDictionary is of type 'System.Runtime.CompilerServices.Configu redTaskAwaitable`1[System.Collections.Generic.List`1[Microsoft.AspNetCore.Identity.IdentityRo le]]', but this ViewDataDictionary instance requires a model item of type 'System.Collections.Generic.IEnumerable` 1[Microsoft.AspNetCore.Identity.IdentityRo le]'.
Я сейчас заметил что вставил в вопрос не тот Index.cshtml, (из за того что в MVC на разные контроллеры файлы представления должны называться Index я запутался).
Index.cshtml для RoleAdminController.cs, относящийся к сабжу выглядит так:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
@model IEnumerable<IdentityRole>
 
<div class="bg-primary m-1 p-1"><h4>Roles</h4></div>
 
<div class="text-danger" asp-validation-summary="ModelOnly"></div>
 
<table class="table table-sm table-bordered table-bordered">
    <tr><th>ID</th><th>Name</th><th>Users</th><th></th></tr>
    @if (Model.Count() == 0)
    {
        <tr><td colspan="4" class="text-center">No Roles</td></tr>
    }
    else
    {
        foreach (var role in Model)
        {
            <tr>
                <td>@role.Id</td>
                <td>@role.Name</td>
                <td identity-role="@role.Id"></td>
                <td>
                    <form asp-action="Delete" asp-route-id="@role.Id" method="post">
                        <a class="btn btn-sm btn-primary" asp-action="Edit"
                           asp-route-id="@role.Id">Edit</a>
                        <button type="submit"
                                class="btn btn-sm btn-danger">
                            Delete
                        </button>
                    </form>
                </td>
            </tr>
        }
    }
</table>
<a class="btn btn-primary" asp-action="Create">Create</a>
Но все равно там тот же тип IEnumerable в модели, и я попробовал поменять на
C#
1
@model System.Runtime.CompilerServices.ConfiguredTaskAwaitable<IdentityRole>
ошибка остается.
0
 Аватар для IamRain
4693 / 2701 / 734
Регистрация: 02.08.2011
Сообщений: 7,226
04.11.2023, 18:18
Цитата Сообщение от Dr9vik Посмотреть сообщение
ConfigureAwait(false));
У вас, Dr9vik, смотрю, любовь до смерти с этим ConfigureAwait(false).
0
403 / 265 / 69
Регистрация: 12.04.2020
Сообщений: 1,404
04.11.2023, 18:54
IamRain, как мы уже выяснили
проверку на контекст мы никуда не убирали
поэтому и любовь
мне лично не мешает

Цитата Сообщение от kradun Посмотреть сообщение
Теперь пишет
простите, не привык писать этот сахар
C#
1
public async Task<IActionResult> Index() => View(await _roleManager.Roles.ToListAsync().ConfigureAwait(false));
1
 Аватар для IamRain
4693 / 2701 / 734
Регистрация: 02.08.2011
Сообщений: 7,226
04.11.2023, 19:04
Цитата Сообщение от Dr9vik Посмотреть сообщение
проверку на контекст мы никуда не убирали
Причем здесь проверка на контекст? Проверка одного if-а занимает десятки наносекунд - это очень быстро.
Восстановление контекста (переключение контекста физического потока) - уже прилично дольше (не замерял) - целевое применение СonfigureAwait(false).
А выполнение кода на ThreadPool-е с наличием ConfigureAwait(false) говорит о том, что человек так них*ра и не понял, для чего это нужно на самом деле.
1
0 / 0 / 0
Регистрация: 30.07.2020
Сообщений: 27
04.11.2023, 19:09  [ТС]
Цитата Сообщение от Dr9vik Посмотреть сообщение
public async Task<IActionResult> Index() => View(await _roleManager.Roles.ToListAsync().Configu reAwait(false));
Вернулась изначальная ошибка:
NpgsqlOperationInProgressException: A command is already in progress: SELECT a."Id", a."AccessFailedCount", a."ConcurrencyStamp", a."Email", a."EmailConfirmed", a."LockoutEnabled", a."LockoutEnd", a."NormalizedEmail", a."NormalizedUserName", a."PasswordHash", a."PhoneNumber", a."PhoneNumberConfirmed", a."SecurityStamp", a."TwoFactorEnabled", a."UserName" FROM "AspNetUsers" AS a
Npgsql.Internal.NpgsqlConnector.<StartUs erAction>g__DoStartUserAction|278_0(Conn ectorState newState, NpgsqlCommand command, ref <>c__DisplayClass278_0 )
Npgsql.Internal.NpgsqlConnector.StartUse rAction(ConnectorState newState, NpgsqlCommand command, CancellationToken cancellationToken, bool attemptPgCancellation)
Npgsql.NpgsqlCommand.ExecuteReader(Comma ndBehavior behavior, bool async, CancellationToken cancellationToken)
Npgsql.NpgsqlCommand.ExecuteReader(Comma ndBehavior behavior, bool async, CancellationToken cancellationToken)
Npgsql.NpgsqlCommand.ExecuteDbDataReader Async(CommandBehavior behavior, CancellationToken cancellationToken)
Microsoft.EntityFrameworkCore.Storage.Re lationalCommand.ExecuteReaderAsync(Relat ionalCommandParameterObject parameterObject, CancellationToken cancellationToken)
Microsoft.EntityFrameworkCore.Storage.Re lationalCommand.ExecuteReaderAsync(Relat ionalCommandParameterObject parameterObject, CancellationToken cancellationToken)
Microsoft.EntityFrameworkCore.Query.Inte rnal.SingleQueryingEnumerable<T>+AsyncEn umerator.InitializeReaderAsync(AsyncEnum erator enumerator, CancellationToken cancellationToken)
Npgsql.EntityFrameworkCore.PostgreSQL.St orage.Internal.NpgsqlExecutionStrategy.E xecuteAsync<TState, TResult>(TState state, Func<DbContext, TState, CancellationToken, Task<TResult>> operation, Func<DbContext, TState, CancellationToken, Task<ExecutionResult<TResult>>> verifySucceeded, CancellationToken cancellationToken)
Microsoft.EntityFrameworkCore.Query.Inte rnal.SingleQueryingEnumerable<T>+AsyncEn umerator.MoveNextAsync()
Microsoft.EntityFrameworkCore.Query.Shap edQueryCompilingExpressionVisitor.Single OrDefaultAsync<TSource>(IAsyncEnumerable <TSource> asyncEnumerable, CancellationToken cancellationToken)
Microsoft.EntityFrameworkCore.Query.Shap edQueryCompilingExpressionVisitor.Single OrDefaultAsync<TSource>(IAsyncEnumerable <TSource> asyncEnumerable, CancellationToken cancellationToken)
Microsoft.AspNetCore.Identity.EntityFram eworkCore.UserStore<TUser, TRole, TContext, TKey, TUserClaim, TUserRole, TUserLogin, TUserToken, TRoleClaim>.IsInRoleAsync(TUser user, string normalizedRoleName, CancellationToken cancellationToken)
Microsoft.AspNetCore.Identity.UserManage r<TUser>.IsInRoleAsync(TUser user, string role)
ServerMVC.Infrastructure.RoleUsersTagHel per.ProcessAsync(TagHelperContext context, TagHelperOutput output) in RoleUsersTagHelper.cs
+ if (user != null
Microsoft.AspNetCore.Razor.Runtime.TagHe lpers.TagHelperRunner.<RunAsync>g__Await ed|0_0(Task task, TagHelperExecutionContext executionContext, int i, int count)
AspNetCore._Views_RoleAdmin_Index.Execut eAsync() in Index.cshtml
+ <td identity-role="@role.Id"></td>
0
 Аватар для IamRain
4693 / 2701 / 734
Регистрация: 02.08.2011
Сообщений: 7,226
04.11.2023, 19:19
kradun, попробуйте модель явно в виде List<IdentityRole> обозначить.
И в теле разметки можно вместо Count() использовать просто свойство Count. Не совсем понятно, почему у вас наблюдается эта проблема, честно говоря.
1
0 / 0 / 0
Регистрация: 30.07.2020
Сообщений: 27
04.11.2023, 19:31  [ТС]
Происходит вообще что то странное, если написать без await:
C#
1
public async Task<IActionResult> Index() => View(roleManager.Roles.ToListAsync().ConfigureAwait(false));
И в модели поменять @model IEnumerable<IdentityRole> на @model List<IdentityRole>
Цитата Сообщение от IamRain Посмотреть сообщение
List<IdentityRole> обозначить.
И в теле разметки можно вместо Count() использовать просто свойство Count
То вылазит ошибка
InvalidOperationException: The model item passed into the ViewDataDictionary is of type 'System.Runtime.CompilerServices.Configu redTaskAwaitable`1[System.Collections.Generic.List`1[Microsoft.AspNetCore.Identity.IdentityRo le]]', but this ViewDataDictionary instance requires a model item of type 'System.Collections.Generic.List`1[Microsoft.AspNetCore.Identity.IdentityRo le]'.
Если же написать с await:
C#
1
public async Task<IActionResult> Index() => View(await roleManager.Roles.ToListAsync().ConfigureAwait(false));
То уже мы видим изначальную ошибку: NpgsqlOperationInProgressException: A command is already in progress
0
 Аватар для IamRain
4693 / 2701 / 734
Регистрация: 02.08.2011
Сообщений: 7,226
04.11.2023, 19:37
kradun, выложите ваш проект на гитхаб - хотелось бы воспроизвести проблему.
И дайте ссылку сюда, пожалуйста.
1
403 / 265 / 69
Регистрация: 12.04.2020
Сообщений: 1,404
04.11.2023, 19:45
Цитата Сообщение от IamRain Посмотреть сообщение
А выполнение кода на ThreadPool-е с наличием ConfigureAwait(false) говорит о том, что человек так них*ра и не понял, для чего это нужно на самом деле.
я прекрасно знаю что контекста нету
Цитата Сообщение от IamRain Посмотреть сообщение
Проверка одного if-а занимает десятки наносекунд - это очень быстро.
одного?
0
0 / 0 / 0
Регистрация: 30.07.2020
Сообщений: 27
04.11.2023, 19:53  [ТС]
Цитата Сообщение от IamRain Посмотреть сообщение
kradun, выложите ваш проект на гитхаб - хотелось бы воспроизвести проблему.
И дайте ссылку сюда, пожалуйста.
https://github.com/kradunches/ari-metiostation
Проект в папке /server
База данных - PostgreSQL 16.0, в подпапке /database лежит бэкап сервера
0
 Аватар для IamRain
4693 / 2701 / 734
Регистрация: 02.08.2011
Сообщений: 7,226
04.11.2023, 20:21
Цитата Сообщение от kradun Посмотреть сообщение
подпапке /database лежит бэкап сервера
Используйте миграции, так универсальнее.
1
 Аватар для IamRain
4693 / 2701 / 734
Регистрация: 02.08.2011
Сообщений: 7,226
04.11.2023, 20:31
Вроде не наблюдается проблемы. Но у меня таблица с ролями пустая.
Миниатюры
Управление ролями пользователей с помощью Identity в ASP.NET CORE MVC  
0
0 / 0 / 0
Регистрация: 30.07.2020
Сообщений: 27
04.11.2023, 20:35  [ТС]
Цитата Сообщение от IamRain Посмотреть сообщение
Но у меня таблица с ролями пустая.
Попробуйте создать, а потом изменить роль
0
 Аватар для IamRain
4693 / 2701 / 734
Регистрация: 02.08.2011
Сообщений: 7,226
04.11.2023, 20:47
Создается успешно, а редактировать там нечего. Добавить/Удалить пользователей (которых пока нету).
Вы бы описали четкую последовательность, при который воспроизводится ошибка - не хочется гадать.
Миниатюры
Управление ролями пользователей с помощью Identity в ASP.NET CORE MVC  
0
 Аватар для IamRain
4693 / 2701 / 734
Регистрация: 02.08.2011
Сообщений: 7,226
04.11.2023, 20:52
По-хорошему, ваше приложение должно само запускать миграции (создавать схему, сидировать базу).
Это делается при старте приложения, чтобы остальным разработчикам было легче запускать приложение, не занимаясь возней с базой.
0
0 / 0 / 0
Регистрация: 30.07.2020
Сообщений: 27
04.11.2023, 21:09  [ТС]
Цитата Сообщение от IamRain Посмотреть сообщение
Вы бы описали четкую последовательность, при который воспроизводится ошибка - не хочется гадать.
Вообще у меня ошибка A command is already in progress появляется когда я просто перехожу по адресу /RoleAdmin
У меня в БД есть 3 пользователя, которых можно создать перейдя по адресу /Admin и 3 роли
До того как написать на форум ошибка воспроизводилась когда я закомментировал весь код в файле Infrastructure/RoleUsersTagHelper.cs и кликал по кнопке Edit Role
Возможно у вас появится ошибка если вы тоже создадите пользователей и несколько ролей, а потом перейдете по адресу /RoleAdmin
Цитата Сообщение от IamRain Посмотреть сообщение
По-хорошему, ваше приложение должно само запускать миграции (создавать схему, сидировать базу).
А вот это я пока не знаю как сделать, знаю как просто миграцию сделать, у меня в проекте она есть.
0
 Аватар для IamRain
4693 / 2701 / 734
Регистрация: 02.08.2011
Сообщений: 7,226
04.11.2023, 21:43
Да, проблема воспроизведена. ТегХелпер коряво реализован - каждое его упоминание делает запрос в таблицу пользователей.
Костыльное решение - писать список пользователей один раз в статическую переменную (на момент генерации странички).
По завершению - обнулять. Рекомендую подумать над тем, как это можно реализовать по-другому, и нужен ли здесь вообще этот хелпер.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
private static AppUser[]? _users;
 
        public override async Task ProcessAsync(TagHelperContext context,
                TagHelperOutput output)
        {
            _users ??= userManager.Users.ToArray();
 
            List<string> names = new List<string>();
            IdentityRole role = await roleManager.FindByIdAsync(Role);
            if (role != null)
            {
                foreach (var user in _users)
                {
                    if (user != null
                        && await userManager.IsInRoleAsync(user, role.Name))
                    {
                        names.Add(user.UserName);
                    }
                }
            }
 
            output.Content.SetContent(names.Count == 0 ? "No Users" : string.Join(", ", names));
            _users = null;
        }
Добавлено через 11 минут
Вот этот _users = null - тут я поторопился, я бы занулял это явно как-то через статику после завершения генерации, либо просто бы добавил InMemoryCache<string[]> который бы был полем хелпера и который бы хранил список пользователей по 2-3 минуты, условно.
1
0 / 0 / 0
Регистрация: 30.07.2020
Сообщений: 27
04.11.2023, 21:46  [ТС]
Цитата Сообщение от IamRain Посмотреть сообщение
Костыльное решение - писать список пользователей один раз в статическую переменную (на момент генерации странички).
Насколько я знаю статические переменные лучше вообще не использовать в веб-приложениях, тк это будет работать только у одного пользователя.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
04.11.2023, 21:46
Помогаю со студенческими работами здесь

Перейти с asp.net identity на core identity
Всем привет, работаю в легасном проекте. Там, когда пользователь регался - система солила пароли. Сейчас надо на кор переходить, а...

Какая разница между ASP .Net Core и ASP .Net Core MVC?
Какая разница между ASP .Net Core и ASP .Net Core MVC? Или я может что-то не так понял? И подскажите пожалуйста еще какие-то книги для...

Миграция в ASP.NET MVC 5 с Identity
Есть проект ASP.net MVC 5 c индивидуальными учетными записями, пару моделей и контекст для них. Пытаюсь включить миграции...

Asp.net core identity
Добрый день. В своем проекте я хочу использовать двухуровневую систему - Web(MVC) и DAL(library) Если я создаю проект по умолчанию с...

Identity в ASP.NET Core 2.0
Доброе время суток. Пытаюсь реализовать авторизацю с помощью Identity на asp.net core 2.0. Но столкнулся с проблемой, что у пользователя...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru