首页 > 解决方案 > 在已发布的 ASP.Net Core API 中创建和保存文件不起作用

问题描述

我正在尝试使用 google drive API(docx、excel 等)和 iTextSharp(png、jpeg 等)将上传的文件转换为 pdf 的 .Net Core API。首先,我将文件上传到服务器并将其保存在服务器目录中,然后我将该文件转换为 PDF(使用 Drive API 或 iTextSharp)并保存到同一个文件夹,但它不起作用并且没有错误。当我在本地主机中测试它时,它工作得很好。这是代码:

public async System.Threading.Tasks.Task DriveExcelAsync(string pathupload, string download, string filename, string ext)
    {
        // UserCredential credential;
        string serviceAccountEmail = "myaccount@myaccount-api.im.gserviceaccount.com";

        var certificate = new X509Certificate2(Path.Combine(Directory.GetCurrentDirectory(), "key.p12"), "secret", X509KeyStorageFlags.Exportable);

        ServiceAccountCredential credential = new ServiceAccountCredential(
           new ServiceAccountCredential.Initializer(serviceAccountEmail)
           {
               Scopes = new[] { DriveService.Scope.Drive }
           }.FromCertificate(certificate));

        // Create Drive API service.
        var service = new DriveService(new BaseClientService.Initializer()
        {
            HttpClientInitializer = credential,
            ApplicationName = ApplicationName,
        });

        string mime = "";
        string reqstream = "";
        if (ext == ".xls" || ext == ".xlsx")
        {
            mime = "application/vnd.google-apps.spreadsheet";
            reqstream = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
        }
        else if (ext == ".doc" || ext == ".docx")
        {
            mime = "application/vnd.google-apps.document";
            reqstream = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
        }

        var fileMetadata = new Google.Apis.Drive.v3.Data.File()
        {
            Name = filename,
            MimeType = mime
        };

        FilesResource.CreateMediaUpload request;
        using (var stream1 = new System.IO.FileStream(pathupload,
                                System.IO.FileMode.Open))
        {
            request = service.Files.Create(
                fileMetadata, stream1, reqstream);
            request.Fields = "id";
            request.Upload();
            request.Resume();
        }
        var file = request.ResponseBody;
        Console.WriteLine("File ID: " + file.Id);

        //DOWNLOAD FILE

        var fileId = file.Id;
        var request1 = service.Files.Export(fileId, "application/pdf");
        var streamdownload = new System.IO.MemoryStream();

        request1.MediaDownloader.ProgressChanged +=
                (IDownloadProgress progress) =>
                {
                    switch (progress.Status)
                    {
                        case DownloadStatus.Downloading:
                            {
                                Console.WriteLine(progress.BytesDownloaded);
                                break;
                            }
                        case DownloadStatus.Completed:
                            {
                                Console.WriteLine("Download complete.");

                                using (FileStream fileOutp = new FileStream(download, FileMode.Create, FileAccess.Write))
                                {
                                    streamdownload.WriteTo(fileOutp);
                                }

                                break;
                            }
                        case DownloadStatus.Failed:
                            {
                                Console.WriteLine("Download failed.");
                                break;
                            }
                    }
                };
        request1.Download(streamdownload);
    }

    public async void ConvertToPdf(string filePath, string filename)
    {
        string ext = Path.GetExtension(filePath).ToLower();
        object paramSourcePath = filePath;
        object paramMissing = Type.Missing;
        string paramExportFilePath = Path.Combine(Directory.GetCurrentDirectory(), "File", filename + ".pdf");

        try
        {
            await DriveExcelAsync(filePath, paramExportFilePath, filename, ext);
            if (ext == ".doc" || ext == ".docx" || ext == ".xls" || ext == ".xlsx")
            {
                await DriveExcelAsync(filePath, paramExportFilePath, filename, ext);
            }
            else if (ext == ".jpg" || ext == ".jpeg" || ext == ".png")
            {
                iTextSharp.text.Rectangle pageSize = null;
                using (var srcImage = new Bitmap(filePath))
                {
                    pageSize = new iTextSharp.text.Rectangle(0, 0, srcImage.Width, srcImage.Height);
                }
                using (var ms = new MemoryStream())
                {
                    var document = new iTextSharp.text.Document(pageSize, 0, 0, 0, 0);
                    PdfWriter.GetInstance(document, ms).SetFullCompression();
                    document.Open();
                    var image = iTextSharp.text.Image.GetInstance(filePath);
                    document.Add(image);
                    document.Close();

                    System.IO.File.WriteAllBytes(paramExportFilePath, ms.ToArray());
                }
            }
        }catch(Exception e)
        {
            throw e;
        }
    }

我认为应该保存转换后的文件的部分在我发布项目后由于某种原因无法正常工作。有谁知道如何解决这个问题?谢谢。

更新
在尝试了很多事情之后,我终于可以通过将已发布的项目移动到另一个使用不同 IIS 应用程序池标识的域/站点来使其工作。但我仍然不知道为什么它不能在以前的域/站点上运行,我认为它与 IIS 应用程序池身份权限有关。

标签: c#iisasp.net-coregoogle-drive-apiasp.net-core-webapi

解决方案


推荐阅读