Browse our Products
Aspose.Email for .NET 22.5 Release Notes
All Changes
Key | Summary | Category |
---|---|---|
EMAILNET-40450 | Implement IAsyncImapClient | Enhancement |
EMAILNET-40452 | Implement IAsyncSmtpClient | Enhancement |
EMAILNET-40451 | Implement IAsyncPop3Client | Enhancement |
EMAILNET-40596 | Graph client - reading unread messages with paging | Feature |
EMAILNET-40591 | Performance issue while migrating mails to office 365 | Bug |
EMAILNET-40574 | Creating MSG file issue with RTF embedded content | Bug |
EMAILNET-40605 | Maximum number of headers in one message should be less than or equal to 5. | Bug |
EMAILNET-40597 | Re-saving EML loses the calendar appointment message part | Bug |
EMAILNET-40595 | MailMessage.Date returns Current Date for MSG file | Bug |
EMAILNET-40593 | Attachments are lost after EML to MSG | Bug |
New Features
Enumerating Messages with Paging Support using Graph Client
The API provides the paging and filtering support for listing messages. This is very helpful where the mailbox has a large number of messages and requires a lot of time for retrieving the summary information about these.
List Messages from Exchange Server using IGraphClient
// reading unread messages with paging
using var client = GraphClient.GetClient(tokenProvider, config.Tenant);
// paging option
var itemsPerPage = 10;
// create unread messages filter
GraphQueryBuilder builder = new GraphQueryBuilder();
builder.IsRead.Equals(false);
var query = builder.GetQuery();
// list messages
var pageInfo = client.ListMessages(KnownFolders.Inbox, new PageInfo(itemsPerPage), query);
var messages = pageInfo.Items;
while (!pageInfo.LastPage)
{
pageInfo = client.ListMessages(KnownFolders.Inbox, pageInfo.NextPage, query);
messages.AddRange(pageInfo.Items);
}
// set messages state as read
foreach (var message in messages)
{
client.SetRead(message.ItemId);
}
A new approach to handling mail clients in asynchronous mode
We have added the following changes to the public API:
IAsyncSmtpClient
- Allows applications to send messages by using the Simple Mail Transfer Protocol (SMTP).SmtpClient.CreateAsync
- Creates a new instance of the Aspose.Email.Clients.Smtp.SmtpClient classSmtpSend
- Aspose.Email.Clients.Smtp.IAsyncSmtpClient.SendAsync(Aspose.Email.Clients.Smtp.Models.SmtpSend) method parameter set.SmtpForward
- The Aspose.Email.Clients.Smtp.IAsyncSmtpClient.ForwardAsync(Aspose.Email.Clients.Smtp.Models.SmtpForward) arguments.IAsyncImapClient
- Allows applications to access and manipulate messages by using the Internet Message Access Protocol (IMAP).ImapClient.CreateAsync
- Creates a new instance of the Aspose.Email.Clients.Imap.ImapClientclass
Code example
static readonly string tenantId = "YOU_TENANT_ID";
static readonly string clientId = "YOU_CLIENT_ID";
static readonly string redirectUri = "http://localhost";
static readonly string username = "username";
static readonly string[] scopes = { "https://outlook.office.com/IMAP.AccessAsUser.All", "https://outlook.office.com/SMTP.Send" };
static async Task Main(string[] args)
{
await SmtpAsync();
await ImapAsync();
Console.ReadLine();
}
static async Task SmtpAsync()
{
var tokenProvider = new TokenProvider(clientId, tenantId, redirectUri, scopes);
var client = SmtpClient.CreateAsync("outlook.office365.com", username, tokenProvider, 587).GetAwaiter().GetResult();
var eml = new MailMessage("from@domain.com", "to@domain.com", "test subj async", "test body async");
// send message
var sendOptions = SmtpSend.Create();
sendOptions.AddMessage(eml);
await client.SendAsync(sendOptions);
Console.WriteLine("message was sent");
// forward message
var fwdOptions = SmtpForward.Create();
fwdOptions.SetMessage(eml);
fwdOptions.AddRecipient("rec@domain.com");
await client.ForwardAsync(fwdOptions);
Console.WriteLine("message was forwarded");
}
static async Task ImapAsync()
{
var tokenProvider = new TokenProvider(clientId, tenantId, redirectUri, scopes);
var client = ImapClient.CreateAsync("outlook.office365.com", username, tokenProvider, 993).GetAwaiter().GetResult();
await client.SelectFolderAsync(ImapFolderInfo.InBox);
var messages = await client.ListMessagesAsync();
Console.WriteLine("Messages :" + messages.Count);
}
public class TokenProvider : IAsyncTokenProvider
{
private readonly PublicClientApplicationOptions _pcaOptions;
private readonly string[] _scopes;
public TokenProvider(string clientId, string tenantId, string redirectUri, string[] scopes)
{
_pcaOptions = new PublicClientApplicationOptions
{
ClientId = clientId,
TenantId = tenantId,
RedirectUri = redirectUri
};
_scopes = scopes;
}
public async Task<OAuthToken> GetAccessTokenAsync(bool ignoreExistingToken = false, CancellationToken cancellationToken = default)
{
var pca = PublicClientApplicationBuilder
.CreateWithApplicationOptions(_pcaOptions).Build();
try
{
var result = await pca.AcquireTokenInteractive(_scopes)
.WithUseEmbeddedWebView(false)
.ExecuteAsync(cancellationToken);
return new OAuthToken(result.AccessToken);
}
catch (MsalException ex)
{
Console.WriteLine($"Error acquiring access token: {ex}");
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex}");
}
return null;
}
public void Dispose()
{
}
}