将 System.String 转换为 System.Guid

问题描述 投票:0回答:1

我目前在尝试将数据库中具有 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 的数据库,但将来它会,所以如果我们有新的数据库,我可以简单地删除我当前拥有的转换器示例,而不必重写所有代码。

我希望有人可以帮助我解决这个问题,我知道这是可能的,但由于某种原因我无法让它发挥作用。

提前致谢!

c# sql entity-framework .net-8.0
1个回答
-3
投票

要将

System.String
转换为
System.Guid
,请使用
Guid.TryParse(string, out Guid)
Guid.Parse(string)
。这两种方法都提供可靠的转换,这对于在 .NET 应用程序中处理 GUID 至关重要。

© www.soinside.com 2019 - 2024. All rights reserved.