1

I am new to this wonderful framework AngularJS. I have a C# API controller where I would like to upload data from a form that includes an image. Normally (razor) I would upload a form as json and include the image as a HttpPostedFileBase:

public ArtWork SaveArtWork(ArtWork artWork, HttpPostedFileBase file)
    { // save in db and return object }

I have found a lot of different ways for uploading the file wrapped in a FormData object ([AngularJS Uploading An Image With ng-upload):

$scope.uploadFile = function(files) {
var fd = new FormData();
//Take the first selected file
fd.append("file", files[0]);

$http.post(uploadUrl, fd, {
    withCredentials: true,
    headers: {'Content-Type': undefined },
    transformRequest: angular.identity
}).success( ...all right!... ).error( ..damn!... );
};

But I have some other properties I have parsed to a json object, and now I would like to upload it all in a bundle. Or is it possible to get the image data as a base64 and add it to my json object? I know that a base64 is 1/3 bigger than a byte stream, but it's so easy to work with :)

Here's my Angular Controller:

'use strict';

(function () {

// Factory
angular.module('umbraco').factory('artworkResource', function ($http) {
    return {
        getById: function (id) {
            return $http.get("backoffice/Trapholt/ArtWorkApi/GetById/" + id);
        },
        save: function (artwork) {
            return $http.post("backoffice/Trapholt/ArtWorkApi/SaveArtWork", angular.toJson(artwork));
        },
        save2: function (artwork, fd) {
        return $http.post("backoffice/Trapholt/ArtWorkApi/SaveArtWork", angular.toJson(artwork), fd);
    }
    };
});

// Controller
function artworkController($scope, $routeParams, artworkResource, $http) {

    $scope.categories = ['Keramik', 'Maleri', 'Møbel', 'Skulptur'];

    artworkResource.getById($routeParams.id).then(function (response) {
        $scope.curatorSubject = response.data;
    });


    var fd;
    $scope.uploadFile = function(files) {
        fd = new FormData();
        fd.append("file", files[0]);
    };

    $scope.save = function (artwork) {
        artworkResource.save(artwork, fd).then(function (response) {
            $scope.artwork = response.data;

            alert("Success", artwork.Title + " er gemt");
        });
    };


};
//register the controller
angular.module("umbraco").controller('ArtworkTree.EditController', artworkController);

})();

So how can I combine my image and the other properties in one json object or two arguments? Please leave a comment if I need to explain some more, any help would really be appreciated :)

1 Answer 1

2

I found a solution, where I added the file and the model to the form data. So it was actually pretty easy to expand solution from here. This is my Angular controller:

function artworkController($scope, $routeParams, artworkResource, $http) {

    $scope.categories = ['Keramik', 'Maleri', 'Møbel', 'Skulptur'];

    artworkResource.getById($routeParams.id).then(function (response) {
        $scope.curatorSubject = response.data;
    });


    var fd;
    $scope.uploadFile = function(files) {
        fd = new FormData();
        fd.append("file", files[0]);
    };

    $scope.save = function (artwork) {

        fd.append("ArtWork", angular.toJson(artwork));

        $http.post("backoffice/Trapholt/ArtWorkApi/Post", fd, {
            transformRequest: angular.identity,
            headers: { 'Content-Type': undefined }
        });
    };


};

And this i my C# mvc API controller:

public HttpResponseMessage Post()
    {
        HttpResponseMessage result = null;
        var httpRequest = HttpContext.Current.Request;
        if (httpRequest.Files.Count > 0)
        {
            var file = httpRequest.Files[0];
            var artworkjson = httpRequest.Form[0];
            var artwork = JsonConvert.DeserializeObject<ArtWork>(artworkjson);
            if (artwork == null)
            {
                return Request.CreateResponse(HttpStatusCode.BadRequest, "No saved");
            }

            using (var binaryReader = new BinaryReader(file.InputStream))
            {
                artwork.Picture = binaryReader.ReadBytes(file.ContentLength);
            }

            result = Request.CreateResponse(HttpStatusCode.Created, "ok");
        }
        else
        {
            result = Request.CreateResponse(HttpStatusCode.BadRequest);
        }
        return result;
    }

The html view is a normal form where all the inputs are bound with the model, expect the file input field:

<input type="file" id="file" name="picture" onchange="angular.element(this).scope().uploadFile(this.files)"/>
Sign up to request clarification or add additional context in comments.

Comments

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.