我目前在尝试将数据库中具有 guid 行为的字符串转换为应用程序中的实际 Guid 时遇到一些问题。我已经尝试了很多东西,目前这就是我的“用户”设置:
[EntityTypeConfiguration(typeof(UserConfiguration))]
[Table("AspNetUsers")]
public class User : IdentityUser<Guid>
{
}
如您所见,我使用
Guid
作为 TKey
。在我的课程顶部,您可以看到表架构,其中我只想使用标准 AspNetUsers
表。在上面我正在应用我的EntityTypeConfiguration
,如下所示
public class UserConfiguration : IEntityTypeConfiguration<User>
{
public void Configure(EntityTypeBuilder<User> builder)
{
builder.HasKey(x => x.Id);
builder.Property(e => e.Id)
.IsRequired()
.HasConversion
(
guid => guid.ToString(),
str => Guid.Parse(str)
);
}
}
为了演示我的用例,我使用了一个名为
的端点[HttpPost]
[Route(SessionRoutes.ProcessLogin)]
public async Task<ActionResult<LoginResult>> ProcessLogin(string userName, string password, bool isPersist)
{
try
{
LoginResult result = new();
string errorMessage = string.Empty;
if (_userSessionService.IsBrowserValid(_browserService, _deviceService, out errorMessage))
{
result = await _userSessionService.ProcessLogin(userName.Trim(), password, isPersist);
}
else
{
return BadRequest($"Login error: {errorMessage}");
}
return Ok(result);
}
catch (Exception ex)
{
_logger.Log(LogLevel.Error, ex.Message);
return BadRequest(new { code = "MANAGEMENTAPI-LOGGEDINUSERVALIDATION-999 ", message = "Er is iets mis gegaan. Probeer het opnieuw. " + ex.Message });
public async Task<LoginResult> ProcessLogin(string userName, string password, bool isPersist)
{
try
{
LoginResult result = new();
User appUser = new();
string clientName = ConfigHelper.ClientName(_configuration);
if (_httpContextAccessor.HttpContext.Request.Headers["UrlReferrer"].ToString == null)
{
return await Task.FromResult(result);
}
string uname = (userName + "_" + clientName);
appUser = await _userManager.FindByNameAsync(uname);
IdentityResult identityResult = await _passwordHelper.ValidateAsync(_userManager, appUser, password);
if (identityResult.Succeeded && appUser != null)
{
Guid Id = appUser.Id;
if (await _identityService.VerifyPasswordAsync(appUser, password))
{
if (_userManager.SupportsUserLockout && await _userManager.GetAccessFailedCountAsync(appUser) > 0)
{
await _userManager.ResetAccessFailedCountAsync(appUser);
}
}
else
{
if (_userManager.SupportsUserLockout && await _userManager.GetLockoutEnabledAsync(appUser))
{
await _userManager.AccessFailedAsync(appUser);
}
}
var status = await _signInManager.HandleSignInResultAsync(await _signInManager.CheckPasswordSignInAsync(appUser, password, true));
}
return await Task.FromResult(result);
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
}
}
我现在执行以下操作
var appUser = await _userManager.FindByNameAsync(userName);
从 UserManager(即 Identity UserManager)调用此函数后,我在 Swagger 中收到以下错误:
Unable to cast object of type 'System.Guid' to type 'System.String'
System.InvalidCastException: Unable to cast object of type 'System.Guid' to type 'System.String'.
at Microsoft.Data.SqlClient.SqlBuffer.get_String()
at Microsoft.Data.SqlClient.SqlDataReader.GetString(Int32 i)
at lambda_method31(Closure, QueryContext, DbDataReader, ResultContext, SingleQueryResultCoordinator)
at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()
Exception thrown: 'System.InvalidCastException' in System.Private.CoreLib.dll
Exception thrown: 'System.Exception' in ManagementAPI.dll
Exception thrown: 'System.Exception' in System.Private.CoreLib.dll
ManagementAPI.Controllers.UserSessionController: Error: Unable to cast object of type 'System.Guid' to type 'System.String'.
这就是我的 UserManager 设置方式:
public class IdentityUserManager : UserManager<User>
{
private readonly IdentityContext _context;
public IdentityUserManager(IUserStore<User> store, IOptions<IdentityOptions> optionsAccessor, IPasswordHasher<User> passwordHasher, IEnumerable<IUserValidator<User>> userValidators, IEnumerable<IPasswordValidator<User>> passwordValidators, ILookupNormalizer keyNormalizer, IdentityErrorDescriber errors, IServiceProvider services, ILogger<UserManager<User>> logger, IdentityContext context)
: base(store, optionsAccessor, passwordHasher, userValidators, passwordValidators, keyNormalizer, errors, services, logger)
{}
}
我尝试了多种选项将数据库中的字符串转换为有效的 GUID。 为了支持我的数据库声明,我在这里有一个屏幕截图:
我最终真正想要的是简单地将数据库中具有字符串作为 id 的完整 AspNetUser 转换为使用 Guid 和 IdentityUser 转换为我的项目中的整个对象。尽管瓶颈似乎在于它是字符串而不是指南。现在您可能在想“为什么不更改该列的数据库值”。好吧,我根本不能,我们正在重构我们的项目,并且仍然使用一个不完全支持 Id Guid 的数据库,但将来它会,所以如果我们有新的数据库,我可以简单地删除我当前拥有的转换器示例,而不必重写所有代码。
我希望有人可以帮助我解决这个问题,我知道这是可能的,但由于某种原因我无法让它发挥作用。
提前致谢!
要将
System.String
转换为 System.Guid
,请使用 Guid.TryParse(string, out Guid)
或 Guid.Parse(string)
。这两种方法都提供可靠的转换,这对于在 .NET 应用程序中处理 GUID 至关重要。