Blazor Wasm, отправляющий почту, вызывает исключение System.PlatformNotSupportedException: System.Net.Dns:GetHostByName не поддерживается на этой платформе

#c# #asp.net #email #blazor #blazor-client-side

#c# #asp.net #Адрес электронной почты #blazor #blazor-на стороне клиента

Вопрос:

Я пытаюсь отправить электронное письмо из приложения Blazor WASM, но я получаю это исключение

Майкрософт.AspNetCore.Компоненты.Веб-сборка.Рендеринг.WebAssemblyRenderer[100] Компонент рендеринга необработанного исключения: сообщение не удалось отправить. System.Net.Mail.SmtpException: не удалось отправить сообщение. —> System.Исключение PlatformNotSupportedException: System.Net.Dns:GetHostByName не поддерживается на этой платформе. в System.Net.Sockets.TcpClient..ctor (System.Строковое имя хоста, порт System.Int32) <0x44e7108 0x000aa> в :0 в System.Net.Mail.SmtpClient.Отправка внутреннего (System.Net.Mail.MailMessage сообщение) <0x44e6a78 0x00016> в :0 в System.Net.Mail.SmtpClient.Отправить (сообщение System.Net.Mail.MailMessage) <0x44e19c0 0x000c4> в : 0 — Конец внутренней трассировки стека исключений — в System.Net.Mail.SmtpClient.Отправить (сообщение System.Net.Mail.MailMessage) <0x44e19c0 0x000ee> в :0 в MusicSellingApp.Client.Страницы.Профиль исполнителя.SendMail () [0x000a3] в C:UsersismailghedamsiSourceReposMusicSellingPlatformVeilleMusicSellingAppClientPagesArtistProfile.razor:33 в MusicSellingApp.Client.Страницы.Профиль исполнителя.OnInitializedAsync () [0x0000f] в C:UsersismailghedamsiSourceReposMusicSellingPlatformVeilleMusicSellingAppClientPagesArtistProfile.razor:38 в Microsoft.AspNetCore.Компоненты.База компонентов.RunInitAndSetParametersAsync () <0x3f6d608 0x0013a> в :0

Это мой файл razor

 @page "/artistProfile"
@inject ILocalStorageService storageService
@using System.Net.Mail
<h2>@(artist == null)</h2>
<UserInfoComponent User="@artist" />

@code{
    Artist artist;

    public void SendMail()
    {
        try
        {
            using (MailMessage mail = new MailMessage())
            {
                mail.From = new MailAddress("mymail@gmail.com");
                mail.To.Add("mymail@gmail.com");
                mail.Subject = "Sending mail";
                mail.Body = "<h2>this is a mail body</h2>";
                mail.IsBodyHtml = true;
                using (SmtpClient smtp = new SmtpClient("smtp.gmail.com", 587))
                {
                    smtp.Credentials = new System.Net.NetworkCredential("mymail@gmail.com", "mypassword");
                    smtp.EnableSsl = true;
                    smtp.Send(mail);
                }
            }
        }
        catch (Exception)
        {
            throw;
        }
    }
    protected override async Task OnInitializedAsync()
    {
        SendMail();
        artist = await storageService.GetItemAsync<Artist>("loggedUser");
    }

}
  

Тот же код c # работает над консольным приложением

Комментарии:

1. как веб-страница браузера будет отправлять электронное письмо? это какой-то новый HTML5 API ?! Если это так, то эти ребята из W3C не бездельничают!

2. Blazor позволяет выполнять код c # непосредственно в браузере

3. Это правда, попробуйте выполнить этот код C # в браузере Process.Start("Notepad") , запустит ли он новый процесс блокнота?

4. ваше сообщение об ошибке довольно чистое

Ответ №1:

Несмотря на то, что Blazor (wasm) может запускать код C # непосредственно в браузере, он ограничен возможностями браузера, отправка электронной почты — это не то, что может сделать браузер. В этом случае обычно происходит исключение PlatformNotSupportedException, или вы получите предупреждение в visual Studio CA1416: проверка совместимости платформы. Альтернативой в этом случае будет вызов API сервера, который отправляет электронное письмо.

Ответ №2:

Ответ @Guilherme в основном верен в том, что Blazor (WASM) не может использовать такие классы, как SmtpClient, которые не поддерживаются на платформе браузера. Однако это еще не вся история. Существует обходной путь, который можно использовать для самых простых нужд электронной почты, который использует старомодную технику использования привязочных ссылок «mailto:» в сочетании с введением IJSRuntime.

Позвольте мне предоставить несколько примеров кода на случай, если это поможет следующему разработчику, который столкнется с этим сообщением. Просто имейте в виду, что этот метод использует строку запроса, а функция MAILTO имеет ограничение примерно в 2000 символов. Превышение этого ограничения может помешать открытию сообщения в почтовом приложении пользователя по умолчанию.

С помощью нажатия кнопки или другого триггера вызовите функцию в вашей модели представления (или коде c #):

 protected void SendLocalEmail(string toEmailAddress, string subject, string body)
{
    JsRuntime.InvokeAsync<object>("blazorExtensions.SendLocalEmail",
      new object[] { toEmailAddress, subject, body });
}
  

Затем в вашей папке wwwroot у вас должен быть соответствующий файл .js (т. е. GlobalFunctions.js ), который содержит соответствующую функцию JavaScript SendLocalEmail(), такую как:

 window.blazorExtensions = {
  SendLocalEmail: function (mailto, subject, body) {
    var link = document.createElement('a');
    var uri = "mailto:"   mailto   "?";
    if (!isEmpty(subject)) {
        uri = uri   "subject="   subject;
    }

    if (!isEmpty(body)) {
        if (!isEmpty(subject)) { // We already appended one querystring parameter, add the 'amp;' separator
            uri = uri   "amp;"
        }

        uri = uri   "body="   body;
    }

    uri = encodeURI(uri);
    uri = uri.substring(0, 2000); // Avoid exceeding querystring limits.
    console.log('Clicking SendLocalEmail link:', uri);

    link.href = uri;
    document.body.appendChild(link); // Needed for Firefox
    link.click();
    document.body.removeChild(link);
  }
};

function isEmpty(str) {
  return (!str || str.length === 0);
}
  

Наконец, убедитесь, что вы включили ссылку на ваш файл .js в index.html файл (также в папке wwwroot):

 <script src="GlobalFunctions.js"></script>
  

Я размещаю приведенную выше ссылку на скрипт под этой строкой:

 <script>navigator.serviceWorker.register('service-worker.js');</script>
  

Комментарии:

1. да, это не работает. Если я первым делом помещаю предупреждение в функцию javascript, оно не появляется, поэтому я знаю, что оно не вызывается