0 / 0 / 0
Регистрация: 30.07.2020
Сообщений: 27

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

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

Author24 — интернет-сервис помощи студентам
Я изучаю как работает 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
4624 / 2640 / 727
Регистрация: 02.08.2011
Сообщений: 7,086
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
4624 / 2640 / 727
Регистрация: 02.08.2011
Сообщений: 7,086
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
4624 / 2640 / 727
Регистрация: 02.08.2011
Сообщений: 7,086
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
4624 / 2640 / 727
Регистрация: 02.08.2011
Сообщений: 7,086
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
4624 / 2640 / 727
Регистрация: 02.08.2011
Сообщений: 7,086
04.11.2023, 20:21
Цитата Сообщение от kradun Посмотреть сообщение
подпапке /database лежит бэкап сервера
Используйте миграции, так универсальнее.
1
 Аватар для IamRain
4624 / 2640 / 727
Регистрация: 02.08.2011
Сообщений: 7,086
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
4624 / 2640 / 727
Регистрация: 02.08.2011
Сообщений: 7,086
04.11.2023, 20:47
Создается успешно, а редактировать там нечего. Добавить/Удалить пользователей (которых пока нету).
Вы бы описали четкую последовательность, при который воспроизводится ошибка - не хочется гадать.
Миниатюры
Управление ролями пользователей с помощью Identity в ASP.NET CORE MVC  
0
 Аватар для IamRain
4624 / 2640 / 727
Регистрация: 02.08.2011
Сообщений: 7,086
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
4624 / 2640 / 727
Регистрация: 02.08.2011
Сообщений: 7,086
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
Ответ Создать тему
Опции темы

Новые блоги и статьи
Реализация многопоточных сетевых серверов на Python
py-thonny 16.05.2025
Когда сталкиваешься с необходимостью писать высоконагруженные сетевые сервисы, выбор технологии имеет критическое значение. Python, со своей элегантностью и высоким уровнем абстракции, может. . .
C# и IoT: разработка Edge приложений с .NET и Azure IoT
UnmanagedCoder 16.05.2025
Мир меняется прямо на наших глазах, и интернет вещей (IoT) — один из главных катализаторов этих перемен. Если всего десять лет назад концепция "умных" устройств вызывала скептические улыбки, то. . .
Гибридные квантово-классические вычисления: Примеры оптимизации
EggHead 16.05.2025
Гибридные квантово-классические вычисления — это настоящий прорыв в подходах к решению сложнейших вычислительных задач. Представьте себе союз двух разных миров: классические компьютеры, с их. . .
Использование вебсокетов в приложениях Java с Netty
Javaican 16.05.2025
HTTP, краеугольный камень интернета, изначально был спроектирован для передачи гипертекста с минимальной интерактивностью. Его главный недостаток в контексте современных приложений — это. . .
Реализация операторов Kubernetes
Mr. Docker 16.05.2025
Концепция операторов Kubernetes зародилась в недрах компании CoreOS (позже купленной Red Hat), когда команда инженеров искала способ автоматизировать управление распределёнными базами данных в. . .
Отражение в C# и динамическое управление типами
stackOverflow 16.05.2025
Reflection API в . NET — это набор классов и интерфейсов в пространстве имён System. Reflection, который позволяет исследовать и манипулировать типами, методами, свойствами и другими элементами. . .
Настройка гиперпараметров с помощью Grid Search и Random Search в Python
AI_Generated 15.05.2025
В машинном обучении существует фундаментальное разделение между параметрами и гиперпараметрами моделей. Если параметры – это те величины, которые алгоритм "изучает" непосредственно из данных (веса. . .
Сериализация и десериализация данных на Python
py-thonny 15.05.2025
Сериализация — это своего рода "замораживание" объектов. Вы берёте живой, динамический объект из памяти и превращаете его в статичную строку или поток байтов. А десериализация выполняет обратный. . .
Чем асинхронная логика (схемотехника) лучше тактируемой, как я думаю, что помимо энергоэффективности - ещё и безопасность.
Hrethgir 14.05.2025
Помимо огромного плюса в энергоэффективности, асинхронная логика - тотальный контроль над каждым совершённым тактом, а значит - безусловная безопасность, где безконтрольно не совершится ни одного. . .
Многопоточные приложения на C++
bytestream 14.05.2025
C++ всегда был языком, тесно работающим с железом, и потому особеннно эффективным для многопоточного программирования. Стандарт C++11 произвёл революцию, добавив в язык нативную поддержку потоков,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru