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

ASP.NET MVC集成SendGrid遇apiKey空值异常及环境变量疑问

ASP.NET MVC配置SendGrid时API Key空值异常问题及解决

问题描述

首次在ASP.NET MVC应用中配置SendGrid服务,尝试通过API Key完成身份验证,但持续触发Value cannot be null. Parameter name: apiKey异常。不清楚存储SendGrid密钥的环境变量名称、位置及设置方式,网上未找到明确指引,无法推进。

异常信息

Value cannot be null.
Parameter name: apiKey
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.ArgumentNullException: Value cannot be null.
Parameter name: apiKey

Source Error:

Line 30:         {
Line 31:             var apiKey = Environment.GetEnvironmentVariable("https://app.sendgrid.com/settings/api_keys/API1");
Line 32:             var client = new SendGridClient(apiKey);
Line 33:             var from = new EmailAddress("test@example.com", "Example User");
Line 34:             var subject = "Sending with SendGrid is Fun";

Source File: C:\Users\M\source\repos\AssessmentTask2\AssessmentTask2\App_Start\IdentityConfig.cs    Line: 32

当前使用的IdentityConfig.cs代码

using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using System.Web;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin;
using Microsoft.Owin.Security;
using AssessmentTask2.Models;
using SendGrid;
using SendGrid.Helpers.Mail;
using System.Configuration;
using System.Diagnostics;
using System.Net;

namespace AssessmentTask2
{
    public class EmailService : IIdentityMessageService
    {
        public async Task SendAsync(IdentityMessage message)
        {
            await configSendGridasync(message);
        }
        //SG.uSDrb4hJQmKPJbTNr_eW2w.lMMbl1c5P8rxdn6cwBr3xdrqXun
        static async Task configSendGridasyn(IdentityMessage message)
        {
            var apiKey = Environment.GetEnvironmentVariable("NAME_OF_THE_ENVIRONMENT_VARIABLE_FOR_YOUR_SENDGRID_KEY");
            var client = new SendGridClient(apiKey);
            var from = new EmailAddress("test@example.com", "Example User");
            var subject = "Sending with SendGrid is Fun";
            var to = new EmailAddress("test@example.com", "Example User");
            var plainTextContent = "and easy to do anywhere, even with C#";
            var htmlContent = "<strong>and easy to do anywhere, even with C#</strong>";
            var msg = MailHelper.CreateSingleEmail(from, to, subject, plainTextContent, htmlContent);
            var response = await client.SendEmailAsync(msg);

            if (client != null)
            {
                await client.SendEmailAsync(msg);
            }
            else
            {
                Trace.TraceError("Failed to create Web transport.");
                await Task.FromResult(0);
            }
        }
    }

    public class SmsService : IIdentityMessageService
    {
        public Task SendAsync(IdentityMessage message)
        {
            // Plug in your SMS service here to send a text message.
            return Task.FromResult(0);
        }
    }

    // Configure the application user manager used in this application. UserManager is defined in ASP.NET Identity and is used by the application.
    public class ApplicationUserManager : UserManager<ApplicationUser>
    {
        public ApplicationUserManager(IUserStore<ApplicationUser> store)
            : base(store)
        {
        }

        public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context) 
        {
            var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));
            // Configure validation logic for usernames
            manager.UserValidator = new UserValidator<ApplicationUser>(manager)
            {
                AllowOnlyAlphanumericUserNames = false,
                RequireUniqueEmail = true
            };

            // Configure validation logic for passwords
            manager.PasswordValidator = new PasswordValidator
            {
                RequiredLength = 6,
                RequireNonLetterOrDigit = true,
                RequireDigit = true,
                RequireLowercase = true,
                RequireUppercase = true,
            };

            // Configure user lockout defaults
            manager.UserLockoutEnabledByDefault = true;
            manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5);
            manager.MaxFailedAccessAttemptsBeforeLockout = 5;

            // Register two factor authentication providers. This application uses Phone and Emails as a step of receiving a code for verifying the user
            // You can write your own provider and plug it in here.
            manager.RegisterTwoFactorProvider("Phone Code", new PhoneNumberTokenProvider<ApplicationUser>
            {
                MessageFormat = "Your security code is {0}"
            });
            manager.RegisterTwoFactorProvider("Email Code", new EmailTokenProvider<ApplicationUser>
            {
                Subject = "Security Code",
                BodyFormat = "Your security code is {0}"
            });
            manager.EmailService = new EmailService();
            manager.SmsService = new SmsService();
            var dataProtectionProvider = options.DataProtectionProvider;
            if (dataProtectionProvider != null)
            {
                manager.UserTokenProvider = 
                    new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity"));
            }
            return manager;
        }
    }

    // Configure the application sign-in manager which is used in this application.
    public class ApplicationSignInManager : SignInManager<ApplicationUser, string>
    {
        public ApplicationSignInManager(ApplicationUserManager userManager, IAuthenticationManager authenticationManager)
            : base(userManager, authenticationManager)
        {
        }

        public override Task<ClaimsIdentity> CreateUserIdentityAsync(ApplicationUser user)
        {
            return user.GenerateUserIdentityAsync((ApplicationUserManager)UserManager);
        }

        public static ApplicationSignInManager Create(IdentityFactoryOptions<ApplicationSignInManager> options, IOwinContext context)
        {
            return new ApplicationSignInManager(context.GetUserManager<ApplicationUserManager>(), context.Authentication);
        }
    }
}

解决步骤

1. 修正环境变量使用错误

  • 你当前代码中使用的环境变量名称是无效的:"https://app.sendgrid.com/settings/api_keys/API1" 和 "NAME_OF_THE_ENVIRONMENT_VARIABLE_FOR_YOUR_SENDGRID_KEY" 都不是正确的变量名。
  • 环境变量名称由你自定义,推荐用SENDGRID_API_KEY作为变量名。

2. 设置环境变量(Windows本地开发)

方法一:系统/用户环境变量

  1. 右键「此电脑」→「属性」→「高级系统设置」→「环境变量」
  2. 在「用户变量」或「系统变量」区域点击「新建」,变量名填SENDGRID_API_KEY,变量值填你的SendGrid API密钥(比如代码注释里的SG.uSDrb4hJQmKPJbTNr_eW2w.lMMbl1c5P8rxdn6cwBr3xdrqXun)
  3. 重启Visual Studio,让环境变量生效

方法二:项目调试环境变量

  1. 在Visual Studio中右键项目→「属性」→「调试」
  2. 找到「环境变量」区域,点击「编辑」,添加SENDGRID_API_KEY=你的API密钥

3. 修正代码中的环境变量获取语句

把获取API Key的代码改成:

var apiKey = Environment.GetEnvironmentVariable("SENDGRID_API_KEY");

4. 修复其他代码问题

  • 方法名拼写错误:configSendGridasyn 应改为configSendGridasync(少了一个字母c),否则会出现调用不匹配的问题
  • 移除重复发送逻辑:代码中先后两次调用await client.SendEmailAsync(msg);,删掉其中一次
  • 利用传入的message参数:当前代码硬编码了邮件内容,应替换为message中的数据,比如:
    var to = new EmailAddress(message.Destination);
    var subject = message.Subject;
    var plainTextContent = message.Body;
    

修正后的configSendGridasync方法示例

static async Task configSendGridasync(IdentityMessage message)
{
    var apiKey = Environment.GetEnvironmentVariable("SENDGRID_API_KEY");
    if (string.IsNullOrEmpty(apiKey))
    {
        Trace.TraceError("SendGrid API Key未在环境变量中配置");
        return;
    }

    var client = new SendGridClient(apiKey);
    var from = new EmailAddress("你的验证邮箱@example.com", "你的应用名称");
    var to = new EmailAddress(message.Destination);
    var subject = message.Subject;
    var plainTextContent = message.Body;
    var htmlContent = $"<p>{message.Body}</p>";
    
    var msg = MailHelper.CreateSingleEmail(from, to, subject, plainTextContent, htmlContent);
    var response = await client.SendEmailAsync(msg);
    
    Trace.TraceInformation($"SendGrid响应状态: {response.StatusCode}");
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 23:45:35