0

Hi, I have been learning ASP.NET as well as doing a small project through MVC application. My application is based on raising a purchase request for a product by an institution. It's a basic form through which all data are stored in DB. How to add upload PDF or DOC into this coding so that the pdf quotation can be uploaded while submitting the form.

**

  1. My Model

**

namespace sparki02.Models{
public class PRview
{
    public int Id { get; set; }
    [DataType(DataType.Html)]
    public string Caption { get; set; }
    [Required]
    [DataType(DataType.ImageUrl)]
    public string ImageUrl { get; set; }
    [Required]
    [StringLength(100)]
    [Display(Name = "Supplier Name")]
    public string SupplierName { get; set; }
    [Required]
    [StringLength(255)]
    [Display(Name = "Material Name")]
    public string MATName { get; set; }
    [Required]
    [StringLength(100)]
    public string Brand { get; set; }
    public PRtype PRtype { get; set; }
    [Display(Name = "PR Type")]
    public byte PRtypeId { get; set; }
    [Required]
    [Display(Name = "Unit Price")]
    public double Unitprice { get; set; }}}

**

2. Controller

**

    public ActionResult NewPR()
    {var prtypes = _context.PRtypes.ToList();
     var viewModel = new NewPRViewModel
    {PRview = new PRview(), 
     PRtypes = prtypes};

    return View("NewPR", viewModel);
    }

    [HttpPost]
    public ActionResult Save(PRview prview, NewPRViewModel model)
    {

        var validImageTypes = new string[]
        {
            "image/gif",
            "image/jpeg",
            "image/pjpeg",
            "image/png"
        };

        if (model.ImageUpload == null || model.ImageUpload.ContentLength == 0)
        {
            ModelState.AddModelError("ImageUpload", "This field is required");
        }
        else if (validImageTypes.Contains(model.ImageUpload.ContentType))
        {
            ModelState.AddModelError("ImageUpload", "Please choose either a GIF, JPG or PNG image.");
        }



        if (!ModelState.IsValid)
        {
            var viewModel = new NewPRViewModel
            {
                PRview = prview, 
                PRtypes = _context.PRtypes.ToList(),
                Caption = model.Caption
            };


            return View("NewPR", viewModel);
        }

        if (prview.Id == 0)
            _context.PRviews.Add(prview);

        else
        {

            var prviewInDb = _context.PRviews.Single(c => c.Id == prview.Id);

            prviewInDb.PRtypeId = prview.PRtypeId; 
            prviewInDb.MATName = prview.MATName;
            prviewInDb.SupplierName = prview.SupplierName;
            prviewInDb.Brand = prview.Brand;
            prviewInDb.Unitprice = prview.Unitprice;
            prviewInDb.ImageUrl = prview.ImageUrl;

            if (model.ImageUpload != null && model.ImageUpload.ContentLength > 0)
            {
                var uploadDir = "~/uploads";
                var imagePath = Path.Combine(Server.MapPath(uploadDir), model.ImageUpload.FileName);
                var imageUrl = Path.Combine(uploadDir, model.ImageUpload.FileName);
                model.ImageUpload.SaveAs(imagePath);
                prview.ImageUrl = imageUrl;

            }

        }

        _context.SaveChanges();
        return RedirectToAction("Index", "PRview");

**

  1. My View block

** Only content related to file upload

{ @model sparki02.ViewModels.NewPRViewModel
  @using (Html.BeginForm("Save", "PRview", FormMethod.Post, new { enctype =    "multipart/form-data" }))
{@Html.ValidationSummary(true, "Please fix the following errors.")
<div>
    @Html.LabelFor(m => m.Caption)
    @Html.EditorFor(m => m.Caption)
</div>
<div>
    @Html.LabelFor(m => m.ImageUpload)
    @Html.TextBoxFor(m => m.ImageUpload, new { type = "file" })
</div>
<button type="submit">Create</button>

    <div class="form-group">
        <button type="submit" class="btn btn-primary">Save</button>
    </div>
    <div class="form-group"> <p> @DateTime.Now</p> </div>

}

  • There are many many tutorials online which cover uploading documents from an MVC form...have you researched or tried anything? I don't see any file upload control in your form, and I don't see any code to save it into the database. Both of those things you can research. You've already set up some of the correct things, like the enctype, and having the HttpPostedFileBase parameter, you just haven't finished the job. If you're stuck on a specific issue, explain what you tried and what goes wrong, rather than just saying "I'd like to do X"... – ADyson May 30 '18 at 19:59
  • @ADyson: I had previously tried adding byte[] file upload through which it saves to DB [Uploading Files into Database with ASP.NET MVC](https://stackoverflow.com/questions/15106190/uploading-files-into-database-with-asp-net-mvc) it didn't go well. The file gets uploaded shows message success but never saves in DB. Then tried saving it in the server using HttpPostedFileBase but it doesn't save in server location. –  May 31 '18 at 03:32
  • " it doesn't save in server location" because you haven't written any code to do it...you need to extract a byte array from the file and add them to your EF database object. But equally you can easily make your file part of your viewmodel instead of being a separate parameter to the action method - see this blog: https://cpratt.co/file-uploads-in-asp-net-mvc-with-view-models/ (make sure you read all the way to the end) – ADyson May 31 '18 at 08:18
  • @ADyson I had tried byte[] method and HttpPostedFileBase. As it didn't turn out well removed its code. Will try this link, Thank you. –  May 31 '18 at 11:25
  • @ADyson I followed the link [cpratt.co/file-uploads-in-asp-net-mvc-with-view-models] but still, I am unsuccessful getting it working. When I click create it shows no file selected. here is code for MyController kindly advise for any changes to be made. 'code' –  May 31 '18 at 13:40
  • please edit the question to show all your latest view, model and controller code in line with that article. – ADyson May 31 '18 at 13:44
  • @ADyson Kindly find the latest view, model and controller code. Thanks in advance. –  May 31 '18 at 14:08
  • where is the code for NewPRViewModel please? You're still showing your old PrView code, but you're not using that any more. – ADyson May 31 '18 at 14:10
  • Also `public ActionResult Save(PRview prview, NewPRViewModel model)` makes no sense...you need to remove the `PRview prview` from it, as the form isn't submitting that data. Either that or actually the fields you've put into NewPRViewModel should just have been added to PRView. Having two viewmodels for a single view makes no sense. – ADyson May 31 '18 at 14:11

1 Answers1

0

Whereas it is non-trivial to Download or View PDFs, it is relatively trivial to upload them. I used https://learn.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads?view=aspnetcore-2.2 as mentioned by ADyson, but only about 5% of the code is really necessary.

In your CSHTML, you must add a Form File:

<input type="file" class="custom-control-input" tabindex="0" asp-for="FileUpload.FormFile">
                                                            <label asp-for="FileUpload.FormFile" class="custom-control-label">Upload Form</label>

Your form must include

enctype="multipart/form-data"

Your class must include:

    [Required]
    [BindProperty]
    public BufferedSingleFileUploadDb FileUpload { get; set; }


}

public class BufferedSingleFileUploadDb
{
    [Required]
    [Display(Name = "File")]
    public IFormFile FormFile { get; set; }
}

And in your Controller, here's some code that will work, although I commented out Microsoft's AppFile suggestion. You can save the file to a filesystem, database, etc.:

        [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> OrderEquipmentAsync(OrderEquipmentGroup orderEquipGroup)
    {
        if (ModelState.IsValid)
        {
            // save stuff here.
            using (var memoryStream = new MemoryStream())
            {
                await orderEquipGroup.FileUpload.FormFile.CopyToAsync(memoryStream);

                // Upload the file if less than 2 MB
                if (memoryStream.Length < 2097152)
                {
                    //var file = new AppFile()
                    //{
                    //    Content = memoryStream.ToArray()
                    //};

                    //_dbContext.File.Add(file);

                    //await _dbContext.SaveChangesAsync();
                }
                else
                {
                    ModelState.AddModelError("File", "The file is too large.");
                }
            }

My last suggestion is that you be VERY careful when uploading files to a server. As Microsoft says in their article, here are some wise guidelines: 1. use a safe filename, 2. allow only approved file extensions, 3. limit the filesize, 4. Scan the uploaded file before saving.