Click here to Skip to main content
15,890,741 members
Please Sign up or sign in to vote.
1.00/5 (2 votes)
See more:
Regarding this article: Adding Save() functionality to System.Net.Mail.MailMessage[^]

I found someone had already converted this to VB so I copied it:


VB
Public Shared Sub WriteEmailMessageToFile(Message As MailMessage, FileName As String)

        Dim assembly As Assembly = GetType(SmtpClient).Assembly

        Dim _mailWriterType As Type = assembly.[GetType]("System.Net.Mail.MailWriter")

        Using _fileStream As New FileStream(FileName, FileMode.Create)
            ' Get reflection info for MailWriter contructor
            Dim _mailWriterContructor As ConstructorInfo = _mailWriterType.GetConstructor(BindingFlags.Instance Or BindingFlags.NonPublic, Nothing, New Type() {GetType(Stream)}, Nothing)

            ' Construct MailWriter object with our FileStream
            Dim _mailWriter As Object = _mailWriterContructor.Invoke(New Object() {_fileStream})

            ' Get reflection info for Send() method on MailMessage
            Dim _sendMethod As MethodInfo = GetType(MailMessage).GetMethod("Send", BindingFlags.Instance Or BindingFlags.NonPublic)


            ' Call method passing in MailWriter
            _sendMethod.Invoke(Message, BindingFlags.Instance Or BindingFlags.NonPublic, Nothing, New Object() {_mailWriter, True}, Nothing)


            ' Finally get reflection info for Close() method on our MailWriter
            Dim _closeMethod As MethodInfo = _mailWriter.[GetType]().GetMethod("Close", BindingFlags.Instance Or BindingFlags.NonPublic)


            ' Call close method
            _closeMethod.Invoke(_mailWriter, BindingFlags.Instance Or BindingFlags.NonPublic, Nothing, New Object() {}, Nothing)


        End Using

    End Sub


When I execute, it hangs on the line:
VB
_sendMethod.Invoke(Message, BindingFlags.Instance Or BindingFlags.NonPublic, Nothing, New Object() {_mailWriter, True}, Nothing)


Please help me determine what is wrong with this line of code.
Posted
Comments
Sergey Alexandrovich Kryukov 2-Sep-15 21:21pm    
The whole idea is wrong. Getting a method by name from reflection is a really bad thing, bad for maintenance. It makes use of "magic strings" like "Send", which cannot be validated be a compiler. In almost all cases, it can be avoided.
—SA

1 solution

Please see my comment to the question. Avoid doing such things.

I can suggest you the alternative method I use: saving a mail message to file using the same method as sending it: System.Net.Mail.SmptClient.Send
To do so, you can use your instance of System.Net.Mail.SmptClient and modify two properties of its instance: set DeliveryMethod to SmtpDeliveryMethod.SpecifiedPickupDirectory and set PickupDirectoryLocation to some directory (you can later rename the file created there, so it could be a temporary directory). Your SmptClient instance will save a message copy for you.

Please see:
https://msdn.microsoft.com/en-us/library/swas0fwc(v=vs.110).aspx[^],
https://msdn.microsoft.com/en-us/library/system.net.mail.smtpclient.deliverymethod(v=vs.110).aspx[^],
https://msdn.microsoft.com/en-us/library/system.net.mail.smtpdeliverymethod%28v=vs.110%29.aspx[^],
https://msdn.microsoft.com/en-us/library/system.net.mail.smtpclient.pickupdirectorylocation(v=vs.110).aspx[^].

—SA
 
Share this answer
 
v2
Comments
KevinBrady57 3-Sep-15 12:52pm    
Sergey, Thanks for the response. I implemented the methodology you suggested and it works exactly as I need it. It is also much simpler and more straightforward.

I would like to know, however, why the "invoke" method does not work.
Sergey Alexandrovich Kryukov 3-Sep-15 12:58pm    
To figure out why MethodInfo.Invoke did not work, you can check up everything step by step, perhaps under the debugger, and get mode detail about the method. You can have more than one method under the same name; and the method (MethodInfo instance) you've chosen can have different set of parameter than you assumed...

As my advice works, I suggest you accept the answer formally, will you?

—SA
KevinBrady57 3-Sep-15 17:26pm    
Yes, I will accept your answer. I meant to do that earlier. Sorry.
Sergey Alexandrovich Kryukov 3-Sep-15 17:40pm    
Nothing to be sorry about, thank you. Good luck, call again.
—SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900