When using Sendgrid SDK 6.3.4 on a console application, in an attachment if a filename has especial characters, the email will be delivered without attachment.
No errors logged, just the email arriving without the attachment.
For example:
myMessage.AddAttachment(file, "Información.csv"); // won't work
myMessage.AddAttachment(file, "Informacion.csv"); // will work
Hello @walmon,
Thanks for reporting this issue!
I have verified that this is not an API issue. This issue is with this library.
I have added this to our backlog to fix.
With Best Regards,
Elmer
I might have another version of this issue. When sending an attachment with a filename "Reservation Report 1. 9. 2016 0:00:00 - 3. 9. 2016 0:00:00.xlsx", an e-mail with the filename "00.xlsx" is delivered.
It's a bit strange that it's the part of the filename that comes after the last header name:value separator (colon)... Is it the lib, the API, or is it me? Thanks!
Thanks for the additional feedback @jirihelmich. I'll add your vote to this task to help it rise faster in our backlog queue.
Thanks. Based on this, we retrospectively identified some more issues from the past related to this. We were experiencing lost attachments with no good reason in the e-mail source code. We thought it's SPF + spamfilter, throwing away PDFs (like bills, etc.), but as our attachments are localized and may contain customer name (e.g. Chinese, Japanese, Greek), this seem to be the real issue.
Do you have any estimates? Or, is there any way how we could help to fix this? Otherwise, we would have to somehow hack our system and implement transliteration to ASCII, but that's probably more work than fixing this.
Thanks for any further information.
Thanks @jirihelmich,
All of this information should help when it comes time for me to dig in on this one. I've added more votes to this issue based on the +1's on your previous comment.
Hi, thanks for the additional information.
Just wanted to confirm that once we implemented a workaround (transliteration and sanitize of "wild" characters), the attachments are now going through. Our Greek customers are now a bit happier :-)
Thanks for the update @jirihelmich,
I see that there are some more +1s on this issue. I've added those to the ticket in our backlog.
I looked at the code:
AddAttachment method)But nothing there stands out, it's just normal string assignments.
The SendGridMessage instance (which contains the attachments) gets passed to the SendEmailAsync method in the SendGridClient class which seemingly properly serializes it to a JSON string (using the Serialize method) before it gets passed to the RequestAsync method.
var message = new SendGridMessage();
message.AddAttachment("Filename_foo", "content");
message.AddAttachment("Filename_åäö", "content");
var serialized = message.Serialize();
Output:
{
"attachments": [
{
"content": "content",
"filename": "Filename_foo"
},
{
"content": "content",
"filename": "Filename_åäö"
}
]
}
````
The JSON serialized string which gets passed to `RequestAsync` is used to create a seemingly proper [`StringContent`](https://github.com/sendgrid/sendgrid-csharp/blob/2bc388565671dd14234b934e0424689b4ac92d18/src/SendGrid/SendGridClient.cs#L359).
```cs
var content = new StringContent(serialized, Encoding.UTF8, null);
var contentString = content.ReadAsStringAsync().Result;
Which is still intact:
{"attachments":[{"content":"content","filename":"Filename_foo"},{"content":"content","filename":"Filename_åäö"}]}
This is used to construct a HttpRequestMessage.
var request = new HttpRequestMessage
{
Method = new HttpMethod("POST"),
Content = content
};
var requestContent = request.Content.ReadAsStringAsync().Result;
It is still intact:
{"attachments":[{"content":"content","filename":"Filename_foo"},{"content":"content","filename":"Filename_åäö"}]}
Then when I send it using HttpClient it is still intact.
using System;
using System.Net.Http;
using System.Text;
using SendGrid.Helpers.Mail;
namespace SendGridClient
{
public class Program
{
public static void Main(string[] args)
{
var message = new SendGridMessage();
message.AddAttachment("Filename_foo", "content");
message.AddAttachment("Filename_åäö", "content");
var serialized = message.Serialize();
var content = new StringContent(serialized, Encoding.UTF8, null);
var contentResult = content.ReadAsStringAsync().Result;
var request = new HttpRequestMessage
{
Method = new HttpMethod("POST"),
Content = content
};
var requestContent = request.Content.ReadAsStringAsync().Result;
using (var client = new HttpClient())
{
// You can check at http://requestb.in/xayqitxa?inspect
client.BaseAddress = new Uri("http://requestb.in/xayqitxa");
client.DefaultRequestHeaders.Accept.Clear();
var foo = client.SendAsync(request).Result;
}
Console.WriteLine(requestContent);
Console.ReadLine();
}
}
}
So I am no closer than before, but perhaps this can hint someone. I might look more tomorrow if I got time.
@vanillajonathan,
I just tested with success with the following code using the latest v9 C# SDK:
using SendGrid;
using SendGrid.Helpers.Mail;
using System;
using System.Threading.Tasks;
namespace Example
{
internal class Example
{
private static void Main()
{
Execute().Wait();
}
static async Task Execute()
{
var apiKey = Environment.GetEnvironmentVariable("SENDGRID_API_KEY");
var client = new SendGridClient(apiKey);
var msg = new SendGridMessage()
{
From = new EmailAddress("[email protected]", "DX Team"),
Subject = "Hello World from the SendGrid CSharp SDK!",
PlainTextContent = "Hello, Email!",
HtmlContent = "<strong>Hello, Email!</strong>"
};
msg.AddTo(new EmailAddress("[email protected]", "Test User"));
byte[] excelArray = System.IO.File.ReadAllBytes(@"/Users/ethomas/Downloads/Book 2.xlsx");
string base64ExcelRepresentation = Convert.ToBase64String(excelArray);
msg.AddAttachment("Sheet_åäö.xlsx", base64ExcelRepresentation, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
Console.WriteLine(msg.Serialize());
var response = await client.SendEmailAsync(msg);
Console.WriteLine(response.Body.ReadAsStringAsync().Result);
Console.ReadLine();
}
}
}
Anyone affected by the bug should try to upgrade to the latest version of the library.
As a workaround you can strip out the diacritics (accents) from the filename.
http://www.levibotelho.com/development/c-remove-diacritics-accents-from-a-string
@thinkingserious,
I ran your code using v9 C# SDK and the library seems to behave as intended.
I specified a host parameter to the constructor in SendGridClient to make it POST the request to RequestBin and the data arrives with the proper filenames. As far as I can tell the library works as intended and the bug does not apply to v9.
Perhaps time to close the bug as fixed?
Thanks for the confirmation @vanillajonathan
I will close this ticket.
If anyone else continues to experience issues, please open a new ticket.
Thanks!
@thinkingserious
it works for me.
Thank you so much!
Thanks for verifying @jeetbhalani!
Hello @thinkingserious sending the file name with accents still not working. Please do necessary changes to handle it. I spent lot of time and found a solution to send accents with UTF-8 base64 encode as
"=?UTF-8?B?" . base64_encode( $file_name ) . "?="
Which solved my problem.
Most helpful comment
I might have another version of this issue. When sending an attachment with a filename "Reservation Report 1. 9. 2016 0:00:00 - 3. 9. 2016 0:00:00.xlsx", an e-mail with the filename "00.xlsx" is delivered.
It's a bit strange that it's the part of the filename that comes after the last header name:value separator (colon)... Is it the lib, the API, or is it me? Thanks!