UserSettingsController replace value type to JsonDocument

This commit is contained in:
ngfrolov 2022-08-09 15:59:40 +05:00
parent 6e95e68551
commit a5a31d5d82
5 changed files with 68 additions and 63 deletions

View File

@ -25,7 +25,7 @@ namespace AsbCloudApp.Services
/// <param name="key"></param> /// <param name="key"></param>
/// <param name="token"></param> /// <param name="token"></param>
/// <returns></returns> /// <returns></returns>
Task<object> GetOrDefaultAsync(int userId, string key, CancellationToken token); Task<System.Text.Json.JsonDocument> GetOrDefaultAsync(int userId, string key, CancellationToken token);
/// <summary> /// <summary>
/// Добавить настройки с ключем для пользователя /// Добавить настройки с ключем для пользователя
@ -35,7 +35,7 @@ namespace AsbCloudApp.Services
/// <param name="value"></param> /// <param name="value"></param>
/// <param name="token"></param> /// <param name="token"></param>
/// <returns></returns> /// <returns></returns>
Task<int> InsertAsync(int userId, string key, object value, CancellationToken token); Task<int> InsertAsync(int userId, string key, System.Text.Json.JsonDocument value, CancellationToken token);
/// <summary> /// <summary>
/// Отредактировать настройки с ключем для пользователя /// Отредактировать настройки с ключем для пользователя
@ -45,7 +45,7 @@ namespace AsbCloudApp.Services
/// <param name="value"></param> /// <param name="value"></param>
/// <param name="token"></param> /// <param name="token"></param>
/// <returns></returns> /// <returns></returns>
Task<int> UpdateAsync(int userId, string key, object value, CancellationToken token); Task<int> UpdateAsync(int userId, string key, System.Text.Json.JsonDocument value, CancellationToken token);
/// <summary> /// <summary>
/// Удалить настройки с ключем для пользователя /// Удалить настройки с ключем для пользователя

View File

@ -60,7 +60,7 @@ namespace AsbCloudDb.Migrations
b.HasIndex("IdDeposit"); b.HasIndex("IdDeposit");
b.ToTable("t_cluster"); b.ToTable("t_cluster", (string)null);
b.HasComment("Кусты"); b.HasComment("Кусты");
}); });
@ -89,7 +89,7 @@ namespace AsbCloudDb.Migrations
b.HasIndex("IdCompanyType"); b.HasIndex("IdCompanyType");
b.ToTable("t_company"); b.ToTable("t_company", (string)null);
b.HasData( b.HasData(
new new
@ -116,7 +116,7 @@ namespace AsbCloudDb.Migrations
b.HasKey("Id"); b.HasKey("Id");
b.ToTable("t_company_type"); b.ToTable("t_company_type", (string)null);
b.HasData( b.HasData(
new new
@ -156,7 +156,7 @@ namespace AsbCloudDb.Migrations
b.HasKey("IdWell", "StartDate") b.HasKey("IdWell", "StartDate")
.HasName("t_id_well_date_start_pk"); .HasName("t_id_well_date_start_pk");
b.ToTable("t_daily_report"); b.ToTable("t_daily_report", (string)null);
b.HasComment("Ежедневные отчёты"); b.HasComment("Ежедневные отчёты");
}); });
@ -190,7 +190,7 @@ namespace AsbCloudDb.Migrations
b.HasKey("Id"); b.HasKey("Id");
b.ToTable("t_deposit"); b.ToTable("t_deposit", (string)null);
b.HasComment("Месторождение"); b.HasComment("Месторождение");
}); });
@ -249,7 +249,7 @@ namespace AsbCloudDb.Migrations
b.HasIndex("IdTelemetry"); b.HasIndex("IdTelemetry");
b.ToTable("t_detected_operation"); b.ToTable("t_detected_operation", (string)null);
b.HasComment("автоматически определенные операции по телеметрии"); b.HasComment("автоматически определенные операции по телеметрии");
}); });
@ -286,7 +286,7 @@ namespace AsbCloudDb.Migrations
b.HasKey("Id"); b.HasKey("Id");
b.ToTable("t_driller"); b.ToTable("t_driller", (string)null);
b.HasComment("Бурильщик"); b.HasComment("Бурильщик");
}); });
@ -381,7 +381,7 @@ namespace AsbCloudDb.Migrations
b.HasIndex("IdWellOperationCategory"); b.HasIndex("IdWellOperationCategory");
b.ToTable("t_drill_flow_chart"); b.ToTable("t_drill_flow_chart", (string)null);
b.HasComment("Параметры коридоров бурения (диапазоны параметров бурения)"); b.HasComment("Параметры коридоров бурения (диапазоны параметров бурения)");
}); });
@ -410,7 +410,7 @@ namespace AsbCloudDb.Migrations
b.HasIndex("IdWell", "IdFileCategory") b.HasIndex("IdWell", "IdFileCategory")
.IsUnique(); .IsUnique();
b.ToTable("t_drilling_program_part"); b.ToTable("t_drilling_program_part", (string)null);
b.HasComment("части программ бурения"); b.HasComment("части программ бурения");
}); });
@ -525,7 +525,7 @@ namespace AsbCloudDb.Migrations
b.HasIndex("IdWellSectionType"); b.HasIndex("IdWellSectionType");
b.ToTable("t_drill_params"); b.ToTable("t_drill_params", (string)null);
b.HasComment("Режим бурения в секции (диапазоны параметров бурения)"); b.HasComment("Режим бурения в секции (диапазоны параметров бурения)");
}); });
@ -551,7 +551,7 @@ namespace AsbCloudDb.Migrations
b.HasKey("Id"); b.HasKey("Id");
b.ToTable("t_file_category"); b.ToTable("t_file_category", (string)null);
b.HasComment("Категории файлов"); b.HasComment("Категории файлов");
@ -725,7 +725,7 @@ namespace AsbCloudDb.Migrations
b.HasIndex("IdWell"); b.HasIndex("IdWell");
b.ToTable("t_file_info"); b.ToTable("t_file_info", (string)null);
b.HasComment("Файлы всех категорий"); b.HasComment("Файлы всех категорий");
}); });
@ -776,7 +776,7 @@ namespace AsbCloudDb.Migrations
b.HasIndex("IdUser"); b.HasIndex("IdUser");
b.ToTable("t_file_mark"); b.ToTable("t_file_mark", (string)null);
b.HasComment("Действия с файлами."); b.HasComment("Действия с файлами.");
}); });
@ -821,7 +821,7 @@ namespace AsbCloudDb.Migrations
b.HasIndex("IdWell"); b.HasIndex("IdWell");
b.ToTable("t_measure"); b.ToTable("t_measure", (string)null);
b.HasComment("Таблица c данными для вкладки 'Последние данные'"); b.HasComment("Таблица c данными для вкладки 'Последние данные'");
}); });
@ -847,7 +847,7 @@ namespace AsbCloudDb.Migrations
b.HasKey("Id"); b.HasKey("Id");
b.ToTable("t_measure_category"); b.ToTable("t_measure_category", (string)null);
b.HasComment("Категория последних данных"); b.HasComment("Категория последних данных");
@ -918,7 +918,7 @@ namespace AsbCloudDb.Migrations
b.HasIndex("IdWell"); b.HasIndex("IdWell");
b.ToTable("t_operationvalue"); b.ToTable("t_operationvalue", (string)null);
b.HasComment("Целевые/нормативные показатели операции"); b.HasComment("Целевые/нормативные показатели операции");
}); });
@ -946,7 +946,7 @@ namespace AsbCloudDb.Migrations
b.HasKey("Id"); b.HasKey("Id");
b.ToTable("t_permission"); b.ToTable("t_permission", (string)null);
b.HasComment("Разрешения на доступ к данным"); b.HasComment("Разрешения на доступ к данным");
@ -1663,7 +1663,7 @@ namespace AsbCloudDb.Migrations
b.HasIndex("IdWell"); b.HasIndex("IdWell");
b.ToTable("t_relation_company_well"); b.ToTable("t_relation_company_well", (string)null);
b.HasComment("отношение скважин и компаний"); b.HasComment("отношение скважин и компаний");
}); });
@ -1688,7 +1688,7 @@ namespace AsbCloudDb.Migrations
b.HasIndex("IdDrillingProgramPart"); b.HasIndex("IdDrillingProgramPart");
b.ToTable("t_relation_user_drilling_program_part"); b.ToTable("t_relation_user_drilling_program_part", (string)null);
b.HasComment("Отношение пользователей и частей ПБ"); b.HasComment("Отношение пользователей и частей ПБ");
}); });
@ -1707,7 +1707,7 @@ namespace AsbCloudDb.Migrations
b.HasIndex("IdPermission"); b.HasIndex("IdPermission");
b.ToTable("t_relation_user_role_permission"); b.ToTable("t_relation_user_role_permission", (string)null);
b.HasComment("Отношение ролей пользователей и разрешений доступа"); b.HasComment("Отношение ролей пользователей и разрешений доступа");
@ -2289,7 +2289,7 @@ namespace AsbCloudDb.Migrations
b.HasIndex("IdInclude"); b.HasIndex("IdInclude");
b.ToTable("t_relation_user_role_user_role"); b.ToTable("t_relation_user_role_user_role", (string)null);
b.HasComment("Отношение ролей к ролям"); b.HasComment("Отношение ролей к ролям");
@ -2580,7 +2580,7 @@ namespace AsbCloudDb.Migrations
b.HasIndex("IdUserRole"); b.HasIndex("IdUserRole");
b.ToTable("t_relation_user_user_role"); b.ToTable("t_relation_user_user_role", (string)null);
b.HasComment("Отношение пользователей и ролей"); b.HasComment("Отношение пользователей и ролей");
@ -2636,7 +2636,7 @@ namespace AsbCloudDb.Migrations
b.HasIndex("IdWell"); b.HasIndex("IdWell");
b.ToTable("t_report_property"); b.ToTable("t_report_property", (string)null);
b.HasComment("Отчеты с данными по буровым"); b.HasComment("Отчеты с данными по буровым");
}); });
@ -2687,7 +2687,7 @@ namespace AsbCloudDb.Migrations
b.HasIndex("IdWell"); b.HasIndex("IdWell");
b.ToTable("t_schedule"); b.ToTable("t_schedule", (string)null);
b.HasComment("График работы бурильщика"); b.HasComment("График работы бурильщика");
}); });
@ -2741,7 +2741,7 @@ namespace AsbCloudDb.Migrations
b.HasIndex("IdWell"); b.HasIndex("IdWell");
b.ToTable("t_setpoints_rquest"); b.ToTable("t_setpoints_rquest", (string)null);
b.HasComment("Запросы на изменение уставок панели оператора"); b.HasComment("Запросы на изменение уставок панели оператора");
}); });
@ -2774,7 +2774,7 @@ namespace AsbCloudDb.Migrations
b.HasIndex(new[] { "RemoteUid" }, "t_telemetry_remote_uid_index"); b.HasIndex(new[] { "RemoteUid" }, "t_telemetry_remote_uid_index");
b.ToTable("t_telemetry"); b.ToTable("t_telemetry", (string)null);
b.HasComment("таблица привязки телеметрии от комплектов к конкретной скважине."); b.HasComment("таблица привязки телеметрии от комплектов к конкретной скважине.");
}); });
@ -2977,7 +2977,7 @@ namespace AsbCloudDb.Migrations
b.HasKey("IdTelemetry", "DateTime"); b.HasKey("IdTelemetry", "DateTime");
b.ToTable("t_telemetry_data_saub"); b.ToTable("t_telemetry_data_saub", (string)null);
b.HasComment("набор основных данных по SAUB"); b.HasComment("набор основных данных по SAUB");
}); });
@ -3318,7 +3318,7 @@ namespace AsbCloudDb.Migrations
b.HasKey("IdTelemetry", "DateTime"); b.HasKey("IdTelemetry", "DateTime");
b.ToTable("t_telemetry_data_spin"); b.ToTable("t_telemetry_data_spin", (string)null);
b.HasComment("набор основных данных по SpinMaster"); b.HasComment("набор основных данных по SpinMaster");
}); });
@ -3343,7 +3343,7 @@ namespace AsbCloudDb.Migrations
b.HasKey("IdTelemetry", "IdEvent"); b.HasKey("IdTelemetry", "IdEvent");
b.ToTable("t_telemetry_event"); b.ToTable("t_telemetry_event", (string)null);
b.HasComment("Справочник событий. События формируют сообщения. Разделено по версиям посылок от телеметрии."); b.HasComment("Справочник событий. События формируют сообщения. Разделено по версиям посылок от телеметрии.");
}); });
@ -3403,7 +3403,7 @@ namespace AsbCloudDb.Migrations
b.HasIndex("IdTelemetry"); b.HasIndex("IdTelemetry");
b.ToTable("t_telemetry_message"); b.ToTable("t_telemetry_message", (string)null);
b.HasComment("Сообщения на буровых"); b.HasComment("Сообщения на буровых");
}); });
@ -3439,7 +3439,7 @@ namespace AsbCloudDb.Migrations
b.HasKey("IdTelemetry", "IdUser"); b.HasKey("IdTelemetry", "IdUser");
b.ToTable("t_telemetry_user"); b.ToTable("t_telemetry_user", (string)null);
b.HasComment("Пользователи панели САУБ. Для сообщений."); b.HasComment("Пользователи панели САУБ. Для сообщений.");
}); });
@ -3516,7 +3516,7 @@ namespace AsbCloudDb.Migrations
b.HasIndex("Login") b.HasIndex("Login")
.IsUnique(); .IsUnique();
b.ToTable("t_user"); b.ToTable("t_user", (string)null);
b.HasComment("Пользователи облака"); b.HasComment("Пользователи облака");
@ -3553,7 +3553,7 @@ namespace AsbCloudDb.Migrations
b.HasKey("Id"); b.HasKey("Id");
b.ToTable("t_user_role"); b.ToTable("t_user_role", (string)null);
b.HasComment("Роли пользователей в системе"); b.HasComment("Роли пользователей в системе");
@ -3891,7 +3891,7 @@ namespace AsbCloudDb.Migrations
b.HasKey("IdUser", "Key"); b.HasKey("IdUser", "Key");
b.ToTable("t_user_settings"); b.ToTable("t_user_settings", (string)null);
b.HasComment("настройки интерфейса пользователя"); b.HasComment("настройки интерфейса пользователя");
}); });
@ -3949,7 +3949,7 @@ namespace AsbCloudDb.Migrations
b.HasIndex("IdWellType"); b.HasIndex("IdWellType");
b.ToTable("t_well"); b.ToTable("t_well", (string)null);
b.HasComment("скважины"); b.HasComment("скважины");
}); });
@ -3977,7 +3977,7 @@ namespace AsbCloudDb.Migrations
b.HasIndex("IdWellSrc"); b.HasIndex("IdWellSrc");
b.ToTable("t_well_composite"); b.ToTable("t_well_composite", (string)null);
b.HasComment("Композитная скважина"); b.HasComment("Композитная скважина");
}); });
@ -4053,7 +4053,7 @@ namespace AsbCloudDb.Migrations
b.HasIndex("IdWellSectionType"); b.HasIndex("IdWellSectionType");
b.ToTable("t_well_operation"); b.ToTable("t_well_operation", (string)null);
b.HasComment("Данные по операциям на скважине"); b.HasComment("Данные по операциям на скважине");
}); });
@ -4091,7 +4091,7 @@ namespace AsbCloudDb.Migrations
b.HasKey("Id"); b.HasKey("Id");
b.ToTable("t_well_operation_category"); b.ToTable("t_well_operation_category", (string)null);
b.HasComment("Справочник операций на скважине"); b.HasComment("Справочник операций на скважине");
@ -4700,7 +4700,7 @@ namespace AsbCloudDb.Migrations
b.HasKey("Id"); b.HasKey("Id");
b.ToTable("t_well_section_type"); b.ToTable("t_well_section_type", (string)null);
b.HasComment("конструкция секции скважины"); b.HasComment("конструкция секции скважины");
@ -4875,7 +4875,7 @@ namespace AsbCloudDb.Migrations
b.HasKey("Id"); b.HasKey("Id");
b.ToTable("t_well_type"); b.ToTable("t_well_type", (string)null);
b.HasComment("конструкция скважины"); b.HasComment("конструкция скважины");
@ -4932,7 +4932,7 @@ namespace AsbCloudDb.Migrations
b.HasKey("IdTelemetry", "DateTime"); b.HasKey("IdTelemetry", "DateTime");
b.ToTable("t_telemetry_wits_base"); b.ToTable("t_telemetry_wits_base", (string)null);
}); });
modelBuilder.Entity("AsbCloudDb.Model.WITS.Record1", b => modelBuilder.Entity("AsbCloudDb.Model.WITS.Record1", b =>
@ -5096,7 +5096,7 @@ namespace AsbCloudDb.Migrations
b.HasIndex("TelemetryId"); b.HasIndex("TelemetryId");
b.ToTable("t_telemetry_wits_1"); b.ToTable("t_telemetry_wits_1", (string)null);
}); });
modelBuilder.Entity("AsbCloudDb.Model.WITS.Record50", b => modelBuilder.Entity("AsbCloudDb.Model.WITS.Record50", b =>
@ -5184,7 +5184,7 @@ namespace AsbCloudDb.Migrations
b.HasIndex("TelemetryId"); b.HasIndex("TelemetryId");
b.ToTable("t_telemetry_wits_50"); b.ToTable("t_telemetry_wits_50", (string)null);
}); });
modelBuilder.Entity("AsbCloudDb.Model.WITS.Record60", b => modelBuilder.Entity("AsbCloudDb.Model.WITS.Record60", b =>
@ -5236,7 +5236,7 @@ namespace AsbCloudDb.Migrations
b.HasIndex("TelemetryId"); b.HasIndex("TelemetryId");
b.ToTable("t_telemetry_wits_60"); b.ToTable("t_telemetry_wits_60", (string)null);
}); });
modelBuilder.Entity("AsbCloudDb.Model.WITS.Record61", b => modelBuilder.Entity("AsbCloudDb.Model.WITS.Record61", b =>
@ -5292,7 +5292,7 @@ namespace AsbCloudDb.Migrations
b.HasIndex("TelemetryId"); b.HasIndex("TelemetryId");
b.ToTable("t_telemetry_wits_61"); b.ToTable("t_telemetry_wits_61", (string)null);
}); });
modelBuilder.Entity("AsbCloudDb.Model.WITS.Record7", b => modelBuilder.Entity("AsbCloudDb.Model.WITS.Record7", b =>
@ -5380,7 +5380,7 @@ namespace AsbCloudDb.Migrations
b.HasIndex("TelemetryId"); b.HasIndex("TelemetryId");
b.ToTable("t_telemetry_wits_7"); b.ToTable("t_telemetry_wits_7", (string)null);
}); });
modelBuilder.Entity("AsbCloudDb.Model.WITS.Record8", b => modelBuilder.Entity("AsbCloudDb.Model.WITS.Record8", b =>
@ -5584,7 +5584,7 @@ namespace AsbCloudDb.Migrations
b.HasIndex("TelemetryId"); b.HasIndex("TelemetryId");
b.ToTable("t_telemetry_wits_8"); b.ToTable("t_telemetry_wits_8", (string)null);
}); });
modelBuilder.Entity("AsbCloudDb.Model.Cluster", b => modelBuilder.Entity("AsbCloudDb.Model.Cluster", b =>

View File

@ -2,6 +2,7 @@
using System; using System;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations.Schema;
using System.Text.Json;
namespace AsbCloudDb.Model namespace AsbCloudDb.Model
{ {
@ -16,7 +17,7 @@ namespace AsbCloudDb.Model
public string Key { get; set; } = null!; public string Key { get; set; } = null!;
[Column("setting_value", TypeName = "jsonb"), Comment("Значение настроек пользователя")] [Column("setting_value", TypeName = "jsonb"), Comment("Значение настроек пользователя")]
public object? Value { get; set; } public JsonDocument? Value { get; set; }
[ForeignKey(nameof(IdUser))] [ForeignKey(nameof(IdUser))]
public User User { get; set; } = null!; public User User { get; set; } = null!;

View File

@ -5,7 +5,7 @@ using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace AsbCloudInfrastructure.Services namespace AsbCloudInfrastructure.Repository
{ {
public class UserSettingsRepository : IUserSettingsRepository public class UserSettingsRepository : IUserSettingsRepository
{ {
@ -16,17 +16,17 @@ namespace AsbCloudInfrastructure.Services
this.context = context; this.context = context;
} }
public Task<object> GetOrDefaultAsync(int userId, string key, CancellationToken token) public Task<System.Text.Json.JsonDocument> GetOrDefaultAsync(int userId, string key, CancellationToken token)
=> context.Set<UserSetting>() => context.Set<UserSetting>()
.Where(s => s.IdUser == userId && s.Key == key) .Where(s => s.IdUser == userId && s.Key == key)
.Select(s=>s.Value) .Select(s => s.Value)
.FirstOrDefaultAsync(token); .FirstOrDefaultAsync(token);
public async Task<int> InsertAsync(int userId, string key, object value, CancellationToken token) public async Task<int> InsertAsync(int userId, string key, System.Text.Json.JsonDocument value, CancellationToken token)
{ {
var set = context.Set<UserSetting>(); var set = context.Set<UserSetting>();
if (await set.AnyAsync(s=>s.IdUser == userId && s.Key == key, token)) if (await set.AnyAsync(s => s.IdUser == userId && s.Key == key, token))
return IUserSettingsRepository.ErrorKeyIsUsed; return IUserSettingsRepository.ErrorKeyIsUsed;
var entity = new UserSetting var entity = new UserSetting
@ -42,7 +42,7 @@ namespace AsbCloudInfrastructure.Services
return await context.SaveChangesAsync(token); return await context.SaveChangesAsync(token);
} }
public async Task<int> UpdateAsync(int userId, string key, object value, CancellationToken token) public async Task<int> UpdateAsync(int userId, string key, System.Text.Json.JsonDocument value, CancellationToken token)
{ {
var set = context.Set<UserSetting>(); var set = context.Set<UserSetting>();
var updatingItem = await set var updatingItem = await set
@ -60,9 +60,9 @@ namespace AsbCloudInfrastructure.Services
{ {
var set = context.Set<UserSetting>(); var set = context.Set<UserSetting>();
var removingItem = await set var removingItem = await set
.FirstOrDefaultAsync(s=>s.IdUser == userId && s.Key ==key, token); .FirstOrDefaultAsync(s => s.IdUser == userId && s.Key == key, token);
if(removingItem is null) if (removingItem is null)
return IUserSettingsRepository.ErrorKeyNotFound; return IUserSettingsRepository.ErrorKeyNotFound;
set.Remove(removingItem); set.Remove(removingItem);

View File

@ -22,6 +22,8 @@ namespace AsbCloudWebApi.Controllers
[HttpGet("{key}")] [HttpGet("{key}")]
[Permission] [Permission]
[ProducesResponseType(typeof(object), (int)System.Net.HttpStatusCode.OK)]
[Produces("application/json")]
public virtual async Task<IActionResult> GetAsync( public virtual async Task<IActionResult> GetAsync(
[StringLength(255, MinimumLength = 1, ErrorMessage = "The key value cannot less then 1 character and greater then 255. ")] [StringLength(255, MinimumLength = 1, ErrorMessage = "The key value cannot less then 1 character and greater then 255. ")]
string key, string key,
@ -32,12 +34,14 @@ namespace AsbCloudWebApi.Controllers
return Forbid(); return Forbid();
var result = await service.GetOrDefaultAsync((int)userId, key, token).ConfigureAwait(false); var result = await service.GetOrDefaultAsync((int)userId, key, token).ConfigureAwait(false);
return Ok(result); var actionResult = new JsonResult(result);
actionResult.ContentType = "application/json";
return actionResult;
} }
[HttpPost("{key}")] [HttpPost("{key}")]
[Permission] [Permission]
public virtual async Task<ActionResult<int>> InsertAsync(string key, [FromBody] object value, CancellationToken token) public virtual async Task<ActionResult<int>> InsertAsync(string key, [FromBody] System.Text.Json.JsonDocument value, CancellationToken token)
{ {
var userId = User.GetUserId(); var userId = User.GetUserId();
if (userId is null) if (userId is null)
@ -50,7 +54,7 @@ namespace AsbCloudWebApi.Controllers
} }
[HttpPut("{key}")] [HttpPut("{key}")]
public virtual async Task<ActionResult<int>> UpdateAsync(string key, [FromBody] object value, CancellationToken token) public virtual async Task<ActionResult<int>> UpdateAsync(string key, [FromBody] System.Text.Json.JsonDocument value, CancellationToken token)
{ {
var userId = User.GetUserId(); var userId = User.GetUserId();
if (userId is null) if (userId is null)