locked
ASP.Net MVC 5 - Upload Image & PDF, Save to Database & Save to Database to selected value in my dropdownlist RRS feed

  • Question

  • User-1917797656 posted

    Just like the title say, I am building an Library. After many hours of googling and trial and error, I have finally accomplished the task of uploading image, saving to database, creating a thumbnail and showing in View. I am looking for uploading a second file *PDF with a second input to another path

    First the Create View

    @using (Html.BeginForm("Create", "Document", null, FormMethod.Post, new { enctype = "multipart/form-data" }))
            {
                @Html.AntiForgeryToken()
    
                <div class="form-horizontal">
    
                    <hr />
                    @Html.ValidationSummary(true, "", new { @class = "text-danger" })
                    <div class="form-group">
                        @Html.LabelFor(model => model.Titre, htmlAttributes: new { @class = "control-label col-md-2" })
                        <div class="col-md-10">
                            @Html.EditorFor(model => model.Titre, new { htmlAttributes = new { @class = "form-control" } })
                            @Html.ValidationMessageFor(model => model.Titre, "", new { @class = "text-danger" })
                        </div>
                    </div>
    
                    <div class="form-group">
                        @Html.LabelFor(model => model.Description, htmlAttributes: new { @class = "control-label col-md-2" })
                        <div class="col-md-10">
                            @Html.EditorFor(model => model.Description, new { htmlAttributes = new { @class = "form-control" } })
                            @Html.ValidationMessageFor(model => model.Description, "", new { @class = "text-danger" })
                        </div>
                    </div>
                    <div class="form-group">
                        @Html.LabelFor(model => model.Type, htmlAttributes: new { @class = "control-label col-md-2" })
                        <div class="col-md-10">
                            @Html.DropDownList("TypeList", (IEnumerable<SelectListItem>)ViewBag.TypeList, "Select Type", new { @class = "form-control" })
                            @Html.ValidationMessageFor(model => model.Type, "", new { @class = "text-danger" })
                        </div>
                    </div>
    
                    <div class="form-group">
                        @Html.LabelFor(model => model.Image, htmlAttributes: new { @class = "control-label col-md-2" })
                        <div class="col-md-10">
                            <input type="file" class="form-control" name="file" accept="image/png,image/jpg,image/jpeg" />
                            @Html.ValidationMessageFor(model => model.Image, "", new { @class = "text-danger" })
                        </div>
                    </div>
    
                    <div class="form-group">
                        @Html.LabelFor(model => model.Pdf, htmlAttributes: new { @class = "control-label col-md-2" })
                        <div class="col-md-10">
                            <input type="file" class="form-control" accept=".pdf" />
                            @Html.ValidationMessageFor(model => model.Pdf, "", new { @class = "text-danger" })
                        </div>
                    </div>
    
    
                    <div class="form-group">
                        <div class="col-md-offset-2 col-md-10">
                            <input type="submit" value="Create" name="file" class="btn btn-default" />
                        </div>
                    </div>
                </div>
            }

    Then the Controller Create Action

    [HttpPost]
            [ValidateAntiForgeryToken]
            public ActionResult Create([Bind(Include = "IdDoc,Titre,Description,Image,Pdf")] Document document, HttpPostedFileBase file)
            //public ActionResult Create(Document document, HttpPostedFileBase file)
            {
                ViewBag.TypeList = new SelectList(db.Types, "IdType", "Label");
                if (ModelState.IsValid)
                {
                    string path = Path.Combine(Server.MapPath("~/Content/ImageUploaded/"), Path.GetFileName(file.FileName));
                    file.SaveAs(path);
                    db.Documents.Add(new Document
                    {
                        IdDoc = document.IdDoc, Titre = document.Titre, Description = document.Description, Image = file.FileName
    
    
                    });
                    //db.Documents.Add(document);
                    db.SaveChanges();
                    return RedirectToAction("Index");
                } 
    
                return View(document);
            }

    And my two classes

    [Table("Document")]
        public class Document
            {
    
                [Key]
                public int IdDoc { get; set; }
                public string Titre { get; set; }
                public string Description { get; set; }
                public virtual string Image { get; set; }
                public virtual string Pdf { get; set; }
                public virtual Type Type { get; set; }
           
            }
     [Table("Type")]
        public class Type
        {
            [Key]
            public int IdType { get; set; }
            public string Label { get; set; }
            public ICollection<Document> Documents { get; set; }
    
        }

    For now as i said, i only can upload the first input for picture, but not the second input for a pdf files and not the selected value in the dropdownlist ..

    Thanks

    Tuesday, January 15, 2019 2:24 PM

Answers

  • User1520731567 posted

    Hi khalilbnzz,

    According to your code,I suggest you could add ForeignKey in model,like:

        [Table("Document")]
        public class Document
        {
            [Key]
            public int IdDoc { get; set; }
            public string Titre { get; set; }
            public string Description { get; set; }
            public virtual string Image { get; set; }
            public virtual string Pdf { get; set; }
            public int IdType { get; set; }
            [ForeignKey("IdType")]
            public virtual Type Type { get; set; }
        }

    And modify the DropDownList to:

    @Html.DropDownListFor(model => model.Type.IdType, (IEnumerable<SelectListItem>)ViewBag.TypeList, "Select Type", new { @class = "form-control" })
    

    How it works in my project:

    Best Regards.

    Yuki Tao

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, January 16, 2019 10:24 AM
  • User1520731567 posted

    Hi khalilbnzz,

    The INSERT statement conflicts with the FOREIGN KEY constraint "FK_dbo.Document_dbo.Type_IdType". The conflict occurred in the database "BabyDB", table "dbo.Type", column "IdType'.

    You added IdType = document.Type.IdType in your insert,you're right.

    And the other question,you inserted 5 in IdType.

    This record stores a null value.

    I suggest you could delete this record which IdType is 5 in Type table.

    It will be OK.

    Best Regards.

    Yuki Tao

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, January 17, 2019 5:52 AM

All replies

  • User-474980206 posted

    the browser only posts inputs with a name attribute. add a name to the pdf file input. your select value will posy to a string parameter named TypeList.  You probably wanted to bind it to "Type" instead. use he DropDownListFor(m->m.Type, ViewBag.TypeList)

    Tuesday, January 15, 2019 3:09 PM
  • User-1917797656 posted
    I already try the input with name attribute but doesn't work
    Tuesday, January 15, 2019 3:20 PM
  • User475983607 posted

    I already try the input with name attribute but doesn't work

    Phrases like "doesn't work" are not specific enough to guess what does not work.  Is the browser uploading the file but your code has a bug?  You can check by opening Dev Tools (F12) and looking at the request.

    A few things I noticed... you should not use the EF models in your View.  Rather use View Models.  The submit button is named "file" and there is an input parameter named file.  There is no indication in the code where the action is handling multiple files.  There is no indication if you fixed the select name.

    Is there anyway you can post the updated code so we can verify?

    Tuesday, January 15, 2019 3:40 PM
  • User-1917797656 posted
    It's my first time with asp.net mvc ef6
    It's the updated code, what doesn't work it's the upload of a second file to another path for the same document.. I don't know how to proceed.
    The attribute name for the second input i removed intentionally because it upload the file twice to the same path..
    Tuesday, January 15, 2019 4:21 PM
  • User475983607 posted

    It's my first time with asp.net mvc ef6 

    The source code is the record of truth.  We need the source code or code that reproduces the issue in order to provide assistance.

    It's the updated code, what doesn't work it's the upload of a second file to another path for the same document.. I don't know how to proceed.

    Post the most recent code as requested.  

    The attribute name for the second input i removed intentionally because it upload the file twice to the same path..

    As stated above, browsers submit inputs that have names.  inputs without names are not submitted.  Guessing how technology works is not a good approach.  The follow tutorial explains how to upload multiple files.

    https://www.mikesdotnetting.com/article/287/uploading-multiple-files-with-asp-net-mvc

    IMHO, you should use your EF6 models in MVC.  EF6 models belong to EF not MVC.  Rather craft a ViewModel and use the EF model to fill the ViewModel.  This will help separate your data access layer from the UI plus it is easier to take advantage of model validation.  Maybe go through a few getting started tutorials.

    https://docs.microsoft.com/en-us/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/creating-an-entity-framework-data-model-for-an-asp-net-mvc-application

    Tuesday, January 15, 2019 5:11 PM
  • User-1917797656 posted

    The most recent code

    The Controller Create : 

     public ActionResult Create(Document document, IEnumerable<HttpPostedFileBase> file)
            {
                if (ModelState.IsValid)
                {
                    //Let's take first file
                    if (file.ElementAt(0) != null)
                    {
                        var IMGFILE = file.ElementAt(0);
                        if (IMGFILE != null && IMGFILE.ContentLength > 0)
                        {
    
                            var fileName = Path.GetFileName(IMGFILE.FileName);
                            var path = Path.Combine(Server.MapPath("~/Content/ImageUploaded/"), fileName);
                            IMGFILE.SaveAs(path);
                            db.Documents.Add(new Document
                            {
                                IdDoc = document.IdDoc,
                                Titre = document.Titre,
                                Description = document.Description,
                                Image = IMGFILE.FileName
                            });
                            db.SaveChanges();
                        }
                    }
    
                    //Let's take the second one now.
                    if (file.ElementAt(1) != null)
                    {
                        var PDFFILE = file.ElementAt(1);
                        if (PDFFILE != null && PDFFILE.ContentLength > 0)
                        {
                            var fileName = Path.GetFileName(PDFFILE.FileName);
                            var path = Path.Combine(Server.MapPath("~/Content/PdfFiles/"), fileName);
                            PDFFILE.SaveAs(path);
                            db.Documents.Add(new Document
                            {
                                IdDoc = document.IdDoc,
                                Titre = document.Titre,
                                Description = document.Description,
                                Pdf = PDFFILE.FileName
                            });
                            db.SaveChanges();
                        }
                    }
                }
                //return RedirectToAction("Index");
                return View(document);
            }

    The View Code : 

    @Html.ValidationSummary(true, "", new { @class = "text-danger" })
                    <div class="form-group">
                        @Html.LabelFor(model => model.Titre, htmlAttributes: new { @class = "control-label col-md-2" })
                        <div class="col-md-10">
                            @Html.EditorFor(model => model.Titre, new { htmlAttributes = new { @class = "form-control" } })
                            @Html.ValidationMessageFor(model => model.Titre, "", new { @class = "text-danger" })
                        </div>
                    </div>
    
                    <div class="form-group">
                        @Html.LabelFor(model => model.Description, htmlAttributes: new { @class = "control-label col-md-2" })
                        <div class="col-md-10">
                            @Html.EditorFor(model => model.Description, new { htmlAttributes = new { @class = "form-control" } })
                            @Html.ValidationMessageFor(model => model.Description, "", new { @class = "text-danger" })
                        </div>
                    </div>
                    <div class="form-group">
                        @Html.LabelFor(model => model.Type, htmlAttributes: new { @class = "control-label col-md-2" })
                        <div class="col-md-10">
                            @Html.DropDownList("TypeList", (IEnumerable<SelectListItem>)ViewBag.TypeList, "Select Type", new { @class = "form-control" })
                            @Html.ValidationMessageFor(model => model.Type, "", new { @class = "text-danger" })
                        </div>
                    </div>
    
                    <div class="form-group">
                        @Html.LabelFor(model => model.Image, htmlAttributes: new { @class = "control-label col-md-2" })
                        <div class="col-md-10">
                            <input type="file" class="form-control" name="file" accept="image/png,image/jpg,image/jpeg" id="picFile"/>
                            @Html.ValidationMessageFor(model => model.Image, "", new { @class = "text-danger" })
                        </div>
                    </div>
    
                    <div class="form-group">
                        @Html.LabelFor(model => model.Pdf, htmlAttributes: new { @class = "control-label col-md-2" })
                        <div class="col-md-10">
                            <input type="file" class="form-control" name="file" accept=".pdf" id="pdfFile" />
                            @Html.ValidationMessageFor(model => model.Pdf, "", new { @class = "text-danger" })
                        </div>
                    </div>
    
    
                    <div class="form-group">
                        <div class="col-md-offset-2 col-md-10">
                            <input type="submit" value="Create" class="btn btn-default" />
                        </div>
                    </div>
                </div>

    After testing, it save two items

    Tuesday, January 15, 2019 7:23 PM
  • User1520731567 posted

    Hi khalilbnzz,

    According to your code,I suggest you could add ForeignKey in model,like:

        [Table("Document")]
        public class Document
        {
            [Key]
            public int IdDoc { get; set; }
            public string Titre { get; set; }
            public string Description { get; set; }
            public virtual string Image { get; set; }
            public virtual string Pdf { get; set; }
            public int IdType { get; set; }
            [ForeignKey("IdType")]
            public virtual Type Type { get; set; }
        }

    And modify the DropDownList to:

    @Html.DropDownListFor(model => model.Type.IdType, (IEnumerable<SelectListItem>)ViewBag.TypeList, "Select Type", new { @class = "form-control" })
    

    How it works in my project:

    Best Regards.

    Yuki Tao

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, January 16, 2019 10:24 AM
  • User-1917797656 posted

    Thanks Yuki, i'll give it a try

    The INSERT statement conflicts with the FOREIGN KEY constraint "FK_dbo.Document_dbo.Type_IdType". The conflict occurred in the database "BabyDB", table "dbo.Type", column "IdType'.
    The investigation has been stopped.

    EDIT : After i edit the Create Controller, it add an other IdType that doesn't exit

      public ActionResult Create(Document document, HttpPostedFileBase file)
             {
                 ViewBag.TypeList = new SelectList(db.Types, "IdType", "Label");
                 if (ModelState.IsValid)
                 {
                     string path = Path.Combine(Server.MapPath("~/Content/ImageUploaded/"), Path.GetFileName(file.FileName));
                     file.SaveAs(path);
                     db.Documents.Add(new Document
                     {
                         IdDoc = document.IdDoc, Titre = document.Titre, Description = document.Description, Image = file.FileName, Type=document.Type
    
    
                     });
                     //db.Documents.Add(document);
                     db.SaveChanges();
                     return RedirectToAction("Index");
                 } 
    
                 return View(document);
             }

    EDIT 2 : It's done like a charm, thank you

    public ActionResult Create(Document document, HttpPostedFileBase file)
             {
                 ViewBag.TypeList = new SelectList(db.Types, "IdType", "Label");
                 if (ModelState.IsValid)
                 {
                     string path = Path.Combine(Server.MapPath("~/Content/ImageUploaded/"), Path.GetFileName(file.FileName));
                     file.SaveAs(path);
                     db.Documents.Add(new Document
                     {
                         IdDoc = document.IdDoc,
                         Titre = document.Titre,
                         Description = document.Description,
                         Image = file.FileName,
                         IdType = document.Type.IdType
                     });
                     //db.Documents.Add(document);
                     db.SaveChanges();
                     return RedirectToAction("Index");
                 } 
    
                 return View(document);
             }

    Wednesday, January 16, 2019 10:35 AM
  • User1520731567 posted

    Hi khalilbnzz,

    The INSERT statement conflicts with the FOREIGN KEY constraint "FK_dbo.Document_dbo.Type_IdType". The conflict occurred in the database "BabyDB", table "dbo.Type", column "IdType'.

    You added IdType = document.Type.IdType in your insert,you're right.

    And the other question,you inserted 5 in IdType.

    This record stores a null value.

    I suggest you could delete this record which IdType is 5 in Type table.

    It will be OK.

    Best Regards.

    Yuki Tao

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, January 17, 2019 5:52 AM