Я пытаюсь написать небольшое консольное приложение, используя C#
поверх платформы .NET Core 2.2.
Консольное приложение выполнит HTTP-запрос к внешнему API для получения нескольких изображений.Я могу сделать запрос на сервер и получить ответ.Однако сервер отвечает многокомпонентным ответом, используя сообщения MIMI.
Я могу проанализировать запрос и получить тело MIME для каждого сообщения.Но я не могу понять, как создать файл из содержимого тела.
Вот пример того, как необработанное сообщение MIMI начинается с
Я попытался записать тело в виде строки в файл, но это не сработало
string body = GetMimeBody(message);
File.WriteAllText("image_from_string" + MimeTypeMap.GetExtension(contentType), bytes);
Я также попытался преобразовать строку в byte[]
, как это было, но все равно не сработало
byte[] bytes = Encoding.ASCII.GetBytes(body);
File.WriteAllBytes("image_from_ascii_bytes" + MimeTypeMap.GetExtension(contentType), bytes);
byte[] bytes = Encoding.Default.GetBytes(body);
File.WriteAllBytes("image_from_default_bytes" + MimeTypeMap.GetExtension(contentType), bytes);
byte[] bytes = Encoding.UTF8.GetBytes(body);
File.WriteAllBytes("image_from_utf8_bytes" + MimeTypeMap.GetExtension(contentType), bytes);
Под "не работает" я имею в виду, что изображение не открывается правильно.Программа просмотра фотографий говорит, что «изображение кажется поврежденным или поврежденным».
Как правильно сделать хорошее изображение из сообщения?
ОБНОВЛЕНО
Вот код вместе с частями для разбора
var responseContentType = response.Content.Headers.GetValues("Content-Type").FirstOrDefault();
string splitter = string.Format("--{0}", GetBoundary(responseContentType));
string content = await response.Content.ReadAsStringAsync();
var messages = content.Split(splitter, StringSplitOptions.RemoveEmptyEntries);
foreach (var message in messages)
{
var mimiParts = message.Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries);
if (mimiParts.Length == 0)
{
continue;
}
string contentId = Str.GetValue("Content-ID", mimiParts, ':');
string objectId = Str.GetValue("Object-ID", mimiParts, ':');
string contentType = Str.GetValue("Content-Type", mimiParts, ':');
if (string.IsNullOrWhiteSpace(contentId) || string.IsNullOrWhiteSpace(objectId) || string.IsNullOrWhiteSpace(contentType))
{
continue;
}
string body = mimiParts[mimiParts.Length - 1];
var filename = string.Format("{0}_{1}{2}", contentId, objectId, MimeTypeMap.GetExtension(contentType));
var decoded = System.Net.WebUtility.HtmlDecode(data);
File.WriteAllText("image_from_html_decoded_bytes" + filename, decoded);
}
Вот метод, который анализирует сообщение
public class Str
{
public static string GetValue(string startWith, string[] lines, char splitter = '=')
{
foreach (var line in lines)
{
var value = line.Trim();
if (!value.StartsWith(startWith, StringComparison.CurrentCultureIgnoreCase) || !line.Contains(splitter))
{
continue;
}
return value.Split(splitter)[1].Trim();
}
return string.Empty;
}
}
Вот скриншот, показывающий содержимое mimiParts
переменная
ОБНОВЛЕНО 2
Исходя из приведенных ниже отзывов, я пытался использовать пакеты MimeKit вместопытаюсь разобрать ответ сам.Ниже показано, как я пытался потреблять ответ.Тем не менее, я все еще получаю ту же ошибку, что и выше.При записи файла изображения я получаю поврежденную ошибку изображения.
var responseContentType = response.Content.Headers.GetValues("Content-Type").FirstOrDefault();
if (!ContentType.TryParse(responseContentType, out ContentType documentContentType))
{
return;
}
var stream = await response.Content.ReadAsStreamAsync();
MimeEntity entity = MimeEntity.Load(documentContentType, stream);
Multipart messages = entity as Multipart;
if (messages == null)
{
throw new Exception("Unable to cast entity to Multipart");
}
foreach (MimeEntity message in messages)
{
string contentId = message.Headers["Content-ID"];
string objectId = message.Headers["Object-ID"];
string contentType = message.Headers["Content-Type"];
if (string.IsNullOrWhiteSpace(contentId) || string.IsNullOrWhiteSpace(objectId) || string.IsNullOrWhiteSpace(contentType))
{
continue;
}
var filename = string.Format("{0}_{1}{2}", contentId, objectId, MimeTypeMap.GetExtension(contentType));
message.WriteTo(filename);
}