0

I am a beginner in ASP.Net MVC 5 and I want to know how to upload file in database and the display them to the user. I saw numerous example on internet related to above question. But all talks about putting file in some solution folder. But I want to upload file to database and be able to retrieve it in "Details View".

Issue: I am able to upload file in Database, but I am not sure how to Display the file link to user. Clicking on which user should be able to view/download the uploaded file. Below is my attempt.

Model:

public class File
{
    public int Id { get; set; }
    [StringLength(255)]
    public string FileName { get; set; }
    public byte[] Content { get; set; }
}

Controller:

// GET: FileUpload
public ActionResult Create()
{
    return View();
}

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(File file, HttpPostedFileBase upload)
{
    try
    {
        if (ModelState.IsValid)
        {
            if (upload != null && upload.ContentLength > 0)
            {
                var tempfile = new File
                {
                    FileName = System.IO.Path.GetFileName(upload.FileName),
                };
                using (var reader = new System.IO.BinaryReader(upload.InputStream))
                {
                    tempfile.Content = reader.ReadBytes(upload.ContentLength);
                }
                file.Content = tempfile.Content;
            }
            _context.Files.Add(file);
            _context.SaveChanges();
            return RedirectToAction("Index");
        }
    }
    catch (RetryLimitExceededException /* dex */)
    {
        //Log the error (uncomment dex variable name and add a line here to write a log.
        ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists see your system administrator.");
    }
    return View(file);
}

public ActionResult Details(int? id)
{
    if (id == null)
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }
    File f1 = _context.Files.Where(f => f.Id == id).SingleOrDefault();
    if (f1 == null)
    {
        return HttpNotFound();
    }
// NOT SURE WHAT TO HERE
    return View(f1);
}

View: Details.chtml file

@model fileupload.Models.File
<h4>File</h4>
@* NOT SURE HOW TO HANDLE THE FILE LINK HERE*@

So, In the database I can see some binary content entry in "Content" Column. But I am not sure how can I display some link in the detail section. I want to display the file link in the details view. Clicking on which the file will get downloaded or something like preview. Kindly guide me.

EDIT 1

public FileContentResult Download(int id)
{
    var file = _context.Files.First(f => f.Id == id);
    var fileRes = new FileContentResult(file.Content.ToArray(), "application/pdf");
    fileRes.FileDownloadName = file.FileName;
    return fileRes;
}
9
  • So you have an existing detail view? You just need to replace each entries to a URL that allows you to download your file. I'm guessing that would be a URL to another action method Commented Aug 6, 2017 at 22:42
  • I got the content in Binary format in the details controller action. Now what next. I mean I need to provide a link in the details section. If that link is clicked then the file should either get downloaded. If nothing, then as I have the binary formatted file in details controller action. How can I show/render it in Details View. Commented Aug 6, 2017 at 22:44
  • Even if it will be another URL Action method. How can I allow downloading on button click. I am newbie. Kindly guide me. Commented Aug 6, 2017 at 22:46
  • If any more clarity is required about my question. Kindly ask me. Commented Aug 6, 2017 at 22:53
  • Sorry I named it wrong - do you have an existing index view? You need to alter that so that instead of going to a detail view, it calls a controller action that downloads the file. This page has some code that has an example of a controller that downloads a file from a database. Each line of your index page has the correct link (i.e. passes in the correct id) to this controller. forums.asp.net/t/… Commented Aug 6, 2017 at 23:07

2 Answers 2

0

Assuming your code in your controller is correctly populating your model, you simply need base64 encode the image and display that.

@{
    var encodedImage = Convert.ToBase64String(Model.Content);
    var embeddedImage = $"data:image/png;base64,{encodedImage}";
}

<img src="@embeddedImage" />

Take a look at this question as well: MVC How to display a byte array image from model

Sign up to request clarification or add additional context in comments.

Comments

0

Add below code in model :

            public string imagePath { get; set; }

            [Display(Description = "imgfile")]
            [RegularExpression(@"([a-zA-Z0-9()\s_\\.\-:!@#$%^&])+(.png|.jpg|.gif|.bmp|.tiff|.PNG|.JPG|.GIF|.BMP|.TIFF)$", ErrorMessage = "Only Image files allowed.")]
            public HttpPostedFileBase imgfile { get; set; }

In controller (This will validate your image for maore than 1mb from your action, if u want to validate it before post you can google it for jquery validations) :

if (userRegObj != null && userRegObj.imgfile != null && userRegObj.imgfile.FileName != null && userRegObj.imgfile.ContentLength > 1024000)//1 MB
                    {
                        TempData["msg"] = "danger~Profile Picture Should be Less Than 1 MB";
                        if (userRegObj.Id <= 0)
                        {
                            return View(userRegObj);
                        }
                        return RedirectToAction("Action", "Controller", new { id = userRegObj.Id });
                    }



                    else if (userRegObj != null && userRegObj.imgfile != null && userRegObj.imgfile.FileName != null)
                    {
                        string path = Path.Combine(Server.MapPath("~/Media/ProfilePics"), Path.GetFileName(userRegObj.imgfile.FileName)); // folder to save images
                        userRegObj.imagePath = Path.GetFileName(userRegObj.imgfile.FileName);
                        userRegObj.imgfile.SaveAs(path);
                    }

In view (This code will help you if your model having an image then it will show the image in the upload section else it will show a default image as you want to manage yourself) :

@if (Model != null && Model.Id>0 &&Model.imagePath!=null)
                                        {
                                            <div class="form-group">
                                                <label for="exampleInputEmail1">Upload Your Image:<br /><small>(Width:155, Height:155)</small></label>
                                                <span class="imageupld">
                                                    <img src="@Url.Content("~/Media/ProfilePics/"+Model.imagePath)" alt="obsequium" id="profilepic"  style="margin-top:8.5px" />
                                                </span>
                                                <span class="file-up" style="overflow:hidden;">
                                                    <span class="pic" id="p">@Model.imagePath</span>
                                                    @Html.TextBoxFor(m => m.imgfile, new { @class = "profilepic", type = "file", data_value = "pic", tabindex = 17, accept = "image/*", id = "picVal", @onchange = "checkImage()" })
                                                    @Html.ValidationMessageFor(m => m.imgfile, "", new { @class = "text-red", id = "imgVal" })
                                                </span>
                                            </div>
                                        }
                                        else if (Model != null && Model.Id>0 && Model.imagePath == null )
                                        {
                                        <div class="form-group">
                                            <label for="exampleInputEmail1">Upload Your Image:<br /><small>(Width:155, Height:155)</small></label>
                                            <span class="imageupld">
                                                <img src="@Url.Content("~/Content/Template/")images/imgupload.png" alt="obsequium" id="profilepic" style="margin-top:8.5px">
                                            </span>
                                            <span class="file-up" style="overflow:hidden;">
                                                <span class="pic">Upload Image</span>
                                                @Html.TextBoxFor(m => m.imgfile, new { @class = "profilepic", type = "file", data_value = "pic", tabindex = 17, accept = "image/*", id = "picVal", @onchange = "checkImage()" })
                                                @Html.ValidationMessageFor(m => m.imgfile, "", new { @class = "text-red", id = "imgVal" })
                                            </span>
                                        </div>
                                    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.