E-mail with no content when using the System.Threading.ThreadPool - asp.net

I'm experiencing a strange behavior trying to send email using Threading.ThreadPool.
This has worked for over a year now but recently it has stated to intermittently send emails with no content. The addressees and subject are all fine, however, the rest of the email is blank. Nothing has changed code wise (apart from Windows updates to the server it runs on).
Here's the code I'm using - does anyone have a suggestion of how I might narrow down where the problem is occurring? Upon re-sending the email to someone who has claimed of receiving a blank email they get it fine - it uses the exact same code as the first one that was sent.
Sub to generate email:
Public Sub EmailConfirmation(email As String,
firstname As String,
details As String)
Try
Dim embody As String = GlobalHelper.emailBody
'static class which loads the email text at application load for use later.
'This is a point of concern because it's obviously where the embody text is
'is loaded, but the issue is intermittent and if there was a failure here surely
'it would be caught by the 'try...catch' and a log of the error created (which has
'never happened). I also ran an experiment for a while where if this string was
'empty then create a log entry. After receiving a complaint of a blank email
'no error log was found.
embody = Replace(embody, "[FirstName]", firstname)
embody = Replace(embody, "[DATA]", details)
'create the mail message
Dim mail As New MailMessage()
'set the addresses
mail.From = New MailAddress("myemail#mydomain.com", "My Display Name")
mail.To.Add(email)
mail.IsBodyHtml = True
'set the content
mail.Subject = "Email Subject!"
mail.Body = embody
AddEmailToThreadPool(mail)
Catch ex As Exception
'if there is an error it is logged here.
End Try
End Sub
Sub that adds to ThreadPool:
Private Sub AddEmailToThreadPool(email As MailMessage)
System.Threading.ThreadPool.QueueUserWorkItem(New System.Threading.WaitCallback(AddressOf sendEmail), email)
End Sub
Sub that sends email:
Private Sub sendEmail(stateinfo As Object)
Dim email As MailMessage = CType(stateinfo, MailMessage)
Try
'send the message
Dim smtp As New SmtpClient("mail.mydomain.com")
smtp.Send(email)
Catch ex As Exception
'error is logged here.
End Try
End Sub

I copied from MSDN MailMessage class
Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.

Well, after fixing the incorrect doc type declaration I've not had a single complaint of blank emails in almost a month. I'm going to assume this fixed the problem all though I'm not certain why.
Thanks for all of your input/help.

Related

execute code on load in vb.net aspx page

I appreciate help for this issue which stoled a lot of hours.
I have this code:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
Label1.Text = "924 695 302"
Label2.Text = "690 142 449"
Dim ipvisitante = Request.ServerVariables("remote_addr")
Dim hoje = DateTime.Now
Dim informacao = ipvisitante & " --- " & hoje
'Send e-mail
Dim strFrom = "fernandopessoa#fpessoa.net" ''IMPORTANT: This must be same as your smtp authentication address.
Dim strTo = "francopessoa.espana#hotmail.com"
Dim MailMsg As New MailMessage(New MailAddress(strFrom.Trim()), New MailAddress(strTo))
MailMsg.BodyEncoding = Encoding.Default
MailMsg.Subject = "This is a test"
MailMsg.Body = "This is a sample message using SMTP authentication"
MailMsg.Priority = MailPriority.High
MailMsg.IsBodyHtml = True
'Smtpclient to send the mail message
Dim SmtpMail As New SmtpClient
Dim basicAuthenticationInfo As New Net.NetworkCredential("fernandopessoa#fpessoa.net", "---------")
''IMPORANT: Your smtp login email MUST be same as your FROM address.
SmtpMail.Host = "mail.fpessoa.net"
SmtpMail.UseDefaultCredentials = False
SmtpMail.Credentials = basicAuthenticationInfo
MsgBox("O ficheiro existe", MsgBoxStyle.Information, "SIM")
'Write to txt File
FileOpen(1, "visitas.txt", OpenMode.Append)
WriteLine(1, informacao)
FileClose()
End Sub
Now, when the page Loads, the text apears in the Labels.
Surprisingly, it doesn't execute the rest of the code, Display Msgbox, Write to the .txt File and send the e-mail.
Can anyone give me a clue of what's going wrong with my code?
Thanks in advance.
The code does execute... it runs on the Web Server. It does not run in the client's web browser, and never will.
That explains the MsBox() and file, though the web server may also be getting hung up waiting for someone to click "Okay" on a MsgBox no one will ever see. For the e-mail, you never call SmtpMail.Send(MailMsg)
While I'm here, that file code is using an antique api.
It sounds like you need a quick primer on how this all works, so here is what happens step by step:
User clicks a link to your page or types your page address in their address bar.
The browser sends an HTTP request to your server.
Your server receives the request, creates a new instance of your page class in a worker thread.
Code runs in your page class for ALL phases of the ASP.Net Page Lifecycle .
The ASP.Net runtime uses your page class instance to render an HTTP response (usually in html) and send it to the browser.
Your page class instance is destroyed.
The browser receives the response, parses a new Document Object Model (DOM), and renders that DOM to the display.
The user sees and interacts with your page, causing a post-back.
Go to step 2, taking special note of the "new instance" phrase when you reach step 3.

Sending e-mail by System.Net.Mail.SmtpClient causes 'Mailbox unavailable, Spam Rejected'

In a web application using asp.net 4.0, I use the class System.Net.Mail.SmtpClient to send email.
This is my code:
Shared Function InviaMail(ByVal toAddress As String, ByVal TestoMsg As String, ByVal TestoSubject As String) As Boolean
Dim from As New MailAddress("xxx#xxx.pro", "xxx.pro")
Dim toDest As New MailAddress(toAddress, "")
Dim mm As New MailMessage(from, toDest)
Dim altView As AlternateView
altView = AlternateView.CreateAlternateViewFromString(TestoMsg, Nothing, MediaTypeNames.Text.Html)
mm.AlternateViews.Add(altView)
mm.Subject = TestoSubject
mm.Body = TestoMsg
mm.IsBodyHtml = True
Dim smtp As New SmtpClient
Try
smtp.Send(mm)
mm.Dispose()
mm = Nothing
smtp.Dispose()
smtp = Nothing
Return True
Catch ex As Exception
Return False
End Try
End Function
For some time now, whenever I try to send an email I get this error:
Mailbox unavailable. The server response was: 5.2.0 Jhw61q00C2SXeFl01 Spam Rejected
I searched for hours for a solution, but did not find any information.
Please help me understand what is going on, and why I'm getting this error. If you need more information, I will provide it, but please try to help me.
After more tests, I think the problem is due to the raising of the anti-spam policy of internet services providers. I will ask for this to my provider.

VB.NET mailto: Run-time error '91'

Can anyone take a look at my code below and recommend how I can stop receiving the dreaded error 91. Error: Object variable or With block variable not set.
I am using the mailto: function to send an email using the native email client and populating the email w/ data from a gridview. After the error pops up, I simply click ok and the email is loaded w/ the exact data I want!
Protected Sub GridView2_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles GridView2.SelectedIndexChanged, GridView1.SelectedIndexChanged
Dim MailFormat, Number, BodyOfEmail, FullName As String
Dim RowValue As Double
RowValue = GridView1.SelectedDataKey.Value - 1
Number = GridView1.Rows(RowValue).Cells(5).Text.ToString
FullName = GridView1.Rows(RowValue).Cells(25).Text.ToString
BodyOfEmail = “SomeTextInTheBody”
MailFormat = "mailto:" & Number & "?" & "subject= A subject here" & "&body=" & BodyOfEmail
System.Diagnostics.Process.Start(MailFormat)
End Sub
I can execute the following code from the .aspx page just fine:
a href="mailto:someone#example.com?Subject=Hello%20again"
and outlook opens without issue. It appears to only be an issue when the aspx.vb code up at the top is executed...
Thanks
<a href="mailto:xxx"/> works fine because it is executing in the user's browser, and will use the user's locally-installed interactive email application, whatever it happens to be.
Process.Start("mailto:xxx") will always fail because it is executing on the web server, which will probably not have a locally-installed interactive email application available, and even if it did, you would not be able to start it interactively on a desktop that does not exist. The fact that it happens to throw error 91 in your test environment is irrelevant. Don't do it, full stop.
What you need to do is arrange for a bit of JavaScript to execute on page render after the server-side event has completed. Something like location.href = "mailto:xxx" may do the trick. Exactly where you should insert this depends on your page design.
Alternatively, if you want to keep the email generation code entirely on the server-side, and you know that your users will always be using Outlook, you could look at calling Exchange Server directly. See here for a starting point.
Have you considered using the SmtpClient class?
Dim SmtpServer As New SmtpClient()
Dim mail As New MailMessage()
SmtpServer.Credentials = New Net.NetworkCredential("sender address", "sender password")
SmtpServer.Port = 587 'If sending from gmail...
SmtpServer.Host = "smtp.gmail.com" 'If sending from gmail...
mail = New MailMessage()
mail.From = New MailAddress("sender address")
mail.To.Add("recipient address")
mail.Subject = ""
mail.Body = ""
SmtpServer.Send(mail)

Sharepoint not getting current user NetworkCredential from active directory

we have strange problem, we have single signon and we are trying to fetch unread email count from Exchange ews webservice, the problem is it always gets same count for all user which is actually for server user.
'it should now get for current user who requested the page
'but its always for server user where sharepoint is installed
Public Sub GetUnreadEmailCount()
Dim errormsg As String = String.Empty
Dim UnreadCount As Integer = 0
Dim esb As New ExchangeServiceBinding
Try
esb.RequestServerVersionValue = New RequestServerVersion
esb.RequestServerVersionValue.Version = ExchangeVersionType.Exchange2007_SP1
esb.UseDefaultCredentials = True
esb.Url = Domain + "/EWS/Exchange.asmx"
ServicePointManager.ServerCertificateValidationCallback = New RemoteCertificateValidationCallback(AddressOf CertificateValidationCallBack)
Dim biArray(1) As BaseFolderIdType
Dim dfFolder As New DistinguishedFolderIdType
dfFolder.Id = DistinguishedFolderIdNameType.inbox
biArray(0) = dfFolder
Dim geGetFolder As New GetFolderType
geGetFolder.FolderIds = biArray
geGetFolder.FolderShape = New FolderResponseShapeType
geGetFolder.FolderShape.BaseShape = DefaultShapeNamesType.AllProperties
Dim gfResponse As GetFolderResponseType = esb.GetFolder(geGetFolder)
Dim rmta As ResponseMessageType() = gfResponse.ResponseMessages.Items
Dim rmt As FolderInfoResponseMessageType = DirectCast(rmta(0), FolderInfoResponseMessageType)
If rmt.ResponseClass = ResponseClassType.Success Then
Dim folder As FolderType = DirectCast(rmt.Folders(0), FolderType)
UnreadCount = folder.UnreadCount
End If
Label1.Text = vbCrLf + "Unread email count : " + UnreadCount.ToString
' Return UnreadCount
Catch ex As Exception
If Not ex.Message Is Nothing Then errormsg = ex.Message
Try
If Not ex.InnerException.Message Is Nothing Then errormsg = errormsg + " : " + ex.InnerException.Message
Catch e As Exception
End Try
Finally
If esb IsNot Nothing Then esb.Dispose() : esb = Nothing
If Not errormsg = String.Empty Then
Label1.Text = vbCrLf + "Error : " + errormsg
End If
End Try
End Sub
We were actually having the same problem, although we were not using single sign on. So I'm not sure this is exactly what you are experiencing.
The problem is that you can not have a user on Machine A give their credentials to Machine B (SharePoint?) and then have Machine B send those credentials on to Machine C
It's referred to as the "Double Hop" problem and is a security feature, however I'm not really into the technical side of it. Our solution was to use Kerberos.
I hope this helps you, if not, that it helps you rule out this specific issue :)
Your server side code is running as the AppPool's identity, which is your sharepoint service account. I'm assuming that's what you mean by 'the server user.'
esb.UseDefaultCredentials = true;
will use the creds of the context. I'm not sure of what's available in the EWS services, so if you can use a higher-privileged account and get based on the user coming in, i.e., HttpContext.Current.User.Identity as a parameter, then that may be the best way.
You could authenticate via javascript directly to the EWS services, skipping server-side code altogether, and write something that consumes & displays the server stuff as you need it.
You'd need to find a way to auth the user directly to the EWS services. Double-hop is an issue with NTLM, as your NTLM ticket is only valid for the first hop. Kerberos fixes that, but you still need to impersonate.

How to customize InnerException.Message for System.Data.UpdateException in ASP.NET

First of all thanks for taking the time to read through my post. I have a question that may be a newbie piece of cake for some.
I am adding data to a database table using Entity Framework. When adding a duplicate Primary Key I get an exception in InnerException.Message that reads "Violation of PRIMARY KEY constraint 'PK_StudentID'. Cannot insert duplicate key in object 'dbo.Students'. The statement has been terminated. "
However, what I want to do is to rephrase this error message for the end user, but also save this exact message with the table name and column name to my logs for later. Essentially, I want to rephrase the error message to "You cannot have a duplicate entry for Student Identification Number. Please enter a new value."
How can I do this?
I have tried to inherit from System.Data.UpdateException and put an if check to see what the innerexception.message reads, and then change it accordingly. That did not work.
Thanks,
I think this will do what you want.
Try
'your code
Catch ex As Exception
'store the ex.Message where you want
Throw New Exception("Your custom message here.")
End Try
Example:
Private Sub uiFunction()
Dim errorMessage As String
Try
'a call to a BLL function/sub that could cause an exception
Catch ex As Exception
errorMessage = ex.Message() 'ex.Message() = "Your custom message."
End Try
End Sub
Public Sub BLLFunction()
Try
'run your code that could cause an exception
Catch ex As Exception
Throw New Exception("Your custom message.")
End Try
End Sub

Resources