0

Hello Stackoverflow community,

I am getting following error message while downloading a file from Web API Controller.

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

This is my database table:

CREATE TABLE [cafe].[t06_03_02_jobAttachments](
[ID] [int] IDENTITY(1,1) NOT NULL,
[jobAttachmentId] [int] NOT NULL,
[jobId] [int] NOT NULL,
[file] [varbinary](max) NOT NULL,
[name] [varchar](100) NOT NULL,
[fileExtension] [varchar](10) NOT NULL,
[contentType] [varchar](50) NOT NULL,
[fileSize] [int] NOT NULL
) ON [PRIMARY]

enter image description here

This is my Data Model:

namespace api.Models.Jobs
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.Spatial;

[Table("cafe.t06_03_02_jobAttachments")]
public partial class t06_03_02_jobAttachments
{
    public int ID { get; set; }

    public int jobAttachmentId { get; set; }

    public int jobId { get; set; }

    [Required]
    public byte[] file { get; set; }

    [Required]
    [StringLength(100)]
    public string name { get; set; }

    [Required]
    [StringLength(10)]
    public string fileExtension { get; set; }

    [Required]
    [StringLength(50)]
    public string contentType { get; set; }

    public int fileSize { get; set; }

 }
}

Here is my controller code:

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Http;
using System.Web.Http.Description;
using api.Models;
using api.Models.Jobs;
using System.Data.SqlClient;
using System.Text;
using System.IO;
using System.Web.Mvc;

namespace api.Controllers.jobs
{
 public class JobsController : ApiController
 {
    [HttpGet]
    [ResponseType(typeof(t06_03_02_jobAttachments))]
    public async Task<IHttpActionResult> Gett06_03_02_jobAttachments(int id)
    {
      t06_03_02_jobAttachments t06_03_02_jobAttachments = await db.t06_03_02_jobAttachments.FindAsync(id);
        if (t06_03_02_jobAttachments == null)
        {
            return NotFound();
        }
        return File(t06_03_02_jobAttachments.file, t06_03_02_jobAttachments.contentType, t06_03_02_jobAttachments.name);
    }
 }
}

I am getting this error on my controller when I try to return File as a text file. All I want to do is read the file (saved as Byte array in database) and return it to my Angular application. I have tried multiple solutions posted online but non of them helped me. I would appreciate any help I receive from this blog. I am using .NET Framework 4.6.1 and MVC 5.2.7. Thanks

Faisal Mehboob
  • 609
  • 7
  • 17
  • 4
    `ApiController` doesn't have a `File` method. You're attempting to use the `System.IO.File` type as a method. – madreflection Oct 14 '19 at 21:48
  • Types are not methods. Types often contain methods, fields and/or properties. As there is no "File" method anywhere in the code you posted, wich one did you try to call? – Christopher Oct 14 '19 at 21:53
  • 1
    By the looks of it, OP intended to call the `File` method from MVC's `Controller` class. – madreflection Oct 14 '19 at 21:55
  • @madreflection but it is also possible that he wanted to create a new instance of a class called "File". With this level of mistake (basic Syntax/function calls), I try not to asume anything. So I thought it better to ask. – Christopher Oct 14 '19 at 21:56
  • I seriously doubt that was the intention. That return statement is exactly what you would do with an MVC controller's action method. Same parameters (stream/byte[], content type, suggested name), no `new` keyword. Fair point about not assuming anything, though. – madreflection Oct 14 '19 at 21:58
  • @Christopher I am calling File method from MVC Controller class. – Faisal Mehboob Oct 14 '19 at 22:05
  • 1
    No, you're not. Your controller inherits from `System.Web.Http.ApiController` (Web API), not `System.Web.Mvc.Controller` (MVC). – madreflection Oct 14 '19 at 22:06
  • @madreflection when I call File function like this: System.Web.Mvc.Controller.File() - I get Controller.File() is inaccessible due to its protection level. What should I do? – Faisal Mehboob Oct 14 '19 at 22:10
  • 1
    https://stackoverflow.com/questions/9541351/returning-binary-file-from-controller-in-asp-net-web-api is what you're looking for. – howcheng Oct 14 '19 at 22:15

1 Answers1

1

I made a FileResult class that you can use to return your binary content.

public class FileResult : IHttpActionResult
{
    private byte[] _content;
    private string _contentType;
    public FileResult(byte[] content, string contentType)
    {
        _content = content;
        _contentType = contentType;
    }

    public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        if (cancellationToken.IsCancellationRequested)
            return null;

        // per https://stackoverflow.com/questions/9541351/returning-binary-file-from-controller-in-asp-net-web-api do not wrap this in a using block
        System.IO.MemoryStream stream = new System.IO.MemoryStream(_content);
        stream.Seek(0, System.IO.SeekOrigin.Begin);
        HttpResponseMessage response = new HttpResponseMessage(System.Net.HttpStatusCode.OK);
        response.Content = new StreamContent(stream);
        response.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(_contentType);
        return Task.FromResult(response);
    }
}
howcheng
  • 2,211
  • 2
  • 17
  • 24