【问题标题】:.net core email verification link on GET fails to cast object of type 'System.GUID' to object of type 'Sytem.String'GET 上的 .net 核心电子邮件验证链接无法将“System.GUID”类型的对象转换为“Sytem.String”类型的对象
【发布时间】:2021-10-14 10:40:58
【问题描述】:

我一直在使用 .net core 通过电子邮件发送用户验证链接。该链接构建得很好,看起来还不错,但是当我单击该链接时,我得到了一个打破页面的System.InvalidCastException。该链接会将您带到剃须刀页面,其构建方式如下:

var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
var codeBytes = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
var callbackUrl = Url.Page(      // the UrlHelperExtensions.Page method
    "/Account/ConfirmEmail",
    pageHandler: null,
    values: new { area = "Identity", userId = user.Id, code = codeBytes, returnUrl = svm.Input.ReturnUrl },
    protocol: Request.Scheme);                        

string htmlLink = HtmlEncoder.Default.Encode(callbackUrl);

htmlLink 是我应该能够单击以验证电子邮件地址的链接。然后我使用SmtpClient 发送电子邮件,如下所示:

public bool SendEmailMessage(string subjectHeader, string emailBody, string userEmail)
{

    MailMessage msg = CreateMailMessage(subjectHeader, emailBody, userEmail);

    // call this function to create the client and send the email
    return SendEmail(msg);
}

private MailMessage CreateMailMessage(string subject, string body, string email)
{
    MailMessage msg = new MailMessage
    {
        IsBodyHtml = true,
        From = new MailAddress(_ADMIN_ADDRESS, _FROM_NAME),
        Subject = subject,
        Body = body
    };

    msg.To.Add(new MailAddress(email));

    return msg;
}

private bool SendEmail(MailMessage message)
{
    using (var client = new SmtpClient(_SMTP_HOST, _PORT))
    {
        client.Credentials = new System.Net.NetworkCredential(_SMTP_USER, _SMTP_PASSWORD);
        client.EnableSsl = true;

        try
        {
            client.Send(message);
            return true;
        }
        catch (Exception ex)
        {
            Console.WriteLine("Email not sent");
            Console.WriteLine($"Error message: {ex.Message}");
            return false;
        }
    }
}

这会正确发送电子邮件,并且 Razor 页面会像这样处理 OnGet 方法:

public async Task<IActionResult> OnGetAsync(string userId, string code)
{
    if (userId == null || code == null)
    {
        return RedirectToPage("/Index");
    }

    UserId = userId;
    var user = await _userManager.FindByIdAsync(userId);
    if (user == null)
    {
        return NotFound($"Unable to load user with ID '{userId}'.");
    }

    code = Encoding.UTF8.GetString(WebEncoders.Base64UrlDecode(code));
    var result = await _userManager.ConfirmEmailAsync(user, code);

    StatusMessage = result.Succeeded ? "Thank you for confirming your email." : "Error confirming your email.";
    IsSuccess = result.Succeeded;
    return Page();
}

我一直在查看堆栈跟踪(见下文),但看起来所有使用的模块都是我只能间接使用的东西。我还没有找到为什么我得到一个InvalidCastException,但是我缺少一些代码吗?我的 Startup.cs 文件包含 app.UseHttpsRedirection();,但我认为这与转换错误无关。

有什么想法吗?

Aug 10 21:42:13 ip-172-31-36-195 web: #033[41m#033[30mfail#033[39m#033[22m#033[49m: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[1]
Aug 10 21:42:13 ip-172-31-36-195 web: An unhandled exception has occurred while executing the request.
Aug 10 21:42:13 ip-172-31-36-195 web: System.InvalidCastException: Unable to cast object of type 'System.Guid' to type 'System.String'.
Aug 10 21:42:13 ip-172-31-36-195 web: at Microsoft.Extensions.Internal.PropertyHelper.CallPropertySetter[TDeclaringType,TValue](Action`2 setter, Object target, Object value)
Aug 10 21:42:13 ip-172-31-36-195 web: at Microsoft.Extensions.Internal.PropertyHelper.SetValue(Object instance, Object value)
Aug 10 21:42:13 ip-172-31-36-195 web: at Microsoft.AspNetCore.Mvc.ViewFeatures.Filters.SaveTempDataPropertyFilterBase.SetPropertyValues(ITempDataDictionary tempData)
Aug 10 21:42:13 ip-172-31-36-195 web: at Microsoft.AspNetCore.Mvc.Filters.PageSaveTempDataPropertyFilter.OnPageHandlerExecuting(PageHandlerExecutingContext context)
Aug 10 21:42:13 ip-172-31-36-195 web: at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
Aug 10 21:42:13 ip-172-31-36-195 web: at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeNextPageFilterAsync()
Aug 10 21:42:13 ip-172-31-36-195 web: at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.Rethrow(PageHandlerExecutedContext context)
Aug 10 21:42:13 ip-172-31-36-195 web: at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
Aug 10 21:42:13 ip-172-31-36-195 web: at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeInnerFilterAsync()
Aug 10 21:42:13 ip-172-31-36-195 web: at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
Aug 10 21:42:13 ip-172-31-36-195 web: at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
Aug 10 21:42:13 ip-172-31-36-195 web: at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
Aug 10 21:42:13 ip-172-31-36-195 web: at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()

【问题讨论】:

    标签: url casting asp.net-identity url-parameters


    【解决方案1】:

    我与之前一直在工作的版本进行了比较,并更改了以下内容:

    在我的 Startup.cs 文件中,我删除了这些行:

    var builder = new ConfigurationBuilder()
        .SetBasePath(env.ContentRootPath)
        .AddJsonFile("appsettings.json",
            optional: false,
            reloadOnChange: true)
        .AddEnvironmentVariables();
    
    builder.AddUserSecrets<Startup>();
    

    在我的 ConfirmEmail.cshtml.cs 中,我删除了这些行:

    [TempData]
    public string UserId { get; set; }
    
    // in OnGetAsync:
    UserId = userId; // "userId" was passed in a URL parameter
    

    因此,n ConfirmEmail.cshtml 我删除了这一行:

    <a asp-controller="Transactions" asp-action="ResendVerificationlink" asp-route-userId="@Model.UserId">Resend Verification Link</a>
    

    因为模型不再具有属性UserId

    我不确定这些更改中的哪一个导致错误得到解决,但我想这是ConfirmEmail 类和剃刀页面中的UserId。如果其他人遇到同样的错误,希望这会有所帮助,我仍然对到底出了什么问题以及服务器为什么试图将 System.GUID 转换为 System.String 感到非常困惑。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-13
      • 2022-11-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-19
      相关资源
      最近更新 更多