发送电子邮件ASP.NET MVC 5后删除Rotativa pdf

时间:2021-10-24 16:37:19

I am able to generate pdf using Rotativa and using the code below. So I save the pdf and email as an attachment. Now my problem is how to delete this file. The file generation and emailing could take a while so when the delete call is made it generates an error: The process cannot access the file ....blah/blah.pdf because it is being used by another process.

我可以使用Rotativa生成pdf并使用下面的代码。所以我将pdf和电子邮件保存为附件。现在我的问题是如何删除此文件。文件生成和发送电子邮件可能需要一段时间,因此当进行删除调用时会产生错误:进程无法访问文件.... blah / blah.pdf,因为它正被另一个进程使用。

I need help to be able to clean up the files generated. These files span a years worth of records and take up quite a bit of space and time to generate.

我需要帮助才能清理生成的文件。这些文件跨越了多年的记录,占用了相当多的空间和时间来生成。

How do I make the delete call take place when the file has been completely emailed and released?

如何在文件完全通过电子邮件发送和发布后进行删除调用?

public ActionResult Receipt(int year, int Id, ReceiptViewModel model)
        {
            var root = Server.MapPath("~/App_Data/");
            var pdfname = String.Format("{0}-{1}-{2}.pdf", Id, year, Guid.NewGuid().ToString());
            var path = Path.Combine(root, pdfname);
            path = Path.GetFullPath(path);
            IUserMailer mailer = new UserMailer();


            var a = new ViewAsPdf("Receipt", new { Id, year })
            {
                FileName = pdfname,
                PageSize = Rotativa.Options.Size.A5,
                PageOrientation = Rotativa.Options.Orientation.Portrait,
                SaveOnServerPath = path
            };

            var byteArray = a.BuildFile(ControllerContext);
            var fileStream = new FileStream(path, FileMode.Create, FileAccess.Write);
            fileStream.Write(byteArray, 0, byteArray.Length);
            fileStream.Close();
       // email the pdf as attachment  
      mailer.BulkReceipt(path, pdfname, Id, year).SendAsync();
      // Delete file
System.IO.File.Delete(path);
            return View("ReceiptSuccess", a);


        }

2 个解决方案

#1


0  

You could..., make an in mem copy of the file and then tell the mailer to use that version(in mem).... which means you can delete the local physical file. the in mem version will clean itself up once no-longer used.

你可以...,制作文件的mem副本,然后告诉邮件程序使用该版本(在mem中)....这意味着你可以删除本地物理文件。 mem版本将在不再使用时自行清理。

#2


0  

Usually a method with Async in its name will call a callback method when it is complete or return a Task.

通常,名称中包含Async的方法将在完成时调用回调方法或返回Task。

Often the callback will be passed into the method, something like below:

通常将回调传递给方法,如下所示:

mailer.BulkReceipt(path, pdfname, Id, year).SendAsync(() => System.IO.File.Delete(path));

But sometimes there is a separate event that you need to wire up on your object with the callback for the when it is finished. In this case it could be called SendComplete or something similar.

但有时会有一个单独的事件,您需要使用回调完成对象的连接。在这种情况下,它可以被称为SendComplete或类似的东西。

If the SendAsync call returns a Task, then you probably want to call await and make your Receipt method async:

如果SendAsync调用返回任务,那么您可能想要调用await并使您的Receipt方法异步:

public async Task<ActionResult> Receipt(int year, int Id, ReceiptViewModel model)
{
    ...
    await mailer.BulkReceipt(path, pdfname, Id, year).SendAsync();
    // Delete file
    System.IO.File.Delete(path);

    return View("ReceiptSuccess", a);
}

Or something similar to that...

或类似的东西......

#1


0  

You could..., make an in mem copy of the file and then tell the mailer to use that version(in mem).... which means you can delete the local physical file. the in mem version will clean itself up once no-longer used.

你可以...,制作文件的mem副本,然后告诉邮件程序使用该版本(在mem中)....这意味着你可以删除本地物理文件。 mem版本将在不再使用时自行清理。

#2


0  

Usually a method with Async in its name will call a callback method when it is complete or return a Task.

通常,名称中包含Async的方法将在完成时调用回调方法或返回Task。

Often the callback will be passed into the method, something like below:

通常将回调传递给方法,如下所示:

mailer.BulkReceipt(path, pdfname, Id, year).SendAsync(() => System.IO.File.Delete(path));

But sometimes there is a separate event that you need to wire up on your object with the callback for the when it is finished. In this case it could be called SendComplete or something similar.

但有时会有一个单独的事件,您需要使用回调完成对象的连接。在这种情况下,它可以被称为SendComplete或类似的东西。

If the SendAsync call returns a Task, then you probably want to call await and make your Receipt method async:

如果SendAsync调用返回任务,那么您可能想要调用await并使您的Receipt方法异步:

public async Task<ActionResult> Receipt(int year, int Id, ReceiptViewModel model)
{
    ...
    await mailer.BulkReceipt(path, pdfname, Id, year).SendAsync();
    // Delete file
    System.IO.File.Delete(path);

    return View("ReceiptSuccess", a);
}

Or something similar to that...

或类似的东西......