0

I have a project. There is a Portfolio page, which contains project information, project-related categories, project-related technologies and project-related images. I want the pictures of the project to be added one by one and deleted if desired. Finally, when I press the Save button, I want all the information to be saved to the database and the pictures to be saved in a folder.

This is my Portfolio model

    public Portfolio()
    {
        this.Categories = new HashSet<Category>();
        this.Technologies = new HashSet<Technology>();
        this.Images = new HashSet<Image>();
    }
    public int Id { get; set; }

    [Display(Name ="Project Name"),Required(ErrorMessage ="*")]
    public string ProjectName { get; set; }
    [Display(Name = "Date")]
    public DateTime Date { get; set; }
    [Display(Name = "Url")]
    public string URL { get; set; }
    [Display(Name = "Description")]
    public string Description { get; set; }
    public virtual ICollection<Technology> Technologies { get; set; }
    public virtual ICollection<Category> Categories { get; set; }
    public virtual ICollection<Image> Images { get; set; }

This is my Image model

    public Image()
    {
        this.Portfolios = new HashSet<Portfolio>();
    }
    public int Id { get; set; }
    public string URL { get; set; }
    [NotMapped]
    public HttpPostedFileBase[] files { get; set; }
    public int PortfolioId { get; set; }
    public virtual ICollection<Portfolio> Portfolios { get; set; }

This is my Create Action

    public ActionResult Create(Portfolio portfolio, string[] Cat, string[] Tech, HttpPostedFileBase img)
    {

        //TODO:Image add
        if (ModelState.IsValid)
        {
            if (Cat != null)
            {
                portfolio.Categories = new List<Category>();
                foreach (var item in Cat)
                {
                    var categoryToAdd = context.Category.Find(int.Parse(item));
                    portfolio.Categories.Add(categoryToAdd);
                }
            }
            if (Tech != null)
            {
                portfolio.Technologies = new List<Technology>();
                foreach (var item in Tech)
                {
                    var technologyToAdd = context.Technology.Find(int.Parse(item));
                    portfolio.Technologies.Add(technologyToAdd);
                }
            }
            context.Portfolio.Add(portfolio);
            context.SaveChanges();
            return RedirectToAction("Index");
        }
        else
        {
            return View();
        }
    }

This is my Create View

    <div class="card-body">
    @using (Html.BeginForm("Create", "Portfolio", FormMethod.Post, new { enctype = "multipart/form-data" }))
    {
        @Html.AntiForgeryToken()
        <div class="form-group">
            @Html.LabelFor(m => m.ProjectName, new { @class = "control-label" })
            @Html.ValidationMessageFor(m => m.ProjectName, "", new { @class = "text-danger" })
            @Html.EditorFor(s => s.ProjectName, new { htmlAttributes = new { @class = "form-control" } })
        </div>
        <div class="form-group">
            @Html.LabelFor(m => m.Date, new { @class = "control-label" })
            @Html.ValidationMessageFor(m => m.Date, "", new { @class = "text-danger" })
            @Html.EditorFor(s => s.Date, new { htmlAttributes = new { @class = "form-control" } })
        </div>
        <div class="form-group">
            @Html.LabelFor(m => m.URL, new { @class = "control-label" })
            @Html.ValidationMessageFor(m => m.URL, "", new { @class = "text-danger" })
            @Html.EditorFor(s => s.URL, new { htmlAttributes = new { @class = "form-control" } })
        </div>
        <div class="form-group">
            @Html.LabelFor(m => m.Description, new { @class = "control-label" })
            @Html.ValidationMessageFor(m => m.Description, "", new { @class = "text-danger" })
            @Html.EditorFor(s => s.Description, new { htmlAttributes = new { @class = "form-control" } })
        </div>
        <div class="form-group">
            @Html.LabelFor(m => m.Categories, new { @class = "control-label" })
            @* @Html.ListBoxFor(m=>m.Categories,(IEnumerable<SelectListItem>)ViewBag.Cat)*@
            @Html.ListBox("Cat", null, new { @class = "form-control" })
        </div>
        <div class="form-group">
            @Html.LabelFor(m => m.Technologies, new { @class = "control-label" })
            @* @Html.ListBoxFor(m=>m.Categories,(IEnumerable<SelectListItem>)ViewBag.Cat)*@
            @Html.ListBox("Tech", null, new { @class = "form-control" })
        </div>
        <div class="form-group">
            <script src="~/Scripts/jquery-2.1.3.min.js"></script>
            <script>
                //$(document).ready(function () {
                //    $("#fileButton").click(function () {
                //        var files = $("#fileInput").get(0).files;
                //        var fileData = new FormData();
                //        for (var i = 0; i < files.length; i++) {
                //            fileData.append("fileInput", files[i]);
                //        }
                //        $('#files').val(fileData);
                //    });
                //});
                $(document).ready(function () {
                    var i = 1;
                    function readURL(input) {
                        if (input.files && input.files[0]) {
                            var reader = new FileReader();
                            reader.onload = function (e) {
                                var img = '<div id="imageItem' + i + '" style="position:relative;width:100px;">' +
                                    '<i onclick="remove(\'imageItem' + i + '\')"' + 'style="position:absolute;right:5px;cursor:pointer;">X</i>' +
                                    ' <img src="' + e.target.result + '" width="100" /><input type="hidden" name="img" value="' + e.target.result + '" />' +
                                    '</div>';
                                $('#imageList').append(img);
                            }
                            reader.readAsDataURL(input.files[0]);
                            i = i + 1;
                        }
                    }
                    $("#fu").change(function () {
                        readURL(this);
                    });

                });
                function remove(id) {
                    $('#' + id).remove();
                }
            </script>
            <div class="form-group">
                <div class="row">
                    <div class="col-6">
                        @Html.LabelFor(m => m.Images, new { @class = "control-label" })
                        <input type="file" id="fu" class="form-control" />
                    </div>
                    <div class="col-6">
                        <div id="imageList">
                            @*<div id="imageItem1" style="position:relative;width:100px;">
                                    <i onclick="remove('imageItem1')" style="position:absolute;right:5px;cursor:pointer;">X</i>
                                    <img src="~/images/portfolio/1.jpg" width="100" />
                                </div>*@
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <div class="form-group row">
            <div class="col-6">
                <button class="btn btn-outline-success">Save</button>
            </div>
            <div class="col-6 text-right">
                <a href="@Url.Action("Index","Portfolio")" class="text-primary text-decoration-none"><i class="fa fa-arrow-left text-primary"></i> Back To List</a>
            </div>
        </div>
    }
</div>

As in the picture, I want to select the pictures first and then click the save button to save the information. enter image description here

mert
  • 1
  • 2
  • 4
  • Greetings @mert, I have added the flow to save image or media file in .NET MVC application, in case of you required more details let me know will update the post accordingly. – ankitkanojia Mar 14 '20 at 09:15

2 Answers2

0

View


script and CSS

<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<style>
    .preview-images-zone {
        width: 100%;
        border: 1px solid #ddd;
        min-height: 90px;
        /* display: flex; */
        padding: 5px 5px 0px 5px;
        position: relative;
        overflow: auto;
    }

        .preview-images-zone > .preview-image:first-child {
            height: 90px;
            width: 90px;
            position: relative;
            margin-right: 5px;
        }

        .preview-images-zone > .preview-image {
            height: 90px;
            width: 90px;
            position: relative;
            margin-right: 5px;
            float: left;
            margin-bottom: 5px;
        }

            .preview-images-zone > .preview-image > .image-zone {
                width: 100%;
                height: 100%;
            }

                .preview-images-zone > .preview-image > .image-zone > img {
                    width: 100%;
                    height: 100%;
                }

            .preview-images-zone > .preview-image > .tools-edit-image {
                position: absolute;
                z-index: 100;
                color: #fff;
                bottom: 0;
                width: 100%;
                text-align: center;
                margin-bottom: 10px;
                display: none;
            }

            .preview-images-zone > .preview-image > .image-cancel {
                font-size: 18px;
                position: absolute;
                top: 0;
                right: 0;
                font-weight: bold;
                margin-right: 10px;
                cursor: pointer;
                display: none;
                z-index: 100;
            }

    .preview-image:hover > .image-zone {
        cursor: move;
        opacity: .5;
    }

    .preview-image:hover > .tools-edit-image,
    .preview-image:hover > .image-cancel {
        display: block;
    }

    .ui-sortable-helper {
        width: 90px !important;
        height: 90px !important;
    }

    .container {
        padding-top: 50px;
    }
</style>
 <script>
        $(document).ready(function () {
            $(document).on('change', '.btn-file :file', function () {
                var input = $(this),
                    label = input.val().replace(/\\/g, '/').replace(/.*\//, '');
                input.trigger('fileselect', [label]);
            });

            $('.btn-file :file').on('fileselect', function (event, label) {

                var input = $(this).parents('.input-group').find(':text'),
                    log = label;

                if (input.length) {
                    input.val(log);
                } else {
                    if (log) alert(log);
                }

            });
            function readURL(input) {
                if (input.files && input.files[0]) {
                    var reader = new FileReader();

                    reader.onload = function (e) {
                        $('#img-upload').attr('src', e.target.result);
                    }

                    reader.readAsDataURL(input.files[0]);
                }
            }

            $("#imgInp").change(function () {
                readURL(this);
            });
        });

    </script>

Image upload controller

 @Html.TextBoxFor(model => model.YOUR_MODEL_DATA, new { Type = "file", @class = "form-input-styled", id = "imgInp" })

Preview of image

<img id='img-upload' class="img-fluid" alt=" " width="200" height="200" />

Controller


[HttpPost]
public ActionResult Create(YOUR_TABLE tbl)
{
   tbl.Images  = tbl.files.FileName;
   tbl.files.SaveAs(YOUR_PATH);
}
Dip Surani
  • 61
  • 6
0

@mert you need to take care 2-3 things while upload image using HttpPostedFileBase in .NET MVC.

1) Form must be enctype = "multipart/form-data"

2) Name of input type file should be exact name as class object.

For ex

//In .cshtml file  
<input type='file' name="file"/>

//In Controller file
[HttpPost]
public ActionResult Index(HttpPostedFileBase file){
   // You controller code
   return View();
}

3) Once you get the file in the HttpPostedFileBase controller side, you need to verify the object is null of not and folder path where you want to save the file is exists or not.

[HttpPost]
public ActionResult Index(HttpPostedFileBase file)
{
    if (file != null)
    {
        var directoryPath = Server.MapPath("~/FolderName");
        if (!Directory.Exists(directoryPath))
        {
            Directory.CreateDirectory(directoryPath);
        }

        var fileGuid = Guid.NewGuid();
        var filename = string.Concat(fileGuid, Path.GetExtension(file.FileName));
        var savePath = Path.Combine(directoryPath, filename);
        file.SaveAs(savePath);
    }

    return View();
}
ankitkanojia
  • 3,072
  • 4
  • 22
  • 35