You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.Net Core 5.0用户注册触发MailboxAddress构造方法缺失异常

问题背景

在基于.Net Core 5.0开发的项目中,执行用户注册操作时返回异常。初步排查怀疑问题由Netcore.MailKit导致,不排除AutoMapper侧存在配置问题,本次使用的是日常开发常用的成熟代码结构。运行时返回的具体异常如下:

MissingMethodException: Method not found: 'Void MimeKit.MailboxAddress..ctor(System.String)'

项目依赖版本

  • Netcore.MailKit Version: 2.0.3
  • Microsoft.AspNetcore.Http.Features version: 5.0.9

相关业务代码

用户注册方法

if (!ModelState.IsValid)
{
    return View(userModel);
}

var user = _mapper.Map<User>(userModel);

var result = await userManager.CreateAsync(user, userModel.Password);
if (!result.Succeeded)
{
    foreach (var error in result.Errors)
    {
        ModelState.TryAddModelError(error.Code, error.Description);
    }

    return View(userModel);
}
await userManager.AddToRoleAsync(user, "Customer");

var token = await userManager.GenerateEmailConfirmationTokenAsync(user);
var confirmationLink = Url.Action(nameof(ConfirmEmail), "Account", new { token, email = user.Email }, Request.Scheme);

var message = new Message(new string[] { user.Email }, "Confirmation email link", confirmationLink, null);
await emailSender.SendEmailAsync(message);

return RedirectToAction(nameof(SuccessRegister));

EmailSender类实现

public class EmailSender : IEmailSender
{
    private readonly EmailConfiguration _emailConfig;

    public EmailSender(EmailConfiguration emailConfig)
    {
        _emailConfig = emailConfig;
    }

    public void SendEmail(Message message)
    {
        var emailMessage = CreateEmailMessage(message);
        Send(emailMessage);
    }

    public async Task SendEmailAsync(Message message)
    {
        var mailMessage = CreateEmailMessage(message);
        await SendAsync(mailMessage);
    }

    private MimeMessage CreateEmailMessage(Message message)
    {
        var emailMessage = new MimeMessage();
        emailMessage.From.Add(new MailboxAddress(_emailConfig.From));
        emailMessage.To.AddRange(message.To);
        emailMessage.Subject = message.Subject;

        var bodyBuilder = new BodyBuilder { HtmlBody = string.Format("<h2 style='color:red;'>{0}</h2>", message.Content) };

        if (message.Attachments != null && message.Attachments.Any())
        {
            byte[] fileBytes;
            foreach (var attachment in message.Attachments)
            {
                using (var ms = new MemoryStream())
                {
                    attachment.CopyTo(ms);
                    fileBytes = ms.ToArray();
                }
                bodyBuilder.Attachments.Add(attachment.FileName, fileBytes, ContentType.Parse(attachment.ContentType));
            }
        }

        emailMessage.Body = bodyBuilder.ToMessageBody();
        return emailMessage;
    }

    private void Send(MimeMessage mailMessage)
    {
        using (var client = new SmtpClient())
        {
            try
            {
                client.Connect(_emailConfig.SmtpServer, _emailConfig.Port, true);
                client.AuthenticationMechanisms.Remove("XOAUTH2");
                client.Authenticate(_emailConfig.UserName, _emailConfig.Password);
                client.Send(mailMessage);
            }
            catch
            {
                // 记录错误日志或抛出异常
                throw;
            }
            finally
            {
                client.Disconnect(true);
                client.Dispose();
            }
        }
    }

    private async Task SendAsync(MimeMessage mailMessage)
    {
        using (var client = new SmtpClient())
        {
            try
            {
                await client.ConnectAsync(_emailConfig.SmtpServer, _emailConfig.Port, true);
                client.AuthenticationMechanisms.Remove("XOAUTH2");
                await client.AuthenticateAsync(_emailConfig.UserName, _emailConfig.Password);
                await client.SendAsync(mailMessage);
            }
            catch
            {
                // 记录错误日志或抛出异常
                throw;
            }
            finally
            {
                await client.DisconnectAsync(true);
                client.Dispose();
            }
        }
    }
}

Message类定义

public class Message
{
    public List<MailboxAddress> To { get; set; }
    public string Subject { get; set; }
    public string Content { get; set; }
    public IFormFileCollection Attachments { get; set; }

    public Message(IEnumerable<string> to, string subject, string content, IFormFileCollection attachments)
    {
        To = new List<MailboxAddress>();
        To.AddRange(to.Select(x => new MailboxAddress(x)));
        Subject = subject;
        Content = content;
        Attachments = attachments;
    }
}

Startup服务注册代码

.AddEntityFrameworkStores<AppDbContext>()
    .AddDefaultTokenProviders()
    .AddErrorDescriber<TurkishIdentityErrorDescriber>();

var emailConfig = Configuration.GetSection("EmailConfiguration").Get<EmailConfiguration>();
services.AddSingleton(emailConfig);
services.AddSingleton<Extension>();
services.AddScoped<IEmailSender, EmailSender>();
services.Configure<DataProtectionTokenProviderOptions>(opt => opt.TokenLifespan = TimeSpan.FromHours(2));
services.AddAutoMapper(typeof(Startup));
异常原因

该异常与AutoMapper配置无关,属于典型的依赖版本不兼容问题。
Netcore.MailKit 2.0.3 依赖2.x版本的MimeKit,此版本中MailboxAddress提供了仅接收1个字符串参数(邮箱地址)的构造函数。但项目运行时实际加载的是3.0及以上版本的MimeKit——高版本MimeKit出于邮箱地址解析准确性考虑,移除了这个单参数构造函数,要求必须传入「显示名称」「邮箱地址」两个参数,因此运行时找不到匹配的构造方法,直接抛出MissingMethodException。
出现隐式加载高版本MimeKit的原因,一般是项目中其他NuGet包间接依赖了高版本MimeKit,NuGet还原时自动升级了依赖版本,覆盖了Netcore.MailKit要求的低版本依赖。

修复方案

两种方案按需选择即可:

方案1:适配高版本MimeKit构造函数(推荐)

无需调整依赖版本,仅修改所有调用MailboxAddress单参数构造的位置,改为双参数形式即可,显示名称如果不需要可以传空字符串:

  1. 修改Message类构造函数中的地址转换逻辑:
// 原代码
To.AddRange(to.Select(x => new MailboxAddress(x)));
// 修改后
To.AddRange(to.Select(x => new MailboxAddress("", x)));
  1. 修改EmailSender类中设置发件人的代码:
// 原代码
emailMessage.From.Add(new MailboxAddress(_emailConfig.From));
// 修改后
emailMessage.From.Add(new MailboxAddress("", _emailConfig.From));

修改完成后重新编译运行即可解决问题。

方案2:锁定MimeKit为兼容低版本

如果不想修改业务代码,可以在项目csproj文件中手动添加MimeKit的版本引用,强制使用和Netcore.MailKit 2.0.3兼容的2.x版本,添加如下配置:

<ItemGroup>
  <PackageReference Include="MimeKit" Version="2.15.0" />
</ItemGroup>

添加后重新执行NuGet包还原即可。

内容的提问来源于stack exchange,提问作者Ramazan Musluoğlu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 11:54:22