在 .NET 7 上使用 Graph 和 C# 中的控制台应用程序发送电子邮件

Send email using Graph with console application in C# on .NET 7

提问人:ProgrammerBret 提问时间:11/14/2023 最后编辑:marc_sProgrammerBret 更新时间:11/14/2023 访问量:119

问:

在此处使用最新的 Microsoft Graph 示例,在此处使用 authProvider“客户端凭据提供程序”

以前,我看过一个类似的问题:无法通过 Microsoft 图形 API(C# 控制台)发送电子邮件,但我仍然无法使用最新示例使其工作。

我的 Azure 应用注册具有以下 API 权限:

enter image description here

我使用使用 .NET 7.0 和 C# 的代码:

namespace EmailGraphTesting
{
    public class Program
    {
        static async Task Main(string[] args)
        {
            await SendEmail.SendEmailAsync();
        }
    }
}

我打电话:

using Microsoft.Graph;
using Azure.Identity;
using Microsoft.Graph.Models;
using Microsoft.Graph.Me.SendMail; 

namespace EmailGraphTesting
{
    public class SendEmail
    {
        public static string tenantId = "<tenant Id>";
        public static string clientId = "<client Id>";
        public static string clientSecret = "<client secret>";
        public static string[] scopes = new[] { "https://graph.microsoft.com/.default" };

        public static async Task SendEmailAsync()
        {
            var options = new ClientSecretCredentialOptions
            {
                AuthorityHost = AzureAuthorityHosts.AzurePublicCloud,
            };

            // https://learn.microsoft.com/dotnet/api/azure.identity.clientsecretcredential
            var clientSecretCredential = new ClientSecretCredential(
                tenantId, clientId, clientSecret, options);

            var graphClient = new GraphServiceClient(clientSecretCredential, scopes);

            var requestBody = new SendMailPostRequestBody
            {
                Message = new Message
                {
                    Subject = "Outbox Test",
                    Body = new ItemBody
                    {
                        ContentType = BodyType.Text,
                        Content = "1st attempt"
                    },
                    ToRecipients = new List<Recipient>()
                    {
                        new Recipient
                        {
                            EmailAddress = new EmailAddress
                            {
                                Address = "<receiverEmail here>"
                            }
                        }
                    },
                },
            };
            await graphClient.Me.SendMail.PostAsync(requestBody);
        }
    }
}

运行代码时出现以下错误:

enter image description here

enter image description here

我也试过使用

await graphClient.Users["<email here>"].SendMail.PostAsync(requestBody);

在最后一行无济于事。

C# azure-active-directory microsoft-graph-api net-7.0

评论

1赞 Glen Scales 11/14/2023
代码看起来没问题,但错误非常通用,因此您需要更多地查看响应以找出可能出错的地方(可能有很多问题)。您可以创建自己的调试处理程序,或者只是通过 devblogs.microsoft.com/microsoft365dev/ 运行请求,这将允许您查看完整的请求和响应。
1赞 Tiny Wang 11/14/2023
Users["<email here>"]您确定您使用的电子邮件是正确的吗?我的意思是这里的电子邮件应该采用类似 的格式,并且应该为该帐户分配一个许可证,例如提供电子邮件功能的 M365 E3。[email protected]
1赞 user2250152 11/14/2023
使用客户端密码时,无法调用 graphClient.Me.xxx 终结点,因为你不代表任何用户登录。调用 graphClient.Users[“<email here>”] 时是否收到相同的异常。SendMail.PostAsync(requestBody)?

答:

1赞 Ikhtesam Afrin 11/14/2023 #1

我看到您正在使用客户端凭据提供程序发送电子邮件,但看起来 Me.SendMail 不支持客户端凭据提供程序,而是根据此 SO 线程使用授权代码流提供程序

感谢 Wang @Tiny 的评论,您可以使用 Users[“{id or userPrincipalName}”].发送邮件

请向注册的应用程序授予应用程序权限并使用以下代码,它将为您工作。Mail.Send

using Microsoft.Graph;
using Azure.Identity;
using Microsoft.Graph.Models;
using Microsoft.Graph.Users.Item.SendMail;

var scopes = new[] { "https://graph.microsoft.com/.default" };

var tenantId = "{tenant_id}";

// Values from app registration
var clientId = "{client_id}";
var clientSecret = "{client_Secret}";

// using Azure.Identity;
var options = new TokenCredentialOptions
{
    AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
};

var clientSecretCredential = new ClientSecretCredential(
    tenantId, clientId, clientSecret, options);

var accessToken = await clientSecretCredential.GetTokenAsync(new Azure.Core.TokenRequestContext(scopes) { });
var graphClient = new GraphServiceClient(clientSecretCredential, scopes);
var requestBody = new SendMailPostRequestBody
{
    Message = new Message
    {
        Subject = "Meet for lunch?",
        Body = new ItemBody
        {
            ContentType = BodyType.Text,
            Content = "The new cafeteria is open.",
        },
        ToRecipients = new List<Recipient>
        {
            new Recipient
            {
                EmailAddress = new EmailAddress
                {
                    Address = "{Recipient email address}",
                },
            },
        },
    },
    SaveToSentItems = false,
};

await graphClient.Users["*****@*****.onmicrosoft.com"].SendMail.PostAsync(requestBody);

评论

1赞 ProgrammerBret 11/15/2023
这奏效了!我现在明白需要一个令牌;使用 Microsoft.Graph.Users.Item.SendMail 是关键。这种情况似乎缺少 Microsoft 文档,因为我已经浏览了我能找到的所有教程。非常感谢...