Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/296.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在.Net 4.5 beta版中将System.Net.Mail.MailMessage作为MemoryStream获取_C#_.net 4.5 - Fatal编程技术网

C# 在.Net 4.5 beta版中将System.Net.Mail.MailMessage作为MemoryStream获取

C# 在.Net 4.5 beta版中将System.Net.Mail.MailMessage作为MemoryStream获取,c#,.net-4.5,C#,.net 4.5,因此,下面的代码用于在.NET 4中获得System.NET.Mail.MailMessage对象作为MemoryStream,但是随着.NET 4.5 beta的发布,会出现运行时异常 Assembly assembly = typeof(SmtpClient).Assembly; Type mailWriterType = assembly.GetType("System.Net.Mail.MailWriter"); using (MemoryStream stream = new Memo

因此,下面的代码用于在.NET 4中获得System.NET.Mail.MailMessage对象作为MemoryStream,但是随着.NET 4.5 beta的发布,会出现运行时异常

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()上发生运行时异常。

已设法找出如何在.NET 4.5 beta版中再次运行此功能。MailMessage中的私有API Send()方法已更改为:内部void Send(BaseWriter writer、bool sendEnvelope、bool allowinicode)

请在下面找到更新的代码

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);

    .....
}

建议的解决方案加上额外的真值,效果很好

在VS2012中运行项目时,我开始出现错误,尽管我在所有库中使用的不是.net 4.5而是4.0

该错误仅发生在安装了VS2012的计算机上,看起来VS2012在调试时引用了.net 4.5。当您在运行.net 4.0的客户端中部署和运行应用程序时,一切正常


因此:如果您运行4.0-不要添加额外的TRUE,如果您运行4.5,请添加它。

如果您不想使用不受支持的hack,也不介意额外的性能打击,这可能是有用的

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 );
        }
    }

用于检查我是否使用了额外的布尔值:

 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

我们与邮件信息转换斗争了很长一段时间。最终的解决办法是使用


如果您使用上述方法,您将非常接近,并且在大多数文化中都可以使用,但最终主题编码将击败您。

有什么例外(堆栈跟踪可能会有所帮助)?例外情况是:System.Reflection.TargetParameterCountException:参数计数不匹配。您是否将.NET 4代码与.NET 4.5进行了比较,以查看它们是否丢失了
发送
的重载?使用
dynamic
可以更简单地处理这一问题。请参阅下面的答案,他们在Send方法中添加了一个额外的布尔参数(AllowInCode)。这就是访问非公共方法所得到的结果:)据我所知,没有其他方法可以获取邮件的MemoryStream。甚至之前的文章都使用私有API方法,甚至第三方供应商的示例也使用这种私有API方法。如果有人知道使用公共API实现这一点的方法,那么分享它会有很大帮助:)嗨,除了closeMethod.Invoke(mailWriter,BindingFlags.Instance | BindingFlags.NonPublic,null,new object[]{},null);。。。有线索吗?ThanksNote,在.NET 5 MailWriterContractor中,上述代码中不能为null。新的构造函数是(Stream,bool)。是的,我也遇到过这个。我们必须设置编译器条件,这样我们才能调试代码并使其在生产环境中工作。这是一个很好的解决方法,并且可能会通过进一步的api版本工作。谢谢我在使用这种技术时发现的唯一问题是Bcc目的地从标头中删除。美好的不过有一件事:如果app.config包含smtp设置,则必须覆盖这些设置。请确保将主机设置为
localhost
,凭据设置为
null
,并将SSL启用为
false
。这是我首选的解决方案。唯一的问题是;既然我们在Windows\TEMP中创建了随机文件夹,那么从长远来看,Windows会“允许”这样做吗?我的意思是,如果很多邮件一直同时发送,程序最终会因此而崩溃吗?
var memoryStream = new MemoryStream();
var mimeMessage = MimeMessage.CreateFromMailMessage(message);
mimeMessage.WriteTo(memoryStream);