1

I need some help to solve this problem. To add new record to my database I'm using AngularJS and ASP.NET MVC (without reloading the page). All is working fine, but the problem appears when I'm trying to upload also image with HTML input type="file". I'm using FormData (I think it is the best way to do this?) to upload image and for the rest model properties I'm using ng-model and so on. The funny thing is that when I'm trying to save just image, without any other data then my controller gets the file but when I will add also some properties for my record like Name, Year, Author + image then the controller with only get the model properties or just single image, never both.

Here is my angulajs code:

angular.module('MovieController', [])
        .controller('MovieCtrl', ['$scope', '$http', function ($scope, $http) {
            $scope.model = {};

            $http.get('/Manage/AddMovieVM').success(function (data) {
                $scope.model = data;
            });

            $scope.addMovie = function () {
                $http.post('/Manage/Add', $scope.new.Movie).success(function (data) {
                    $scope.model.Movies.push(data);
                    $scope.showAddForm(false);
                });
            };

            //upload files
            var formData = new FormData();

            $scope.LoadFileData = function (files) {
                for (var file in files) {
                    formData.append("file", files[file]);
                }
            };

            $scope.submit = function () {
                $http.post("/Manage/Edit", formData, {
                    withCredentials: true,
                    headers: { 'Content-Type': undefined },
                    transformRequest: angular.identity
                }).success(function (response) {
                    console.log('succes');
                });
            };
        }]);

Here is my back-end code, ASP.NET MVC:

        [HttpPost]
        public ActionResult Add(Movie model, HttpPostedFileBase file)
        {

            var files = Request.Files;
            var fileName = Path.GetFileName(file.FileName);

            if (ModelState.IsValid)
            {
                using (var db = new MovieSubtitlesContext())
                {
                    var movie = new Movie()
                    {
                        MovieTitle = model.MovieTitle,
                        MovieDescription = model.MovieDescription,
                        MovieDirector = model.MovieDirector,
                        MovieRating = model.MovieRating,
                        MovieImage = fileName
                    };

                    db.Movies.Add(movie);
                    db.SaveChanges();

                    return Json(movie, JsonRequestBehavior.AllowGet);
                }
            }

            return View();
        }

Here is my view:

    <input type="text" class="form-control" placeholder="Title" ng-model="new.Movie.MovieTitle" />

    <textarea rows="15" cols="50" class="form-control" ng-model="new.Movie.MovieDescription" placeholder="Description"></textarea>

    //director and rating similar to first input

   <input id="imgInp" type="file" aria-label="Add photos to your post" class="upload" name="file" onchange="angular.element(this).scope().LoadFileData(this.files)" multiple="" accept="image/*">

I tried a lot. For example to save all in one function like this:

    $scope.addMovie = function () {
        $http.post('/Manage/Edit', $scope.new.Movie, formData, {
            withCredentials: true,
            headers: { 'Content-Type': undefined },
            transformRequest: angular.identity
            }).success(function (data) {
                    $scope.model.Movies.push(data);
                    $scope.showAddForm(false);
                });
    };

I think it is a good idea because there are two post requests but it doesn't work anyway. To my button I tried to call two functions like this but still nothing.

<button type="button" class="btn btn-success" ng-click="addMovie(); submit()">Save</button>

I really don't know what I'm doing wrong and how I can save image with other model properties. (When I'm passing the image name in my textbox it is working fine, but that's not the point, (for example I already have in my folder "batman.jpg" then I just need to pass "batman.jpg" in my:

<input type="text" class="form-control" placeholder="Img" ng-model="new.Movie.MovieImage" required />

//Update for Nadeem

MVC Controller:

 [HttpPost]
        public ActionResult AddMovie(Movie model, HttpPostedFileBase file)
        {
            if (ModelState.IsValid)
            {
                if (file != null && file.ContentLength > 0)
                {
                    var fileName = Path.GetFileName(file.FileName);
                    var path = Path.Combine(Server.MapPath("~/Content/ImagesC"), fileName);
                    file.SaveAs(path);
                    model.MovieImage = fileName;
                }
                using (var db = new MovieSubtitlesContext())
                {
                    var movie = new Movie()
                    {
                        MovieTitle = model.MovieTitle,
                        MovieDescription = model.MovieDescription,
                        MovieDirector = model.MovieDirector,
                        MovieGenre = model.MovieGenre,
                        MovieDuration = model.MovieDuration,
                        MovieTrailer = model.MovieTrailer,
                        ImdbLink = model.ImdbLink,
                        MovieRating = model.MovieRating,
                        MovieImage = model.MovieImage,
                        ReleaseDate = model.ReleaseDate
                    };

                    db.Movies.Add(movie);
                    db.SaveChanges();

                    return Json(movie, JsonRequestBehavior.AllowGet);
                }
            }

            return View();
        }

Here is also my angularjs controller code for AddMovie

$scope.uploadPic = function (file) {
                file.upload = Upload.upload({
                    url: '/Manage/AddMovie',
                    data: {
                        file: file,
                        MovieTitle: $scope.new.Movie.MovieTitle,
                        MovieDescription: $scope.new.Movie.MovieDescription,
                        MovieDirector: $scope.new.Movie.MovieDirector,
                        ReleaseDate: $scope.new.Movie.ReleaseDate,
                        MovieGenre: $scope.new.Movie.MovieGenre,
                        MovieDuration: $scope.new.Movie.MovieDuration,
                        MovieTrailer: $scope.new.Movie.MovieTrailer,
                        ImdbLink: $scope.new.Movie.ImdbLink,
                        MovieRating: $scope.new.Movie.MovieRating
                    }
                });
                file.upload.then(function (response) {
                    $timeout(function () {
                        file.result = response.data;
                    });
                }, function (response) {
                    if (response.status > 0)
                        $scope.errorMsg = response.status + ': ' + response.data;
                }, function (evt) {
                    // Math.min is to fix IE which reports 200% sometimes
                    file.progress = Math.min(100, parseInt(100.0 * evt.loaded / evt.total));
                });
            };
4
  • Okay, I solved this problem. First I had to leave this idea with formData (I really tried somehow to fix that but still was the same problem and I had to move on) so I have found a really nice AngularJS plugin ng-file-upload (you can find it on github). Thanks to this in action method there is a simply way to catch files. We can do this by using Request.files and also with HttpPostedFileBase file. Commented Jan 29, 2016 at 15:35
  • Hello Munich, I am facing the same issue, can you share you Asp.net controller of Request.Files if you can ? Thank you Commented Mar 7, 2016 at 17:32
  • Sure, no problem. I updated my post with mvc and angularjs ctrl Commented Mar 7, 2016 at 18:32
  • Thank you so much my man. I appreciate your help. Commented Mar 8, 2016 at 10:32

0

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.