-1

How can I download a file from db and not from a certain path? I'm uploading a file this way:

[HttpPost, ActionName("CandidateCreate")]
    [ValidateAntiForgeryToken]
    public  IActionResult CandidateCreatePost([Bind("Name,Number,Profile,CV,CVID")] Candidate candidate, IFormFile CV)
    {
        if (ModelState.IsValid)
        {
            if (CV != null)
            {
                if (CV.Length > 0)
                {
                    byte[] p1 = null;
                    using (var fs1 = CV.OpenReadStream())
                    using (var ms1 = new MemoryStream())
                    {
                        fs1.CopyTo(ms1);
                        p1 = ms1.ToArray();

                    }
                    candidate.CVNAME = CV.FileName;
                    candidate.CV = p1;
                    }
                }
            using (var applicationContext = new ApplicationContext())
            {
                candidateRepository.Add(candidate);
                 candidateRepository.SaveChanges();

                return RedirectToAction("Candidate");
            }
        }
        return View();
    }

Everything I could find about downloading is only with path's

**EDIT1 **

I have tried this:

        public async Task<IActionResult> Download(string filename, Candidate candidate, IFormFile CV)
    {
        filename = candidate.Name;
        if (filename == null)
            return Content("filename not present");

        var path = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", filename);

        var memory = new MemoryStream();
        using (var stream = new FileStream(path, FileMode.Open))
        {
            await stream.CopyToAsync(memory);
        }
        memory.Position = 0;
        return File(memory, GetContentType(path), Path.GetFileName(path));
    }
    private string GetContentType(string path)
    {
        var types = GetMimeTypes();
        var ext = Path.GetExtension(path).ToLowerInvariant();
        return types[ext];
    }

    private Dictionary<string, string> GetMimeTypes()
    {
        return new Dictionary<string, string>
        {
            {".pdf", "application/pdf"},
            {".doc", "application/vnd.ms-word"},
            {".docx", "application/vnd.ms-word"}
        };
    }

I'm getting an error because this is using paths... I need something without the path atribute( I think)

Dorin Munteanu
  • 93
  • 1
  • 1
  • 10
  • There is a `File` method on the controller that will accept a `stream`, `byte[]` or `path` to download a file to the browser – Simply Ged Jun 21 '18 at 10:56
  • Instead of actionResult? @SimplyGed – Dorin Munteanu Jun 21 '18 at 10:58
  • No. IActionResult is fine. You would need to call `File(...)` instead of `View()`. e.g. `return File(p1, "application/octetstream", CV.Filename)` – Simply Ged Jun 21 '18 at 11:13
  • See answers to [this question](https://stackoverflow.com/questions/5826649/returning-a-file-to-view-download-in-asp-net-mvc) for an example – Simply Ged Jun 21 '18 at 11:14
  • Possible duplicate of [Returning a file to View/Download in ASP.NET MVC](https://stackoverflow.com/questions/5826649/returning-a-file-to-view-download-in-asp-net-mvc) – Simply Ged Jun 21 '18 at 11:14
  • @SimplyGed can you make an sample for me to test? bc I tried what is posted On the other question and cant make it work – Dorin Munteanu Jun 21 '18 at 11:35
  • @DorinMunteanu: That's on *you* as part of constructing a good quality question. If you've already tried something, you should post the code for what you tried and explicitly explain what didn't "work" about it: exceptions you may have received, along with stacktrace, detail of what occurred, etc. – Chris Pratt Jun 21 '18 at 12:56
  • @ChrisPratt I have edited my question – Dorin Munteanu Jun 21 '18 at 13:52
  • You edited question, but you haven't explained what's not working. Try using [Fiddler](https://www.telerik.com/fiddler) to see what the response contains. – Mark G Jun 21 '18 at 17:20

2 Answers2

1

You don't reveal anything about your ApplicationContext or your Candidate class so I'm going to have to guess what you have there. But you need to retrieve the record from the database and, based on what is in the question, you store the file as a byte[].

I will assume your ApplicationContext looks like this:

public class ApplicationContext : DbContext
{
    public ApplicationContext(DbContextOptions options) : base(options)
    {
    }

    protected ApplicationContext()
    {
    }

    public DbSet<Candidate> Candidates { get; set; }
}

Based on that assumption you can retrieve the record from the database using the ApplicationContext class and use the Candidate.CV as a byte[] for the File method.

public async Task<IActionResult> Download(Candidate candidate)
{
    var candidate = _applicationContext.Candidates.SingleOrDefault(c => c.CVNAME == candidate.CVNAME);

    return File(candidate.CV, GetContentType(path), Path.GetFileName(candidate.CVNAME));
}
private string GetContentType(string path)
{
    var types = GetMimeTypes();
    var ext = Path.GetExtension(path).ToLowerInvariant();
    return types[ext];
}

private Dictionary<string, string> GetMimeTypes()
{
    return new Dictionary<string, string>
    {
        {".pdf", "application/pdf"},
        {".doc", "application/vnd.ms-word"},
        {".docx", "application/vnd.ms-word"}
    };
}

NOTE: There is no error checking in the example so you will have to add your some to make sure you have valid CV. I would also recommend reading up on how to use the DbContext class to retrieve your data from the database.

Simply Ged
  • 8,250
  • 11
  • 32
  • 40
  • I'm getting an error on `return File(candidate.CV, GetContentType(path), Path.GetFileName(candidate.CVNAME));`"The name 'path' does not exist in the current context. This error doesn't make sesne since it's exist in the GetContentType – Dorin Munteanu Jun 22 '18 at 08:43
  • Change the `path` parameter to `candidate.CVNAME` – Simply Ged Jun 23 '18 at 07:58
0

I have managed to make this work this way:

  public IActionResult Download(Candidate candidate)
    {
        var applicationcontext = new ApplicationContext();
            var candidate1 = applicationcontext.Candidates.SingleOrDefault(c => c.CVNAME== candidate.CVNAME);
        var contentType = "APPLICATION/octet-stream";
        var filename = candidate1.CVNAME;
        return File(candidate1.CV, contentType, filename);
    }
Dorin Munteanu
  • 93
  • 1
  • 1
  • 10
  • FWIW, you can get MIME type from just the [filename](https://stackoverflow.com/questions/34131326/using-mimemapping-in-asp-net-5-vnext/35880687#35880687). – Mark G Jun 22 '18 at 16:22