2012-03-07 21 views
21

में मेमोरीस्ट्रीम के रूप में System.Net.Mail.MailMessage प्राप्त करना, इसलिए नीचे दिया गया कोड .NET 4 में काम करने के लिए प्रयुक्त होता है। System.et.Mail.MailMessage ऑब्जेक्ट को मेमोरीस्ट्रीम के रूप में प्राप्त करने के लिए, हालांकि रिलीज़ के साथ .NET 4.5 बीटा का रनटाइम अपवाद होता है।.NET 4.5 बीटा

Assembly assembly = typeof(SmtpClient).Assembly; 
Type mailWriterType = assembly.GetType("System.Net.Mail.MailWriter"); 
using (MemoryStream stream = new MemoryStream()) 
{ 
    ConstructorInfo mailWriterContructor = mailWriterType.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { typeof(Stream) }, null); 
    object mailWriter = mailWriterContructor.Invoke(new object[] { stream }); 
    MethodInfo sendMethod = typeof(MailMessage).GetMethod("Send", BindingFlags.Instance | BindingFlags.NonPublic); 
    sendMethod.Invoke(message, BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { mailWriter, true }, null); 

    ..... 
} 

रनटाइम अपवाद sendMethod.Invoke() पर होता है।

+0

अपवाद (स्टैक ट्रेस करने में मदद कर सकते हैं) क्या है? –

+0

अपवाद यह था: सिस्टम। रिफ्लेक्शन। लक्ष्य पैरामीटर कैंटर अपवाद: पैरामीटर गिनती मेल नहीं खाता। – dimoss

+0

क्या आपने .NET 4 कोड की तुलना .NET 4.5 से की है, यह देखने के लिए कि क्या उन्होंने 'Send' का अधिभार छोड़ा है? यह निश्चित रूप से 'गतिशील' के उपयोग के साथ अधिक आसानी से संभाला जा सकता है। –

उत्तर

29

यह पता लगाने के लिए प्रबंधित किया गया कि यह .NET 4.5 बीटा में फिर से काम कैसे करें। MailMessage में निजी एपीआई भेजें() विधि बदल गई है: आंतरिक शून्य भेजें (बेसवाइटर लेखक, बूल sendEnvelope, bool allowUnicode)

कृपया नीचे अपडेट कोड खोजें।

Assembly assembly = typeof(SmtpClient).Assembly; 
Type mailWriterType = assembly.GetType("System.Net.Mail.MailWriter"); 
using (MemoryStream stream = new MemoryStream()) 
{ 
    ConstructorInfo mailWriterContructor = mailWriterType.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { typeof(Stream) }, null); 
    object mailWriter = mailWriterContructor.Invoke(new object[] { stream }); 
    MethodInfo sendMethod = typeof(MailMessage).GetMethod("Send", BindingFlags.Instance | BindingFlags.NonPublic); 
    sendMethod.Invoke(message, BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { mailWriter, true, true }, null); 

    ..... 
} 
+0

गैर-सार्वजनिक तरीकों तक पहुंचने के लिए आपको यही मिलता है :) –

+7

जहां तक ​​मैं जांच कर सकता हूं, मेलमेस के मेमोरीस्ट्रीम को पाने का कोई और तरीका नहीं है। यहां तक ​​कि यहां तक ​​कि पिछली पोस्ट भी निजी एपीआई विधि का उपयोग करती हैं, और तीसरे पक्ष के विक्रेताओं के उदाहरण भी इस निजी एपीआई विधि का उपयोग करते हैं। अगर कोई सार्वजनिक एपीआई का उपयोग करके ऐसा करने के तरीके के बारे में जानता है तो इसे साझा करने में एक बड़ी मदद होगी :) – dimoss

+0

हाय, मुझे एक ही समस्या है लेकिन closeMethod.Invoke (mailWriter, बाइंडिंगफ्लैग्स.इन्स्टेंस | बाइंडिंगफ्लैग। नॉनपब्लिक, नल, नया वस्तु [] {}, शून्य); ... कोई सुराग? धन्यवाद – VAAA

0

अतिरिक्त सत्य कार्यों के साथ प्रस्तावित समाधान खूबसूरती से काम करता है।

मुझे वीएस2012 में अपनी परियोजना चलाने के दौरान त्रुटि प्राप्त करना शुरू हुआ, भले ही मैं अपने सभी पुस्तकालयों में .NET 4.5 लेकिन 4.0 का उपयोग नहीं कर रहा हूं।

त्रुटि केवल उस मशीन पर होती है जहां आपने VS2012 स्थापित किया है, ऐसा लगता है कि VS2012 डीबगिंग करते समय .NET 4.5 के संदर्भ में बनाता है। जब आप चल रहे क्लाइंट में एप्लिकेशन को तैनात और चलाते हैं .net 4.0 सब कुछ ठीक काम करता है।

इस प्रकार: यदि आप 4.0 चलाते हैं - अतिरिक्त TRUE जोड़ें, यदि आप इसे 4.5 जोड़ते हैं तो इसे जोड़ें।

+0

हाँ मैं भी इसमें भाग गया। कंपाइलर सशर्त को रखना था ताकि हम कोड डीबग कर सकें और इसे उत्पादन में काम कर सकें। – efbenson

12

यदि आप असमर्थित हैक्स के साथ नहीं जाना चाहते हैं और अतिरिक्त प्रदर्शन हिट नहीं मानते हैं तो यह उपयोग योग्य हो सकता है।

public static class MailMessageExtensions 
    { 
    public static string RawMessage(this MailMessage m) 
     { 
     var smtpClient = new SmtpClient { DeliveryMethod = SmtpDeliveryMethod.SpecifiedPickupDirectory }; 

     using (var tempDir = new TemporaryDirectory()) 
      { 
      smtpClient.PickupDirectoryLocation = tempDir.DirectoryPath; 
      smtpClient.Send(m); 
      var emlFile = Directory.GetFiles(smtpClient.PickupDirectoryLocation).FirstOrDefault(); 
      if (emlFile != null) 
       { 
       return File.ReadAllText(emlFile); 
       } 
      else 
       return null; 
      } 
     return null; 
     } 

    } 

class TemporaryDirectory : IDisposable 
    { 
    public TemporaryDirectory() 
     { 
     DirectoryPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); 
     Directory.CreateDirectory(DirectoryPath); 
     } 

    public string DirectoryPath { get; private set; } 

    public void Dispose() 
     { 
     if (Directory.Exists(DirectoryPath)) 
      Directory.Delete(DirectoryPath, true); 
     } 
    } 
+0

अच्छा कामकाज, और आगे एपीआई संस्करणों के माध्यम से काम करने की संभावना है। धन्यवाद! – antlersoft

9

की जाँच के लिए यदि अतिरिक्त बूलियन मैं का उपयोग करें:

If _sendMethod.GetParameters.Length = 2 Then 
    _sendMethod.Invoke(Message, BindingFlags.Instance Or BindingFlags.NonPublic, Nothing, New Object() {_mailWriter, True}, Nothing) 
Else 
    _sendMethod.Invoke(Message, BindingFlags.Instance Or BindingFlags.NonPublic, Nothing, New Object() {_mailWriter, True, True}, Nothing) 
End If 
+1

यह मेरे लिए .NET 4.0 और 4.5 के साथ काम किया। धन्यवाद! – LuckyStrike

संबंधित मुद्दे