Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Edo Husakovic 6 posts 97 karma points
    Jul 27, 2020 @ 10:19
    Edo Husakovic
    0

    Custom dashboard file Upload not received in backend

    So I tried following this forum post and this ASP.Net post(Uses AJAX but is essentially the same) for creating my member import.

    I managed to call my c# controller and get a response but I can't seem to figure out how to actually receive the file in the UmbracoAuthorizedController.

    My JS:

    angular.module("umbraco").controller("DashboardMemberImport", function($scope, $element, $http) {
    // Get a reference to the file input field
    var input = $element[0].querySelector("input[type=file]");
    
    $scope.upload = function() {
    
        // Ignore if no files has been selected
        if (input.files.length === 0) return;
    
        // Get the file object
        var file = input.files[0];
    
        // Use form data to send multipart POST data
        var formData = new FormData();
        formData.append("file", file);
    
        // This is used to check if the file is written into FormData
        for (var value of formData.values()) {
            console.log(value);
        }
    
        // Upload the file using $http
        $http({
            method: "POST",
            url: "/umbraco/backoffice/MemberImport/UploadFiles",
            headers: { "Content-Type": undefined },
            transformRequest: angular.identity,
            data: formData
        }).then(function() {
            alert("success")
        }, function() {
            alert("error")
        });
    };
    });
    

    My c#:

    [HttpPost]
    public ActionResult UploadFiles()
    {
        throw new Exception(Request.Files.Count.ToString());
    }
    

    The controller always returns file count 0 although the console says that there is a file in FormData. enter image description here enter image description here

    In general I am quite confused on how the Request.Files actually works and what I am missing.

    Any help would be greatly appreciated :))

    Umbraco version: 8.6.2

  • Ismail Mayat 4511 posts 10090 karma points MVP 2x admin c-trib
    Jul 28, 2020 @ 13:24
    Ismail Mayat
    0

    I have something working in 7.15.4 looks almost exactly the same as your code. Only thing I have different is in the .net controller when I get the file I have:

     var file = HttpContext.Current.Request.Files["file"];
    

    Shouldn't make a different though.

    Regards

    Ismail

  • Edo Husakovic 6 posts 97 karma points
    Jul 28, 2020 @ 13:35
    Edo Husakovic
    0

    Thanks for your response Ismail

    I already tried this and I just tried it again for good measure.

    Sadly still nothing.

    [HttpPost]
    public ActionResult UploadFiles()
    {
         var test = Request.Files["file"];
         throw new Exception(test.FileName);
    }
    

    enter image description here

  • Kevin Jump 2310 posts 14695 karma points MVP 7x c-trib
    Jul 29, 2020 @ 15:17
    Kevin Jump
    1

    Hi

    I have a working example for v8.

    https://github.com/KevinJump/DoStuffWithUmbraco/tree/master/Src/DoStuff.Core/FileUpload (also in the bottom of that main thread)

    It uses the ngf-file-upload library - which comes as part of Umbraco 8

    the main thing i end up having to add is the CustomMultipartStreamProvider - which handles the file being part of the request alongside other things.

  • Edo Husakovic 6 posts 97 karma points
    Aug 10, 2020 @ 07:35
    Edo Husakovic
    101

    Thank you Kevin

    Your code is exactly what i was looking for. I needed some time to figure it out but now it works perfectly.

    I cleaned the code up a little and I really hope this helps someone out. :)

    I haven't tested multiple file upload so I'm not sure how you would do it but I'm assuming you could use something similair to how to the extra fields are sent.

    HTML:

    <div ng-controller="dashboardMemberImportController as vm">
        <input id="dostufffilepicker" type="file" ngf-select ngf-model="filesHolder" ngf-change="vm.handleFiles($files, $event)" ngf-multipart="true" />
        <button ng-click="vm.upload(vm.file)">upload</button>
    </div>
    

    JS:

    (function() {
        function dashboardController($scope,
            Upload) {
            var vm = this;
    
            vm.handleFiles = handleFiles;
            vm.upload = upload;
    
            function upload(file) {
                Upload.upload({
                    url: "/Umbraco/backoffice/api/MemberImport/UploadFile",
                    fields: {
    
                        //These are additional fields you can send and use as FormData
                        'overwrite': "false",
                        'sendEmail': "true"
                    },
                    file: file
                }).success(function(data, status, headers, config) {
                    alert (data);
                }).error(function(data, status, headers, config) {
                    alert(data);
                });
            }
    
            function handleFiles(files, event) {
                if (files && files.length > 0) {
                    vm.file = files[0];
                }
            }
        }
        angular.module('umbraco')
            .controller('dashboardMemberImportController', dashboardController);
    })();
    

    C#:

    public class MemberImportController : UmbracoAuthorizedApiController
    {
        [HttpPost]
        public async Task<string> UploadFile()
        {
            try
            {
                if (!Request.Content.IsMimeMultipartContent())
                    throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
    
                //This is the path where the file will be saved
                var uploadFolder = IOHelper.MapPath("~/ENDU/memberImport/");
                Directory.CreateDirectory(uploadFolder);
    
                var provider = new CustomMultipartFormDataStreamProvider(uploadFolder);
                var result = await Request.Content.ReadAsMultipartAsync(provider);
                //filename is path to file
                var filename = result.FileData.First().LocalFileName;
    
                //This is how to get the values of the extra fields we defined in the JS
                var overwrite = result.FormData["overwrite"];
                var sendEmail = result.FormData["sendEmail"];
    
                if (filename == null)
                    throw new HttpResponseException(HttpStatusCode.NoContent);
    
                //This is how we get the filestream since filename is the path to the file
                FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read);
    
                return "success";
            }
            catch
            {
                return "file error";
            }
        }
    
        public class CustomMultipartFormDataStreamProvider : MultipartFormDataStreamProvider
        {
            public CustomMultipartFormDataStreamProvider(string path) : base(path) { }
    
            public override string GetLocalFileName(HttpContentHeaders headers)
            {
                return headers.ContentDisposition.FileName.Replace("\"", string.Empty);
            }
        }
    }
    
Please Sign in or register to post replies

Write your reply to:

Draft