【问题标题】:Returning Outlook Mail Item to Client in MVC在 MVC 中将 Outlook 邮件项返回给客户端
【发布时间】:2015-08-28 02:21:19
【问题描述】:

在较高级别上,我正在尝试生成 Outlook 电子邮件项目服务器端,然后将其返回给客户端,以便它在本地 Outlook 中打开,允许他们进行所需的任何更改(这与发送通过 SMTP 发送电子邮件)。

这真的是我第一次使用文件流,我不确定如何继续。我有一个我正在尝试做的非常基本的开始,最初只是在此控制器操作返回邮件项目后打开 Outlook。此代码是在控制器中调用以创建邮件项的代码。我没有任何添加各种电子邮件地址、正文、主题等的逻辑,因为这并不相关。这个代码也被控制器动作调用,只是把它放在这里,以防我在创建邮件项时也做错了。

     public MailItem CreateEmail(int id)
    {
        Application app = new Application();
        MailItem email = (MailItem)app.CreateItem(OlItemType.olMailItem);
        email.Recipients.Add("example@example.com");
        return email;
    }

这是我想将此 MailItem 返回给客户端的控制器操作。 (这就是通过 AJAX 调用的方法)

    public ActionResult GenerateEmail(int id)
    {
        using (MemoryStream ms = new MemoryStream())
        {
            BinaryFormatter format = new BinaryFormatter();
            format.Serialize(ms, logic.CreateEmail(id));
            return File(ms, "message/rfc822");
        }
    }

代码在 format.Serialize 处中断,提示我的 _COM 对象无法序列化。有没有办法做我想做的事,还是应该寻找其他方法来实现这个目标?

【问题讨论】:

    标签: c# asp.net-mvc email outlook


    【解决方案1】:

    主要基于来自here的代码,

    public ActionResult DownloadEmail()
    {
        var message = new MailMessage();
    
        message.From = new MailAddress("from@example.com");
        message.To.Add("someone@example.com");
        message.Subject = "This is the subject";
        message.Body = "This is the body";
    
        using (var client = new SmtpClient())
        {
            var id = Guid.NewGuid();
    
            var tempFolder = Path.Combine(Path.GetTempPath(), Assembly.GetExecutingAssembly().GetName().Name);
    
            tempFolder = Path.Combine(tempFolder, "MailMessageToEMLTemp");
    
            // create a temp folder to hold just this .eml file so that we can find it easily.
            tempFolder = Path.Combine(tempFolder, id.ToString());
    
            if (!Directory.Exists(tempFolder))
            {
                Directory.CreateDirectory(tempFolder);
            }
    
            client.UseDefaultCredentials = true;
            client.DeliveryMethod = SmtpDeliveryMethod.SpecifiedPickupDirectory;
            client.PickupDirectoryLocation = tempFolder;
            client.Send(message);
    
            // tempFolder should contain 1 eml file
    
            var filePath = Directory.GetFiles(tempFolder).Single();
    
            // stream out the contents - don't need to dispose because File() does it for you
            var fs = new FileStream(filePath, FileMode.Open);
            return File(fs, "application/vnd.ms-outlook", "email.eml");
        }
    }
    

    这在 Chrome 中运行良好,但 IE 不想打开它,也许它有一些额外的安全功能。尝试摆弄内容类型和文件扩展名,你也许可以让它在两者中都起作用。

    【讨论】:

    • 我必须添加的一件事是message.Headers.Add("X-Unsent", "1");,正如 Dmitry 建议的那样,消息将以合成模式打开。它也为我在 IE 中打开而没有任何更改,所以我认为问题可能是特定版本的 IE?老实说,我对代码的作用并不完全肯定,但它确实有效。 :)
    【解决方案2】:

    首先,Outlook 对象模型不能用于服务(例如 IIS)。其次,既然你只是指定收件人地址,为什么不在客户端使用mailto链接呢?

    如果您仍想发送邮件,您可以生成一个 EML (MIME) 文件 - Outlook 应该可以正常打开它。要使其看起来未发送,请使用 X-Unsent MIME 标头。

    【讨论】:

    • 谢谢德米特里。就像我上面所说的,我添加的不仅仅是收件人,还会根据用户选择的选项生成一个特定的正文。收件人、抄送和密件抄送字段也都是动态的,具体取决于用户选择。由于问题与此无关,因此我删除了逻辑以使其更易于阅读。您是否有可能发布上面解释的代码示例?在我键入此内容时尝试研究 EML (MIME) 文件的创建。
    • EML 只是一个简单的文本文件,您可能甚至不需要任何库来创建一个。
    猜你喜欢
    • 1970-01-01
    • 2020-11-22
    • 1970-01-01
    • 1970-01-01
    • 2011-05-05
    • 1970-01-01
    • 2013-02-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多