Non-invocable member 'File' cannot be used like a method while generating Reports

19,227

Solution 1

System.IO.File is a static helper class for reading/writing files, you can't create an instance of a static class, so you can certainly not return it.

The File you're looking for is a method in the System.Web.MVC namespace which returns a FileContentResult, see here on msdn.

Solution 2

You may want to pass an instance of your controller to your method like this

In your controller method

   public async Task<IActionResult> GetFile()
   {
    ...
        return await _fileManager.GetFileAsync(this, "filename", mimeType);
    }

In your other class FileManager

public async Task<FileStreamResult> GetFileAsync(ControllerBase controller, string filename, string mimeType)
    {
        ...
        return controller.File(memory, mimeType, filename);
    }
Share:
19,227
Admin
Author by

Admin

Updated on June 07, 2022

Comments

  • Admin
    Admin almost 2 years

    I used a method for generating report in my previous project and tried to use the same method in the new project. However, I encounter "Non-invocable member 'File' cannot be used like a method" error and File cannot be recognized. By looking at the references of file, it seems to be FileContentResult Controller.File() in the previous project, but System.IO.File() in the new project (even if I remove using System.IO; from the references lines, I encounter "The name 'File' does not exist in the current context" error). Any idea to fix the problem?

    public static FileResult GenerateReport()
    {
        EmployeeTableAdapter ta = new EmployeeTableAdapter();
        EmployeeDS ds = new EmployeeDS();
    
        ds.Employee.Clear();
        ds.EnforceConstraints = false;
    
        ta.Fill(ds.Employee);
    
        ReportDataSource rds = new ReportDataSource();
        rds.Name = "ReportingDataSet";
        rds.Value = ds.Employee;
    
        ReportViewer rv = new Microsoft.Reporting.WebForms.ReportViewer();
        rv.ProcessingMode = ProcessingMode.Local;
        rv.LocalReport.ReportPath = System.Web.HttpContext.Current.                                 
            Server.MapPath("~/Reporting/Employee.rdlc");
        rv.LocalReport.EnableHyperlinks = true;
        rv.LocalReport.EnableExternalImages = true;
    
        // Add the new report datasource to the report.
        rv.LocalReport.DataSources.Add(rds);
        rv.LocalReport.EnableHyperlinks = true;
        rv.LocalReport.Refresh();
    
        byte[] streamBytes = null;
        string mimeType = "";
        string encoding = "";
        string filenameExtension = "";
        string[] streamids = null;
        Warning[] warnings = null;
    
        streamBytes = rv.LocalReport.Render("PDF", null, out mimeType, out 
            encoding, out filenameExtension, out streamids, out warnings);
    
        return File(streamBytes, mimeType, "Application" + "_" + ".pdf");
    }
    


    Note: I use MVC5 and SQL Server.

  • Admin
    Admin about 8 years
    Thanks, but I already use System.Web.MVC in the new project as well. But the only difference is the versions. The first one is v4.0, the latter is v5.2. Might it be the reason causing this problem?
  • Alexander Derck
    Alexander Derck about 8 years
    @hexadecimal Just noticed you don't use this in a controller, it's a method of controller so it can't exist in your current method. Can't you return the bytes or a memorystream instead and create the result in the controller?
  • Admin
    Admin about 8 years
    Actually I thought to return return the bytes or a memorystream instead and create the result in the controller, but I have not succeeded. Any sample code please by modifying my code above? Thanks...
  • Alexander Derck
    Alexander Derck about 8 years
    @hexadecimal Just do the same as you do now, and use the bytes you get from this method in the File() method. Also, don't forget to pass your mimetype
  • Admin
    Admin about 8 years
    The best thing to continue the same method inside Controller instead of in another Class I think. Will there be any problem using this report generate method in the Controller?
  • Alexander Derck
    Alexander Derck about 8 years
    @hexadecimal I wouldn't generate it in the controller to respect the single responsibility principle. Just generate the report, pass the bytes to your controller (together with mimetype out parameter) and in the controller put them in the File method. That way you can handle specific report errors in that class and connection errors/bad requests in the controller like you're supposed to :)
  • Slagmoth
    Slagmoth over 3 years
    Seems I am missing something. I have mine in a controller have System.IO.File for the stream and System.Web.Mvc 5.2 in a 4.7.2 application. But I still get that error even bringing back the byte[] from the service layer.