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

ASP.NET Core MVC表单发邮件报ArgumentNullException:原因与解决

ASP.NET Core MVC联系表单发送邮件报错:ArgumentNullException 解决

我在ASP.NET Core MVC项目中开发联系表单发送邮件功能,运行时抛出ArgumentNullException: Value cannot be null. (Parameter 'address')错误,相关代码及报错信息如下:


相关代码

模型类(SendMail.cs)

public class SendMail : IEmailSender
{
    public async Task SendEmailAsync(string email, string subject, string htmlMessage)
    {
        using (MailMessage mailMessage = new MailMessage()) 
        {
            mailMessage.From = new MailAddress(email);
            mailMessage.Subject = subject;
            mailMessage.Body = email + htmlMessage;
            mailMessage.IsBodyHtml = true;
            mailMessage.To.Add(new MailAddress("abc@gmail.com"));

            SmtpClient smtp = new SmtpClient();
            smtp.Host = "smtp.gmail.com";
            smtp.EnableSsl = true;

            System.Net.NetworkCredential NetworkCred = new System.Net.NetworkCredential();
            NetworkCred.UserName = "abc@gmail.com";
            NetworkCred.Password = "cxhzevbomlrgebrb";

            smtp.UseDefaultCredentials = true;
            smtp.Credentials = NetworkCred;
            smtp.Port = 587;

            await smtp.SendMailAsync(mailMessage);
        }
    }
}

视图(Contact.cshtml)

@model eProject3_6.ViewModel.Contact;
<div class="row">
        <div class="eight columns">
            <!-- form -->
            <form method="post">
                <fieldset>
                    <div>
                        <label asp-for="Email">Email <span class="required">*</span></label>
                        <input asp-for="Email" type="text" value="" size="35" id="contactEmail" name="contactEmail">
                        <span asp-validation-for="Email" class="text-danger"></span>
                    </div>
                    <div>
                        <label asp-for="Subject">Subject</label>
                        <input asp-for="Subject" type="text" value="" size="35" id="contactSubject" name="contactSubject">
                        <span asp-validation-for="Subject" class="text-danger"></span>
                    </div>
                    <div>
                        <label asp-for="Message">Message <span class="required">*</span></label>
                        <textarea asp-for="Message" cols="50" rows="15" id="contactMessage" name="contactMessage"></textarea>
                        <span asp-validation-for="Message" class="text-danger"></span>
                    </div>
                    <div>
                        <button class="submit">Submit</button>                        
                        <span id="image-loader">
                            <img alt="" src="~/ContactForm/images/loader.gif">
                        </span>
                    </div>
                </fieldset>
            </form> <!-- Form End -->
        </div>

控制器类(HomeController.cs)

[HttpGet]
public IActionResult Contact() 
{ 
    return View();
}

[HttpPost]
public async Task<IActionResult> Contact(Contact contact)
{
    var msg = contact.Subject + "" + contact.Message;
    await _emailSender.SendEmailAsync(contact.Email, "Contact Message", msg);
    ViewBag.Message = "Thank for your contact";
    return View();
}

ViewModel类(Contact.cs)

public class Contact
{
    public string Email { get ; set ; }
    public string Subject { get; set; }
    public string Message { get; set; }
}

报错信息

ArgumentNullException: Value cannot be null. (Parameter 'address')
System.Net.Mail.MailAddress.TryParse(string address, string displayName, Encoding displayNameEncoding, out ValueTuple<string, string, string, Encoding> parsedData, bool throwExceptionIfFail)
System.Net.Mail.MailAddress..ctor(string address)
eProject3_6.Models.SendMail.SendEmailAsync(string email, string subject, string htmlMessage) in SendMail.cs
mailMessage.From = new MailAddress(email);
eProject3_6.Controllers.HomeController.Contact(Contact contact) in HomeController.cs
await _emailSender.SendEmailAsync(contact.Email, "Contact Message", msg);
...(后续调用栈省略)


错误原因

  1. 模型绑定失败:视图中手动指定name="contactEmail"等属性,覆盖了asp-for生成的与ViewModel字段匹配的name值,导致表单提交时contact.Email无法被正确赋值,最终传入SendEmailAsync的参数为null。
  2. 缺少数据验证:ViewModel未添加必填验证特性,用户即使不填Email也能提交表单,触发空值错误。
  3. SMTP逻辑错误:直接将用户输入的Email作为发件人地址,不符合Gmail SMTP服务要求(发件人必须与认证邮箱一致),同时smtp.UseDefaultCredentials = true会覆盖后续设置的认证信息,导致SMTP认证失败。

解决步骤

1. 修复模型绑定问题

移除视图中手动设置的name属性,让asp-for自动生成匹配ViewModel字段的name值:

<!-- 修正后的Email输入框 -->
<input asp-for="Email" type="text" value="" size="35" id="contactEmail">
<!-- 修正后的Subject输入框 -->
<input asp-for="Subject" type="text" value="" size="35" id="contactSubject">
<!-- 修正后的Message文本框 -->
<textarea asp-for="Message" cols="50" rows="15" id="contactMessage"></textarea>

2. 添加数据验证到ViewModel

给ViewModel字段添加验证特性,强制用户填写必填项:

using System.ComponentModel.DataAnnotations;

public class Contact
{
    [Required(ErrorMessage = "请输入邮箱地址")]
    [EmailAddress(ErrorMessage = "请输入有效的邮箱地址")]
    public string Email { get ; set ; }
    
    public string Subject { get; set; }
    
    [Required(ErrorMessage = "请输入消息内容")]
    public string Message { get; set; }
}

3. 完善控制器验证逻辑

在Post方法中先检查模型有效性,无效则返回视图显示错误:

[HttpPost]
public async Task<IActionResult> Contact(Contact contact)
{
    if (!ModelState.IsValid)
    {
        return View(contact);
    }
    var msg = $"发件人邮箱:{contact.Email}\n主题:{contact.Subject}\n消息:{contact.Message}";
    await _emailSender.SendEmailAsync(contact.Email, "Contact Message", msg);
    ViewBag.Message = "感谢您的联系";
    return View();
}

4. 修正SendMail中的SMTP配置

  • 发件人地址改为SMTP认证邮箱,将用户邮箱设为回复地址
  • 调整UseDefaultCredentials顺序,避免覆盖认证信息:
public async Task SendEmailAsync(string email, string subject, string htmlMessage)
{
    using (MailMessage mailMessage = new MailMessage()) 
    {
        // 发件人必须与SMTP认证邮箱一致
        mailMessage.From = new MailAddress("abc@gmail.com");
        // 设置回复地址为用户邮箱
        mailMessage.ReplyToList.Add(new MailAddress(email));
        mailMessage.Subject = subject;
        mailMessage.Body = htmlMessage;
        mailMessage.IsBodyHtml = false; // 纯文本消息更稳定,如需HTML可改为true
        mailMessage.To.Add(new MailAddress("abc@gmail.com"));

        SmtpClient smtp = new SmtpClient();
        smtp.Host = "smtp.gmail.com";
        smtp.EnableSsl = true;

        System.Net.NetworkCredential NetworkCred = new System.Net.NetworkCredential();
        NetworkCred.UserName = "abc@gmail.com";
        NetworkCred.Password = "cxhzevbomlrgebrb";

        // 先关闭默认凭证,再设置自定义凭证
        smtp.UseDefaultCredentials = false;
        smtp.Credentials = NetworkCred;
        smtp.Port = 587;

        await smtp.SendMailAsync(mailMessage);
    }
}

5. 额外配置注意

  • 若Gmail账户开启了两步验证,需使用应用专用密码替代原密码
  • 若未开启两步验证,需在Gmail账户设置中开启"低安全性应用访问"(或使用更安全的OAuth2认证)

内容的提问来源于stack exchange,提问作者Noo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 16:44:55