Multiple constructors accepting all given argument types have been found in type 'System.Collections.Generic.List`1[Portal.Models.FileDataModel]'

Viewed 1979

I'm using ASP.NET Core 3.1 with EF Core and Azure Storage (File Storage). I am using Microsoft.Azure.Storage.File version 11.2.2 for the Azure Storage file handling.

I'm not sure exactly what this error is referencing other than a Dependency Injection (DI) issue?

Most of the articles or SO articles that I've come across referencing this error message suggest a DI, but when they inject it in Startup.cs, they have an Interface to accompany their injection. I do not.

I'm using a Razor page for this view. This code was previously written for an MVC view that I'm trying to convert for cohesion. See original post HERE. The project in MVC works without any issues. Should I just give up trying to do this all in Razor pages and use MVC for my entire project or is there an obvious issue I'm missing??

Here is my setup:

namespace AzureFileShare.Pages.Files
{
    public class IndexModel : PageModel
    {
        private readonly IConfiguration _configuration;

        public IndexModel(
            IConfiguration configuration)
        {
            _configuration = configuration;
            
        }
        public async Task<IList<FileModel>> OnGetAsync()
        {
            string fileStorageConnection = _configuration.GetValue<string>("fileStorageConnection");
            CloudStorageAccount storageAccount = CloudStorageAccount.Parse(fileStorageConnection);
            CloudFileShare share = storageAccount.CreateCloudFileClient().GetShareReference("payreports");
            CloudFileDirectory root = share.GetRootDirectoryReference();
            CloudFileDirectory dir = root.GetDirectoryReference(@"E000002/stubs");

            // list all files in the directory
            var fileData =  await list_subDir(dir);
            return fileData;

        }
        
        public static async Task<List<FileModel>> list_subDir(CloudFileDirectory fileDirectory)
        {
            var fileData = new List<FileModel>();
           
            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 FileModel()
                        {
                            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 list_subDir(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();
            
        }
    }
}

Model

    public class FileModel
    {
        public string FileName { get; set; }
        public string Size { get; set; }
        public string DateModified { get; set; }
    }

appsettings.json

{
  "ConnectionStrings": {
    "fileStorageConnection": "DefaultEndpointsProtocol=https;AccountName=navraereports;AccountKey=REMOVEDFORPUBLIC;EndpointSuffix=core.windows.net"
  }

}
@page
@model List<FileModel>

@{
    ViewData["Title"] = "Download Pay Stub Copies";
}

<h1>Pay Stub Copies</h1>
<table class="table table-bordered">
    <thead>
        <tr>
            <th>File Name</th>
            <th>File Size</th>
            <th>File Date</th>
            <th>Download</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var data in Model)
        {
            <tr>
                <td>@data.FileName</td>
                <td>@data.Size</td>
                <td>@data.DateModified</td>
                <td>
                    <a class="btn btn-primary"
                       href="/File/DownloadStub?id=@data.FileName">Download</a>
                </td>
            </tr>
        }
    </tbody>
</table>

Stack Trace:

System.InvalidOperationException: Multiple constructors accepting all given argument types have been found in type 'System.Collections.Generic.List`1[AzureFileShare.FileModel]'. There should only be one applicable constructor.
   at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.TryFindMatchingConstructor(Type instanceType, Type[] argumentTypes, ConstructorInfo& matchingConstructor, Nullable`1[]& parameterMap)
   at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.FindApplicableConstructor(Type instanceType, Type[] argumentTypes, ConstructorInfo& matchingConstructor, Nullable`1[]& parameterMap)
   at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.CreateFactory(Type instanceType, Type[] argumentTypes)
   at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.DefaultPageModelActivatorProvider.CreateActivator(CompiledPageActionDescriptor actionDescriptor)
   at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.DefaultPageModelFactoryProvider.CreateModelFactory(CompiledPageActionDescriptor descriptor)
   at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvokerProvider.CreateCacheEntry(ActionInvokerProviderContext context, FilterItem[] cachedFilters)
   at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvokerProvider.OnProvidersExecuting(ActionInvokerProviderContext context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionInvokerFactory.CreateInvoker(ActionContext actionContext)
   at Microsoft.AspNetCore.Mvc.Routing.ActionEndpointFactory.<>c__DisplayClass7_0.<CreateRequestDelegate>b__0(HttpContext context)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke(HttpContext httpContext)
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
1 Answers

UPDATE

In Razor view, replace

@model List<FileModel>

with

@model AzureFileShare.Pages.Files.IndexModel 

In IndexModel.cshtml.cs you'll need a new property for the result

public List<FileModel> FileModels { get; private set; } = new List<FileModel>();

In addition to change of signature, you'll need some changes inside method as well.

public async Task OnGetAsync()
    {
        string fileStorageConnection = _configuration.GetValue<string>("fileStorageConnection");
        CloudStorageAccount storageAccount = CloudStorageAccount.Parse(fileStorageConnection);
        CloudFileShare share = storageAccount.CreateCloudFileClient().GetShareReference("payreports");
        CloudFileDirectory root = share.GetRootDirectoryReference();
        CloudFileDirectory dir = root.GetDirectoryReference(@"E000002/stubs");

        // list all files in the directory
        FileModels = await list_subDir(dir);
    }

Finally, go back to Razor view and change

@foreach (var data in Model)

witn

@foreach (var data in Model.FileModels)

Please try replacing

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

with

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

and remove

return fileData;

from the line right below.

You should also replace

Stream fileStream = file.OpenReadAsync().Result;

with

Stream fileStream = await file.OpenReadAsync();

Replace

await file.DownloadToStreamAsync(memoryStream);

with

await file.DownloadToStreamAsync(new MemoryStream());

and remove

MemoryStream memoryStream = new MemoryStream();
Related