Сохранение электронной почты в каталоге с указанным именем файла не работает в .NET 5.0

Я пытаюсь следовать подходу, предложенному в посте Аллана Игла в кодовом проекте. Этот же подход работал нормально до .NET Core 3.1, но не с .NET 5.0. Вот метод сохранения, который я создал,

 private void Save(MailMessage message, string filePath)
    {
        var assembly = typeof(SmtpClient).Assembly;
        var mailWriterType = assembly.GetType("System.Net.Mail.MailWriter");
        const BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic;
        using (var fileStream = new FileStream(filePath, FileMode.Create))
        {
            var mailWriterContructor = mailWriterType.GetConstructors(bindingFlags)[0];
            var mailWriter = mailWriterContructor.Invoke(new object[] { fileStream });//<-- This line throws error saying parameter mismatch
            var sendMethod = typeof(MailMessage).GetMethod("Send", bindingFlags);
            sendMethod.Invoke(message, bindingFlags, null, new[] { mailWriter, true, true }, null);
            var closeMethod = mailWriter.GetType().GetMethod("Close", bindingFlags);
            closeMethod.Invoke(mailWriter, bindingFlags, null, new object[] { }, null);
        }
    }

Я проверил все доступные базовые методы вызова и попытался работать с ними, передавая необходимые параметры, но ни один из них не работал у меня.

Сообщение об ошибке: «Несоответствие количества параметров». Внутреннее исключение: ноль
Трассировки стека:

 at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.ConstructorInfo.Invoke(Object[] parameters)
   at..//user written line info  

Любая помощь в решении этой проблемы или новый подход к достижению того же результата с помощью System.Net.Mail будут высоко оценены.

Конструктор MailWriter теперь принимает 2 параметра. Не используйте отражение для доступа к внутренним типам, подобным этому: они могут сломаться даже между второстепенными выпусками.

canton7 21.12.2020 17:36

Спасибо @canton7 за ваш ответ и ценное предложение.

BDB 21.12.2020 19:13

Эта статья очень старая и просто непригодная для использования в 2020 году. Несмотря на дату, она была написана в 2009 году и фактически перестала работать в 2014 году, когда один из внутренних методов сменил подпись. Microsoft довольно сильно предупреждает, что SmptClient устарел в документации по классу, и рекомендует вместо него использовать MailKit Важно! Мы не рекомендуем использовать класс SmtpClient для новой разработки, поскольку SmtpClient не поддерживает многие современные протоколы. Вместо этого используйте MailKit или другие библиотеки.

Panagiotis Kanavos 21.12.2020 20:56

Итак, что вы пытаетесь сделать? Забудьте об устаревшем SmtpClient и System.Net.Mail. Что бы вы ни хотели сделать, есть лучшие способы. Именно потому, что System.Net.Mail устарел, MailMessage и MailWriter не могут обрабатывать подписанные, безопасные, расширенные или составные сообщения.

Panagiotis Kanavos 21.12.2020 21:03

Спасибо @PanagiotisKanavos за хорошо объясненный ответ. Теперь стоит обсудить это с моей командой и перейти на новую более мощную библиотеку, такую ​​​​как MailKit, как вы предложили в ответе.

BDB 22.12.2020 00:05

Несмотря на то, что я знал о том, что Microsoft предупредила его об устаревании, и были некоторые изменения во внутренних методах, я все же разместил это в стеке, потому что «System.Net.Mail» используется во многих проектах, а также позволяет избежать необходимости использования одна дополнительная внешняя библиотека. И я считаю, что получать идеи от эксперта в стеке — это всегда хорошо. Итак, стоит ли этот вопрос получить отрицательный голос? В любом случае, голоса за и против одинаково. Просто интересно, не пропустил ли я что-нибудь по вопросу.

BDB 22.12.2020 00:36
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
6
429
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Как я упоминал в комментариях, эта статья устарела в 2020 году. Несмотря на дату, на самом деле она была написана в 2009 году и перестала работать в 2014 году, когда у некоторых внутренних методов сменилась подпись. В любом случае пространство имен System.Net.Mail не следует использовать, потому что, как настоятельно предупреждает Microsoft:

Важный

Мы не рекомендуем использовать класс SmtpClient для новой разработки, поскольку SmtpClient не поддерживает многие современные протоколы. Вместо этого используйте MailKit или другие библиотеки. Дополнительные сведения см. в разделе SmtpClient не следует использовать на GitHub.

MailKit (или, скорее, библиотека MimeKit, на которой он построен) уже поддерживает сохранение и загрузку почтовых сообщений. От В: Как сохранить сообщения? ответ прост:

message.WriteTo("message.eml");

Вы можете использовать клиенты MailKit POP3 или IMAP4 для получения сообщений. В примере DownloadMessages показано, как загружать сообщения из GMail и сохранять их:

        using (var client = new Pop3Client (new ProtocolLogger ("pop3.log"))) {
            client.Connect ("pop.gmail.com", 995, SecureSocketOptions.SslOnConnect);

            client.Authenticate ("username", "password");

            for (int i = 0; i < client.Count; i++) {
                var message = client.GetMessage (i);

                // write the message to a file
                message.WriteTo (string.Format ("{0}.msg", i));

                // mark the message for deletion
                client.DeleteMessage (i);
            }

            client.Disconnect (true);
        }

Чтобы явно дать вам ответ на основе первого комментария,

var encodeForTransport = false;
var mailWriter = mailWriterContructor.Invoke(new object[] { fileStream, encodeForTransport  });

Другие вопросы по теме