【问题标题】:Blazor Wasm sending mail throw exception System.PlatformNotSupportedException: System.Net.Dns:GetHostByName is not supported on this platformBlazor Wasm 发送邮件抛出异常 System.PlatformNotSupportedException: System.Net.Dns:GetHostByName 在此平台上不受支持
【发布时间】:2021-01-27 06:04:22
【问题描述】:

我正在尝试从 Blazor WASM 应用发送电子邮件,但收到此异常

Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100] 未处理的异常呈现组件:无法发送消息。 System.Net.Mail.SmtpException:无法发送消息。 ---> System.PlatformNotSupportedException:此平台不支持 System.Net.Dns:GetHostByName。 在 System.Net.Sockets.TcpClient..ctor (System.String 主机名,System.Int32 端口) 在:0 在 System.Net.Mail.SmtpClient.SendInternal (System.Net.Mail.MailMessage 消息) in :0 在 System.Net.Mail.SmtpClient.Send (System.Net.Mail.MailMessage 消息) in :0 --- 内部异常堆栈跟踪结束 --- 在 System.Net.Mail.SmtpClient.Send (System.Net.Mail.MailMessage 消息) in :0 在 C:\Users\ismailghedamsi\Source\Repos\MusicSellingPlatformVeille\MusicSellingApp\Client\Pages\ArtistProfile.razor:33 中的 MusicSellingApp.Client.Pages.ArtistProfile.SendMail () [0x000a3] 在 C:\Users\ismailghedamsi\Source\Repos\MusicSellingPlatformVeille\MusicSellingApp\Client\Pages\ArtistProfile.razor:38 中的 MusicSellingApp.Client.Pages.ArtistProfile.OnInitializedAsync () [0x0000f] 在 Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync () in :0

这是我的剃须刀文件

@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# 代码正在控制台应用程序上运行

【问题讨论】:

  • 浏览器网页如何发送电子邮件?这是某种新的 HTML5 API 吗?!如果是这样,那么那些 W3C 的人就不会懈怠了!
  • Blazor 允许直接在浏览器上执行 c# 代码
  • 不错,尝试在浏览器上执行这段C#代码Process.Start("Notepad")会启动一个新的记事本进程吗?
  • 你的错误信息很干净

标签: c# asp.net email blazor blazor-client-side


【解决方案1】:

尽管 Blazor (wasm) 可以直接在浏览器上运行 C# 代码,但它受到浏览器功能的限制,发送电子邮件不是浏览器可以做的事情。在这种情况下,通常会抛出 PlatformNotSupportedException,否则您会在 Visual Studio CA1416: Validate platform compatibility 上收到警告。在这种情况下,替代方法是调用发送电子邮件的服务器 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 '&' separator
                uri = uri + "&"
            }
    
            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);
    }
    

    最后,确保在 index.html 文件中包含对 .js 文件的引用(也在 wwwroot 文件夹中):

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

    我将上面的脚本引用放在这一行下面:

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

    【讨论】:

    • 你这行不通。如果我在 javascript 函数中首先发出警报,它不会出现,所以我知道它没有被调用
    猜你喜欢
    • 1970-01-01
    • 2019-12-29
    • 1970-01-01
    • 2022-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-17
    • 2019-10-30
    相关资源
    最近更新 更多