Non-invocable member 'File' cannot be used like a method while generating Reports
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);
}
Admin
Updated on June 07, 2022Comments
-
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, butSystem.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 about 8 yearsThanks, 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 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 about 8 yearsActually 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 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 about 8 yearsThe 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 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 theFile
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 over 3 yearsSeems 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.