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

3

10

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.

Daladier answered 11/3, 2016 at 9:37 Comment(0)
D
9

Moving the method to the Controller solved the problem. Thanks a lot @AlexanderDerck for your help.

Daladier answered 16/3, 2016 at 15:40 Comment(0)
T
6

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.

Telamon answered 11/3, 2016 at 10:2 Comment(7)
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?Daladier
@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?Telamon
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...Daladier
@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 mimetypeTelamon
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?Daladier
@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 :)Telamon
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.Withdrew
C
3

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);
    }
Catalogue answered 16/5, 2018 at 23:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.