0

I'm having a lot of trouble trying to get my App to work when published. Basically, the code is supposed to create a doc from template using Open XML sdk, then save to wwwroot and then upload to blob storage.

It's working fine using local host. Have read and tried some stuff re accessing static files - but nothing seems to work. Any help would be very much appreciated. Relevant code is below:

[HttpGet]
public IActionResult GenerateDocxBrowser(MemoryStream mem, string filepath, string inputLastName, string inputTitle, string requestID, string dateReceived, string complaintType, string complaintDetails, string nameString, string no, string street, string town, string postcode)
{
        var list = _context.Complaints.Where(s => s.ComplaintId.ToString().Contains(requestID)).ToList();
        using (mem = new MemoryStream())
        {

        filepath = @"wwwroot\RequestTemplate.docx";


        nameString = list.Select(s => s.NameString).FirstOrDefault();
            complaintDetails = list.Select(s => s.Complaint).FirstOrDefault();
            street = list.Select(s => s.AddressStreet).FirstOrDefault();
            town = list.Select(s => s.AddressTown).FirstOrDefault();
            using (WordprocessingDocument document = WordprocessingDocument.Open(filepath,true))
            {
                document.GetMergeFields("LastName").ReplaceWithText(inputLastName);
                document.GetMergeFields("Title").ReplaceWithText(inputTitle);
                document.GetMergeFields("ComplaintID").ReplaceWithText(requestID);
                document.GetMergeFields("DateReceived").ReplaceWithText(dateReceived);
                document.GetMergeFields("ComplaintType").ReplaceWithText(complaintType);
                document.GetMergeFields("ComplaintDetails").ReplaceWithText(complaintDetails);
                document.GetMergeFields("NameString").ReplaceWithText(nameString);
                document.GetMergeFields("AddressLn1").ReplaceWithText(no + " " + street);
                document.GetMergeFields("AddressLn2").ReplaceWithText(town + " TAS " + postcode);
                document.SaveAs(@"wwwroot\" + requestID + ".docx");
                document.MainDocumentPart.Document.Save();
                document.Close();
            }
        }

    const string StorageAccountName = "xxx";
    const string StorageAccountKey = "xxxxxx";
    var storageAccount = new CloudStorageAccount(
    new StorageCredentials(StorageAccountName, StorageAccountKey), true);

    var blobClient = storageAccount.CreateCloudBlobClient();
    var container = blobClient.GetContainerReference("tasman/Request Images");

    CloudBlockBlob blockBlob = container.GetBlockBlobReference(requestID + ".docx");

    blockBlob.UploadFromFileAsync(@"wwwroot\" + requestID + ".docx");

    return View();
}
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Tricky035
  • 107
  • 1
  • 11

1 Answers1

0

Your .SaveAs() field should be relative, currently its literally saving to wwwroot somewhere on the drive. You can specify the relative path a few different ways - one of them is below:

var saveToFolder = Path.Combine(Environment.CurrentDirectory, $"/wwwroot/{requestID}.docx");
Ben Sampica
  • 2,912
  • 1
  • 20
  • 25
  • Thanks for responding, Ben. I have implemented your suggested change however, app still works on Localhost but not in published app. i.e. doc saved to wwwroot on localhost. Everything seems to work fine on published app, however no file saved to wwwroot, no error is returned so there doesn't seem to be any clue of why. If i enter a path that the app does not have access to, access denied error is returned. But no with the modified code. – Tricky035 Jun 02 '20 at 00:28
  • What kind of published location is it? Does the application have permissions to write to its own filesystem application folder? If it's a IIS-hosted app, make sure your application pool identity has permissions to write to its own folder (if that's within your security policy). – Ben Sampica Jun 02 '20 at 00:29
  • Hi it's published on azure (sorry i am a bit of newbie to web dev). How do I give it permissions to write to its own filesystem application folder? – Tricky035 Jun 02 '20 at 00:32
  • What kind of Azure app service is it? Azure Web App? – Ben Sampica Jun 02 '20 at 00:39
  • Yes, its an Azure Web App – Tricky035 Jun 02 '20 at 01:27
  • This might interest you https://stackoverflow.com/questions/48947739/azure-app-service-write-to-filesystem-asp-net-web-application – Ben Sampica Jun 02 '20 at 01:29
  • Thanks, it appears to be saving the file here: 'D:\home\site\wwwroot\wwwroot\10944.docx'. However, the app does not appear to be closing the file to allow me to upload it to blob storage. Any idea how to regain access to the file after saving. The code has 'document.Close()' in it, thought that this would work. The error is - IOException: The process cannot access the file 'D:\home\site\wwwroot\wwwroot\10944.docx' because it is being used by another process. – Tricky035 Jun 02 '20 at 04:26
  • I don’t know what word processing document is nor the scope of the memory stream before it enters the method, but I’d look in both of those places where those are called. Check some other answers on SO and you’ll likely get it. As far as this question, seems like it’s working - glad to hear! – Ben Sampica Jun 02 '20 at 04:33
  • Thanks again for your help. I have found the solution to the doc not closing and therefore not allowing upload I deleted 'document.Close()' and modified this line as follows: document.SaveAs(Path.Combine(Environment.CurrentDirectory, $"wwwroot/" + requestID + ".docx")).Close(); – Tricky035 Jun 02 '20 at 05:01