0
public ExchangeService CreateConnection(string url)
    {
        ServicePointManager.ServerCertificateValidationCallback = (object obj, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors) => true;
        ExchangeService service = new ExchangeService();
        service.Url = new Uri(url);
        service.UseDefaultCredentials = true;        // Uses users windows login credentials
        return service;
    }
public void SendEmail(string sEmailTo, string slocation, DateTime dtdate, string slogyard, string sScaling, string sLogMfct, string sOther, string sScaler, int icheckbox)
    {
        string scheckbox;
        string sDomain = Globals.gDefaultEmailSuffix;
        string sUserName = SystemInformation.UserName;
        ExchangeService service = CreateConnection("https://myexchangeserver.com/EWS/Exchange.asmx");
        string sHTMLpre = $"{EmailBody(Globals.gHTML)}";
        EmailMessage mailMessage = new EmailMessage(service);                 // Use with exchange service
                                                                     
        ReplaceWithBR(slogyard);
        ReplaceWithBR(sScaling);
        ReplaceWithBR(sLogMfct);
        ReplaceWithBR(sOther);

        if (icheckbox > 0)
            scheckbox = "Yes";
        else
            scheckbox = "No";

        sHTMLpre = sHTMLpre.Replace("[@Location]", slocation);
        sHTMLpre = sHTMLpre.Replace("[@Date]", dtdate.ToString());
        sHTMLpre = sHTMLpre.Replace("[@LogYard]", slogyard);
        sHTMLpre = sHTMLpre.Replace("[@Scaling]", sScaling);
        sHTMLpre = sHTMLpre.Replace("[@LogManufacturing]", sLogMfct);
        sHTMLpre = sHTMLpre.Replace("[@Scaler]", sScaler);
        sHTMLpre = sHTMLpre.Replace("[@Other]", sOther);
        sHTMLpre = sHTMLpre.Replace("[@RemotesExist]", scheckbox);

        mailMessage.ToRecipients.Add(new EmailAddress($"{sEmailTo}@{sDomain}"));     // Use with Exchange service
        mailMessage.From = new EmailAddress($"{sUserName}@{sDomain}");               // Use with Exchange service
        mailMessage.Subject = $"Scaling Yard Report for {slocation} on {dtdate}";    // Use with Exchange
        mailMessage.Body = sHTMLpre;                                                 // Use with Exchange
                    

        try
        {  
            mailMessage.SendAndSaveCopy());                    //Use with Exchange Service
            if (Globals.bLastEmail == true)
            {
                MessageBox.Show("Email Sent Successfully!");
                Globals.MonthlyLog("Email Sent", $"Recipients:{Globals.gEmailList}");
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
            Globals.MonthlyLog("Email Fail", $"{ex.Message}");

            return;
        }
    }

And Here is the VB.Net code that works just fine:

Public Function CreateConnection(ByVal url As String) As ExchangeService
    ServicePointManager.ServerCertificateValidationCallback = Function(ByVal obj As Object, ByVal certificate As X509Certificate, ByVal chain As X509Chain, ByVal errors As SslPolicyErrors) True
    Dim service As New ExchangeService()
    service.Url = New Uri(url)
    service.UseDefaultCredentials = True        ' Uses users windows login credentials
    Return service
End Function
Public Sub SendEmail(sEmailTo As String, slocation As String, dtdate As String, slogyard As String, sScaling As String, sLogMfct As String, sOther As String, sScaler As String, scheckbox As String)
    Dim sDomain As String = gDefaultEmailSuffix
    Dim sUserName As String = SystemInformation.UserName
    Dim service As ExchangeService = CreateConnection("https://myexchangeserver.com/EWS/Exchange.asmx")
    Dim sHTMLpre As String = $"{EmailBody(gHTML)}"
    Dim mailMessage = New EmailMessage(service)                 ' Use with exchange service
    'Dim mailMessage As New MailMessage()                       ' Use with SMTP client service

    slogyard = slogyard.Replace(ControlChars.Lf, "<br>")
    sScaling = sScaling.Replace(ControlChars.Lf, "<br>")
    sLogMfct = sLogMfct.Replace(ControlChars.Lf, "<br>")
    sOther = sOther.Replace(ControlChars.Lf, "<br>")

    If scheckbox = True Then
        scheckbox = "Yes"
    Else
        scheckbox = "No"
    End If

    sHTMLpre = sHTMLpre.Replace("[@Location]", slocation)
    sHTMLpre = sHTMLpre.Replace("[@Date]", dtdate)
    sHTMLpre = sHTMLpre.Replace("[@LogYard]", slogyard)
    sHTMLpre = sHTMLpre.Replace("[@Scaling]", sScaling)
    sHTMLpre = sHTMLpre.Replace("[@LogManufacturing]", sLogMfct)
    sHTMLpre = sHTMLpre.Replace("[@Scaler]", sScaler)
    sHTMLpre = sHTMLpre.Replace("[@Other]", sOther)
    sHTMLpre = sHTMLpre.Replace("[@RemotesExist]", scheckbox)

    mailMessage.ToRecipients.Add(New EmailAddress($"{sEmailTo}@{sDomain}"))     ' Use with Exchange service
    mailMessage.From = New EmailAddress($"{sUserName}@{sDomain}")               ' Use with Exchange service
    mailMessage.Subject = $"Scaling Yard Report for {slocation} on {dtdate}"    ' Use with Exchange
    mailMessage.Body = sHTMLpre                                                 ' Use with Exchange

    'mailMessage.IsBodyHtml = True                                              ' Use with SMTP CLient
    'mailMessage.To.Add($"{sEmailTo}@{sDomain}")                                ' Use with SMTP CLient
    'mailMessage.From = New MailAddress($"{sUserName}@{sDomain}")               ' Use with SMTP  
    'mailMessage.Subject = $"Scaling Yard Report for {slocation} on {dtdate}"   ' Use with SMTP
    'mailMessage.Body = sHTMLpre                                                ' Use with SMTP


    'Dim SmtpCli As New SmtpClient()                                            ' Leaving this just in case the EWS breaks
    'With SmtpCli                                                               ' SMTP Client Code
    '    .UseDefaultCredentials = False
    '    .Port = 25
    '    .DeliveryMethod = SmtpDeliveryMethod.Network
    '    .Host = gSMTPServer
    '    .Credentials = New NetworkCredential(gSMTPUsername, gSMTPPassword)
    'End With

    Try
        'SmtpCli.Send(mailMessage)                                              ' Use with SMPT client
        mailMessage.SendAndSaveCopy()                                           ' Use with Exchange Service
        If bLastEmail = True Then
            MsgBox("Email Sent Successfully!")
            Call MonthlyLog("Email Sent", $"Recipients:{gEmailList}")
        End If
    Catch ex As Exception
        MessageBox.Show(ex.Message)
        Call MonthlyLog("Email Fail", $"{ex.Message}")

        Exit Sub
    End Try

End Sub

It fails at the line: mailMessage.SendAndSaveCopy() -in C# but not VB.Net

Getting the error: "the request failed. the underlying connection was closed: an unexpected error occurred on a send"

As I said, it works fine with vb.net code, so it is not an exchange server setting like throttling. Any ideas?

CircleDot
  • 15
  • 7
  • I suggest you try to do code conversion from VB to C# and compare the result with what you have.... – NoChance Oct 26 '21 at 21:01
  • Are you certain that your VB version works as you've provided it here? I see that there's some commented-out code using `SmtpClient`. Is it possible that is the VB code that works. If not that, is there any difference between the environment where you're running the VB vs. the C# version of the code? I see that it's using Windows authentication. Different machines with different credentials maybe? – Jack A. Oct 26 '21 at 21:21
  • @JackA. 100% works. The smtpclient stuff is old code I left in case the EWS fails (since I recently switched to EWS), I can switch it back. I have both programs open and running at the same time on the same PC with the smtpclient commented out and it works fine in vb project and errors out in C# project. The vb code with the EWS code in there has been working fine fore the last 4 months. We decided to translate some projects to C# and this is my first go at it. – CircleDot Oct 26 '21 at 21:31
  • @NoChance I already did that and that is how I got here. This is my first project conversion from vb.net to C#. – CircleDot Oct 26 '21 at 21:33
  • Try a different converter. If this fails, debug the version that is not working, maybe an error is raised but you are not catching it. – NoChance Oct 26 '21 at 21:35
  • The C# code looks fine as far as I can tell. A quick search for your error message indicates that you may need to set `ServicePointManager.SecurityProtocol`. For example: https://stackoverflow.com/questions/22627977/the-underlying-connection-was-closed-an-unexpected-error-occurred-on-a-send. If you want to include the full details of the exception in your question, that could be helpful. – Jack A. Oct 26 '21 at 21:42
  • @JackA. It was the .Net framework version. Project needed to target 4.6 and I was at 4.5 – CircleDot Oct 26 '21 at 21:46
  • Ah, good to hear you solved it. If you feel like it maybe try switching back to 4.5 and change your code to include `ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;`. I believe the default value changed between framework versions, and I suspect that was the underlying problem. – Jack A. Oct 26 '21 at 21:53
  • @JackA. I will test it out and let you know. Thanks for the help! – CircleDot Oct 26 '21 at 22:03
  • @JackA. Getting all types of errors when switching back to 4.5 with DevExpress and some other designer issues. Since it works good now, I won't be able to see if your code works. I will try it in the vb project and see maybe. – CircleDot Oct 26 '21 at 22:46
  • 1
    @JackA. It worked in the VB.net code with 4.5. My VB project did not use any DevExpress tools or forms like I did with the my c# conversion. Thanks for the help. – CircleDot Oct 26 '21 at 22:50

2 Answers2

0

Needed to update the target .Net Framework to at least 4.6 or higher. I was working with 4.5. Should have known because I have run into issues with the vb.net program not being able to send the emails on older non updated 32bit Windows 10 PC's that don't have 4.6.

CircleDot
  • 15
  • 7
0

I was using .net 4.5.2 and received the same error. Lower versions of .Net did not force it to use TLS version > 1.1 Either use higher version of .Net framework. Or you can force it to use TLS 1.2

' this resolves the unexpected error the underlying connection was closed by forcing it to use TLS 1.2

System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12
AlexL
  • 1
  • 1