Blazor Wasm发送邮件引发异常System.PlatformNotSupportedException:该平台不支持System.Net.Dns:GetHostByName

时间:2020-10-12 22:24:21

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

我正在尝试从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端口)<0x44e7108 + 0x000aa>在:0中 在System.Net.Mail.SmtpClient.SendInternal(System.Net.Mail.MailMessage消息)<0x44e6a78 + 0x00016>在:0中 在System.Net.Mail.SmtpClient.Send(System.Net.Mail.MailMessage消息)<0x44e19c0 + 0x000c4>在:0中 ---内部异常堆栈跟踪的结尾--- 在System.Net.Mail.SmtpClient.Send(System.Net.Mail.MailMessage消息)<0x44e19c0 + 0x000ee>在: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()<0x3f6d608 + 0x0013a> 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#代码在控制台应用程序上工作

2 个答案:

答案 0 :(得分:0)

尽管 Blazor (wasm) 可以直接在浏览器上运行 C# 代码,但它受到浏览器功能的限制,浏览器无法发送电子邮件。在这种情况下,通常会发生 PlatformNotSupportedException 抛出,否则您将在 Visual Studio CA1416:验证平台兼容性上收到警告。在这种情况下,另一种方法是调用发送电子邮件的服务器 API。

答案 1 :(得分:0)

@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 文件(也在 wwwroot 文件夹中)中包含对 .js 文件的引用:

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

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

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