2

我们正在尝试使用 O365 统一 API 从我们的业务线应用程序发送电子邮件。我使用以下代码发送电子邮件。这会引发DataServiceQueryException 异常 "Unauthorized"

public async Task SendEmailAsUserAsync(EmailMessage message)
{
    try
    {
        var graphClient = await _authenticationHelper.GetGraphClientAsync();
        Message m = InitializeMessage(message);
        await graphClient.Me.SendMailAsync(m, true);
    }
    catch (DataServiceQueryException dsqe)
    {
        _logger.Error("Could not get files: " + dsqe.InnerException.Message, dsqe);
        throw;
    }
}

private static Message InitializeMessage(EmailMessage message)
{
    ItemBody body = new ItemBody {Content = message.Body, ContentType = BodyType.HTML};
    Message m = new Message
    {
        Body = body,
        Subject = message.Subject,
        Importance = Importance.Normal,
    };
    //Add all the to email ids
    if (message.ToRecipients != null)
        foreach (Models.Messaging.EmailAddress emailAddress in message.ToRecipients)
        {
            m.ToRecipients.Add(new Recipient { EmailAddress = new Microsoft.Graph.EmailAddress { Address = emailAddress.Address, Name = emailAddress.Name } });
        }
    return m;
}

_authenticationHelper.GetGraphClientAsync() 的代码是

public async Task<GraphService> GetGraphClientAsync()
{
    Uri serviceRoot = new Uri(appConfig.GraphResourceUriBeta + appConfig.Tenant);
    _graphClient = new GraphService(serviceRoot,
        async () => await AcquireTokenAsyncForUser(appConfig.GraphResourceUri, appConfig.Tenant));
    return _graphClient;
}

private async Task<string> AcquireTokenAsyncForUser(string resource, string tenantId)
{
    AuthenticationResult authenticationResult = await GetAccessToken(resource, tenantId);
    _accessCode = authenticationResult.AccessToken;
    return _accessCode;
}

private async Task<AuthenticationResult> GetAccessToken(string resource, string tenantId)
{
    string authority = appConfig.Authority;
    AuthenticationContext authenticationContext = new AuthenticationContext(authority);
    ClientCredential credential = new ClientCredential(appConfig.ClientId, appConfig.ClientSecret);
    string authHeader = HttpContext.Current.Request.Headers["Authorization"];
    string userAccessToken = authHeader.Substring(authHeader.LastIndexOf(' ')).Trim();
    UserAssertion userAssertion = new UserAssertion(userAccessToken);
    var authenticationResult = await authenticationContext.AcquireTokenAsync(resource, credential, userAssertion);
    return authenticationResult;
}

但是,如果我如下所示更改 SendEmailAsUserAsync 方法,则会发送电子邮件,但会引发 InvalidOperationException,并显示消息“复杂类型 'System.Object' 没有可设置的属性”。

public async Task SendEmailAsUserAsync(EmailMessage message)
{
    try
    {
        var graphClient = await _authenticationHelper.GetGraphClientAsync();
        Message m = InitializeMessage(message);
        //await graphClient.Me.SendMailAsync(m, true); //This did not work
        var user = await graphClient.Me.ExecuteAsync();
        await user.SendMailAsync(m, true);
    }
    catch (DataServiceQueryException dsqe)
    {
        _logger.Error("Could not get files: " + dsqe.InnerException.Message, dsqe);
        throw;
    }  
}

任何人都可以指出这里是否有问题。

4

2 回答 2

0

检查下面的示例项目,这有一个工作示例(在 app.config 中填写 ClientID 等之后)。

Office 365 API 演示应用程序

对于发送电子邮件,它使用以下功能,如果您设置正确,该功能将起作用。它还具有许多使用Authorization Code Grant Flow进行身份验证的功能。

    public async Task SendMail(string to, string subject, string body)
    {
        var client = await this.AuthenticationHelper
            .EnsureOutlookServicesClientCreatedAsync(
            Office365Capabilities.Mail.ToString());

        Message mail = new Message();
        mail.ToRecipients.Add(new Recipient() 
        {
            EmailAddress = new EmailAddress
            {
                Address = to,
            }
        });
        mail.Subject = subject;
        mail.Body = new ItemBody() { Content = body, ContentType = BodyType.HTML };

        await client.Me.SendMailAsync(mail, true);
    }
于 2015-08-15T22:04:27.900 回答
0

实际上,图形 API 没有组装包装器。

Microsoft.Graph.dll已弃用。

所以,你应该:

  1. 处理 REST 请求:请参见此处: http: //graph.microsoft.io/docs/api-reference/v1.0/api/message_send
  2. 使用 Microsoft.Vipr 项目生成包装器:请参见此处:https ://github.com/microsoft/vipr

对于身份验证,ADAL 工作正常 :)

于 2015-12-19T20:32:15.317 回答