Возникли проблемы с чтением части сообщения text/html

Я пытаюсь вытащить тему и тело письма с помощью .Net. Кажется, все в порядке, за исключением text/html MessagePart. Я не уверен в кодировке и т. д. У кого-нибудь это работает нормально? Это ошибка для меня при попытке конвертировать.

Вот необработанная строка для данных тела text/html.

"PGRPdiBkaXI9Imx0ciI-dGV4dCBpbiBoZXJlPGJyPjwvZGl2Pg0K"

который выдает ошибку.

«Введенная строка не является допустимой строкой Base-64, поскольку она содержит символ, отличный от Base 64, более двух символов заполнения или недопустимый символ среди символов заполнения».

Вот код:

    UsersResource.MessagesResource.GetRequest gr = gs.Users.Messages.Get(userEmail, TextBox1.Text);
    gr.Format = UsersResource.MessagesResource.GetRequest.FormatEnum.Full;                
    Message m = gr.Execute();

            foreach (MessagePart p in m.Payload.Parts)
            {
                if (p.MimeType == "text/html")
                {
                    try
                    {
                        byte[] data = Convert.FromBase64String(p.Body.Data);
                        string decodedString = Encoding.UTF8.GetString(data);
                        Response.Write(decodedString);
                    }
                    catch (Exception ex) { }
                }
            }

Я ошибаюсь в расшифровке???

Спасибо за вашу помощь.


person PNC    schedule 28.06.2014    source источник
comment
Та же проблема со мной - просто чтобы вы знали, что вы не одиноки!   -  person Devfly    schedule 29.06.2014
comment
Приятно слышать - я пробовал несколько подходов с тем же результатом. Возникла та же проблема со всем необработанным сообщением при попытке проанализировать мой парсер MIME.   -  person PNC    schedule 29.06.2014


Ответы (4)


Данные тела выглядят в кодировке base64url, а не в кодировке base64. Отличие заключается в использовании - и _ вместо + и / в алфавите кодировки из 64 символов. Одним из решений является замена всех символов - и _ на + и / соответственно перед вызовом FromBase64String.

См. http://tools.ietf.org/html/rfc4648#section-5

person user3788724    schedule 30.06.2014
comment
Вы также захотите сделать что-то вроде этого (из другого вопроса): encoded = b64.replace(/_/g, '/').replace(/-/g,'+'); atob( unescape( encodeURIComponent( encoded ) ) ); - person maxko87; 18.10.2016

Вот код, который я в итоге использовал:

                foreach (MessagePart p in m.Payload.Parts)
                {
                    if (p.MimeType == "text/html")
                    {
                         byte[] data = FromBase64ForUrlString(p.Body.Data);
                         string decodedString = Encoding.UTF8.GetString(data);
                         Response.Write(decodedString);                            
                    }
                }

....

    public static byte[] FromBase64ForUrlString(string base64ForUrlInput)
    {
        int padChars = (base64ForUrlInput.Length % 4) == 0 ? 0 : (4 - (base64ForUrlInput.Length % 4));
        StringBuilder result = new StringBuilder(base64ForUrlInput, base64ForUrlInput.Length + padChars);
        result.Append(String.Empty.PadRight(padChars, '='));
        result.Replace('-', '+');
        result.Replace('_', '/');
        return Convert.FromBase64String(result.ToString());
    }

Хорошая статья http://www.codeproject.com/Tips/76650/Base-base-url-base-url-and-z-base-encoding

person PNC    schedule 30.06.2014

На этой странице https://developers.google.com/gmail/api/v1/reference/users/messages/attachments/get

вы можете обнаружить, что есть пример .NET с этим кодом для декодирования:

// Converting from RFC 4648 base64-encoding
// see http://en.wikipedia.org/wiki/Base64#Implementations_and_history
String attachData = attachPart.Data.Replace('-', '+');
attachData = attachData.Replace('_', '/');
byte[] data = Convert.FromBase64String(attachData);
person lost in binary    schedule 06.03.2015

Метод WebEncoders.Base64UrlDecode в сборка Microsoft.AspNetCore.WebUtilities может декодировать этот в настоящее время:

var bytes = WebEncoders.Base64UrlDecode(data);
person Mike    schedule 11.01.2021