0

The first OnGet gathers all the data and makes it available. Its is here where I set my property value also, which I thought I could reuse. The problem comes when i try to use OnGetDownload or OnGetView.

OnGet is passed an id parameter, and the later two are passed a filed parameter. The OnGet id parameter is used to setup my property public Employee Employee {get; set;}

The issue I'm having is when trying to reuse the property in either OnGetView or OnGetDownload. *yes my code needs refactoring but I'm new and learning :D

cshtml.cs


    public class IndexModel : PageModel
    {
        private readonly IConfiguration _configuration;
        private readonly ICustomer _customer;
        private readonly UserManager<IdentityUser> _userManager;

        public IndexModel(IConfiguration configuration,
            ICustomer customer, UserManager<IdentityUser> userManager)
        {
            _configuration = configuration;
            _customer = customer;
            _userManager = userManager;
        }
        

        public Employee Employee { get; set; }
        public List<AzureFileModel> AzureFileModel { get; private set; } = new List<AzureFileModel>();

        public async Task OnGetAsync(int id)
        {
            Employee = await _customer.GetEmployeeNo(id);
            var empNo = Employee.EmployeeNumber; // related table

            string fileStorageConnection = _configuration.GetValue<string>("FileStorage");
            CloudStorageAccount storageAccount = CloudStorageAccount.Parse(fileStorageConnection);
            CloudFileShare share = storageAccount.CreateCloudFileClient().GetShareReference("test");
            CloudFileDirectory root = share.GetRootDirectoryReference();
            CloudFileDirectory dir = root.GetDirectoryReference(empNo.EmployeeOnline+"/files");

           // list all files in the directory
           AzureFileModel = await ListSubDir(dir);
        }


public static async Task<List<AzureFileModel>> ListSubDir(CloudFileDirectory fileDirectory)
        {
            var fileData = new List<AzureFileModel>();

            FileContinuationToken token = null;
            do
            {
                FileResultSegment resultSegment = await fileDirectory.ListFilesAndDirectoriesSegmentedAsync(token);
                foreach (var fileItem in resultSegment.Results)
                {
                    if (fileItem is CloudFile)
                    {
                        var cloudFile = (CloudFile) fileItem;
                        //get the cloudfile's properties and metadata
                        await cloudFile.FetchAttributesAsync();

                        // Add properties to FileDataModel 
                        fileData.Add(new AzureFileModel()
                        {
                            FileName = cloudFile.Name,
                            Size = Math.Round((cloudFile.Properties.Length / 1024f), 2).ToString(),
                            DateModified = DateTime.Parse(cloudFile.Properties.LastModified.ToString()).ToLocalTime()
                                .ToString()
                        });
                    }

                    if (fileItem is CloudFileDirectory)
                    {
                        var cloudFileDirectory = (CloudFileDirectory) fileItem;
                        await cloudFileDirectory.FetchAttributesAsync();

                        //list files in the directory
                        var result = await ListSubDir(cloudFileDirectory);
                        fileData.AddRange(result);
                    }

                    // get the FileContinuationToken to check if we need to stop the loop
                    token = resultSegment.ContinuationToken;
                }
            } while (token != null);

            return fileData.OrderByDescending(o => Convert.ToDateTime(o.DateModified)).ToList();

        }

 public async Task<IActionResult> OnGetView(string fileId)
        {
            var empNo = Employee.EmployeeNumber;

            string fileStorageConnection = _configuration.GetValue<string>("FileStorage");
            CloudStorageAccount storageAccount = CloudStorageAccount.Parse(fileStorageConnection);
            CloudFileShare share = storageAccount.CreateCloudFileClient().GetShareReference("test");
            CloudFileDirectory rootDir = share.GetRootDirectoryReference();
            CloudFileDirectory dir = rootDir.GetDirectoryReference(empNo.EmployeeOnline+"/files");
            CloudFile file = dir.GetFileReference(fileId);

            try
            {
                var stream = await file.OpenReadAsync();
                return File(stream, "application/pdf");
            }
            catch (Exception ex)
            {
                throw new Exception(String.Format($"An error occurred while executing the view {ex.Message}"));
            }
            
        }

public async Task<IActionResult> OnGetDownload(string fileId)
        {
            removed for brevity

        }
}

I have tried passing in a second parameter in OnGetView(string fileId, int id) but again, I'm not able to retrieve the logged in users id to set it. What am I missing?

cshtml

@page "{id:int}"
@model NavraePortal.WebApp.Pages.Files.IndexModel
@{
    ViewData["Title"] = "Documents";
}

<h1>Pay Stub Copies</h1>
<table class="table table-bordered">
    <thead>
    <tr>
        <th>File Name</th>
        <th>File Date</th>
        <th>Download</th>
        <th>View</th>
    </tr>
    </thead>
    <tbody>
    @foreach (var data in Model.AzureFileModel)
    {
        <tr>
            <td>@data.FileName</td>
            <td>@data.DateModified</td>
            <td>
                <a class="btn btn-primary" asp-route-fileId="@data.FileName" asp-page-handler="Download">Download</a>
            </td>
            <td>
                <a class="btn btn-info" asp-route-fileId="@data.FileName" asp-page-handler="View">View</a>
            </td>
        </tr>
    }
    </tbody>
</table>
Jackdaw
  • 7,626
  • 5
  • 15
  • 33
Kent Hub
  • 139
  • 2
  • 13
  • Did you expect your Employee variable to be still valid when you click on the View or Download link? Did you try to debug the code? – Steve Nov 05 '20 at 21:58
  • I did expect it to hold the value from OnGet to OnGetView but it doesn't. When I run in debug it throws the null exception. – Kent Hub Nov 05 '20 at 22:29
  • 1
    And that's exactly how it is supposed to work. Remember you are not working with a desktop application that can maintain state between user interactions. If you put a breakpoint in the constructor you will see that it is called again and again at each click on the links. – Steve Nov 06 '20 at 08:19
  • I don't know what I did, but it works now :/ I added the `int id` to the OnGetView parameter and it populated. I did that before and nothing. So fun! – Kent Hub Nov 06 '20 at 17:26
  • Is my answer helpful? – Yiyi You Nov 09 '20 at 01:38

1 Answers1

1

You can try to use TempData,here is a demo:

cshtml.cs:

public IActionResult OnGet()
        {
            TempData["EmployeeNumber"] = "111";
            AzureFileModel = new List<AzureFileModel> { new AzureFileModel { FileName = "file1", DateModified = "sss" }, new AzureFileModel { FileName = "file2", DateModified = "ddd" } };
            return Page();
        }
        public async Task<IActionResult> OnGetView(string fileId)
        {
            
            var empNo = TempData.Peek("EmployeeNumber");
            return Page();

        }

        public async Task<IActionResult> OnGetDownload(string fileId)
        {
            var empNo = TempData.Peek("EmployeeNumber");
            return Page();
        
        }

result: enter image description here

Yiyi You
  • 16,875
  • 1
  • 10
  • 22