nes
nes

Reputation: 81

MVC file saving and uploading with same button

I have a Upload and Save forms that works but I would like to pass uploaded image and save other data for movies in one button (to merge Save and Upload)

Here is my cshtml Create view:

        @model MvcMovie.Models.Movie

        @{
            ViewBag.Title = "Create";
        }

        <h2>Create</h2>

        @using (Html.BeginForm()) {
            @Html.ValidationSummary(true)

            <fieldset>
                <legend>Movie</legend>

                <div class="editor-label">
                    @Html.LabelFor(model => model.Title)
                </div>
                <div class="editor-field">
                    @Html.EditorFor(model => model.Title)
                    @Html.ValidationMessageFor(model => model.Title)
                </div>

                <div class="editor-label">
                    @Html.LabelFor(model => model.ReleaseDate)
                </div>
                <div class="editor-field">
                    @Html.EditorFor(model => model.ReleaseDate)
                    @Html.ValidationMessageFor(model => model.ReleaseDate)
                </div>

                <div class="editor-label">
                    @Html.LabelFor(model => model.Genre)
                </div>
                <div class="editor-field">
                    @Html.EditorFor(model => model.Genre)
                    @Html.ValidationMessageFor(model => model.Genre)
                </div>

                <div class="editor-label">
                    @Html.LabelFor(model => model.Price)
                </div>
                <div class="editor-field">
                    @Html.EditorFor(model => model.Price)
                    @Html.ValidationMessageFor(model => model.Price)
                </div>
                <div class="editor-label">
                    @Html.LabelFor(model => model.Rating)
                </div>
                <div class="editor-field">
                    @Html.EditorFor(model => model.Rating)
                    @Html.ValidationMessageFor(model => model.Rating)
                </div>

                    <div class="editor-label">
                    @Html.LabelFor(model => model.ImageUrl)
                </div>
                <div class="editor-field">
                    @Html.EditorFor(model => model.ImageUrl)
                    @Html.ValidationMessageFor(model => model.ImageUrl)
                </div>

                    <input type="submit" value="Create" />

            </fieldset>
                <img src="~/Content/Images/Full/image1.JPG" alt="Sample Image" width="300px" height="200px" />


        }

            @using (Html.BeginForm("Upload", "Movies", FormMethod.Post, new { enctype="multipart/form-data" }))
            { 
                <input name="ImageUploaded" type="file">  
                <input type="submit" value="Upload"/>     
            } 

            @Html.ActionLink("Back to List", "Index")
        @section Scripts {
            @Scripts.Render("~/bundles/jqueryval")
        }

Here's my Controller:

    public ActionResult Create()
    {
        return View();
    }

    //
    // POST: /Movies/Create

    [HttpPost]
    public ActionResult Create(Movie movie)
    {

        if (ModelState.IsValid)
        {
            db.Movies.Add(movie);
            db.SaveChanges();
            return RedirectToAction("Index", "Movies");
        }

        return View(movie);
    }

    public ActionResult Edit(int id = 0)
    {
        Movie movie = db.Movies.Find(id);
       if (movie == null)
      {
           return HttpNotFound();
         }
        return View(movie);
    }


        [HttpPost]
        public ActionResult Upload(ImageModel model)
        {
            if (ModelState.IsValid)
            {
                string fileName = model.ImageUploaded.FileName;
                string serverPath = Server.MapPath("~");
                string imagesPath = serverPath + "Content\\Images\\";
                String fullPath = @"" + "C:/Users/FAZI-7/Desktop/Full/";
                String thumbPath = @"" + "C:/Users/FAZI-7/Desktop/Thumb/";
                ImageModel.ResizeAndSave(thumbPath, fileName, model.ImageUploaded.InputStream, 80, false);
                ImageModel.ResizeAndSave(fullPath, fileName, model.ImageUploaded.InputStream, 600, false);

            }

            return RedirectToAction("Index", "Movies");
        } 

I can't make one button for both functions, I have read that I might need to have the same controller action having two parameters, or put all the controls in one form, but how would I do this?

Upvotes: 1

Views: 1631

Answers (1)

FreeAsInBeer
FreeAsInBeer

Reputation: 12979

Here's a working example. I think one of the critical pieces you're missing is the enctype parameter on your HTML form element.

Create.shtml

@model ARES.Models.EmployeeViewModel

@{
    ViewBag.Title = "Create New Employee";
}

@using (Html.BeginForm("Create", "Employees", FormMethod.Post, new { enctype = "multipart/form-data" })) {
    <fieldset class="containedAndCentered">
        <div class="editor-label">
            Department
        </div>
        <div class="editor-field">
            @Html.DropDownListFor(m => m.SelectedDepartmentId, new SelectList(Model.Departments, "department_id", "department_name", Model.SelectedDepartmentId))
            @Html.ValidationMessageFor(model => model.Departments)
        </div>

        <div class="editor-label">
            Name
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.EmployeeName)
            @Html.ValidationMessageFor(model => model.EmployeeName)
        </div>

        <div class="editor-label">
            Photo
        </div>
        <div class="editor-field">
            <input type="file" id="EmployeePhoto" name="EmployeePhoto" />
        </div>

        <div class="editor-field">
            @Html.HiddenFor(model => model.EmployeeId)
        </div>

        <hr />
        <div class="controls left">
            @Html.ActionLink("Back to List", "Index")
        </div>
        <div class="controls right">
            <input type="submit" value="Create" />
        </div>
    </fieldset>
}

EmployeesController.cs

namespace ARES.Controllers {
    public class EmployeesController : Controller {
        private employee_picsEntities db = new employee_picsEntities();

        [HttpPost]
        public ActionResult Create(EmployeeViewModel evm) {
            if (ModelState.IsValid) {
                // Find the selected department object.
                var department = (from d in db.departments
                                    where d.department_id == evm.SelectedDepartmentId
                                    select d).FirstOrDefault();

                employee_master employee_master = new employee_master() {
                    department = department,
                    employee_name = evm.EmployeeName,
                    file_location = evm.EmployeePictureUrl,
                    status = 1
                };

                // Add the employee to the collection before we set the file_location field so that we have the neccessary employee_id value.
                db.employee_master.Add(employee_master);
                db.SaveChanges();

                // Save a photo if we were provided with one.
                if (evm.EmployeePhoto != null) {
                    employee_master.file_location = SaveEmployeePhoto(employee_master.employee_id, evm.EmployeePhoto);
                }

                //db.employee_master.Add(employee_master);
                db.SaveChanges();
                return RedirectToAction("Index");
            }

            return View(evm);
        }

        public string SaveEmployeePhoto(int employeeId, HttpPostedFileBase employeePhoto) {
            var basePath = "~/Content/images/photos";
            var filename = "";
            var path = Server.MapPath(basePath);
            var savedFileName = "";

            HttpPostedFileBase file = Request.Files[0];
            if (file.ContentLength > 0) {
                filename = employeeId + Path.GetExtension(file.FileName);
                savedFileName = Path.Combine(path, filename);
                file.SaveAs(savedFileName);
            }
            //filename = (basePath + "/" + fileName).ToAbsoluteUrl()
            return string.Format("{0}/{1}", basePath, filename).ToAbsoluteUrl();
        }
    }
}

Upvotes: 1

Related Questions