簡體   English   中英

我如何通過AngularJS視圖/控制器將文件上傳到C#代碼背后?

[英]How can I upload a file to C# code-behind via an AngularJS view/controller?

我有一個Angular視圖和控制器,它從幾種形式收集用戶數據。 然后,來自Angular代碼的數據將傳遞到幾個C#類。 用戶數據當前作為IEnumerable <>對象進入C#。 此集合具有FormData類型,該類型是6個屬性的自定義類(無方法)。 所有用戶數據都通過IEnumerable <>對象存儲在FormData類的'Data'屬性中,並且'Data'屬性是一個字符串。 因為“數據”是字符串,所以任何輸入C#的文件上傳都是字符串,而不是實際文件。 這是視圖:

<div data-ng-controller="customFormController as formController" data-ng-init="formController.init(@Model.Form, '@Model.EmailResults', '@Model.EmailTo')">
    <div data-ng-if="!formController.loading && !formController.submitted" mc-form data-on-submit="formController.submit(model, formData)" data-on-file-select="formController.fileSelect(e)">
    <!--form fields are added dynamically via a separate set of Angular/C# controllers-->
</div>
</div>

這是控制器的一部分:

self.submit = function (model, formData) {

                var deferred = $q.defer();

                var formPostData = {
                    formId: self.formId,
                    data: formData,
                    emailData: self.emailData,
                    emailTo: self.emailTo,
                    saveData: true
                };

                customFormService.postData(formPostData).then(function (result) {

                    self.submitted = true;
                    deferred.resolve(result);

                    window.location.href = '#form-' + self.formId;

                    // push any files
                    if (typeof window.FormData !== 'undefined' && result) {
                        var formData = new FormData();

                        if (fileList && fileList.length) {
                            for (var f in fileList) {
                                if (fileList.hasOwnProperty(f)) {
                                    formData.append('file', fileList[f]);
                                    console.log('Files added to formData property');
}
                            }
                            customFormService.postFiles(result.data, formData);
                            console.log('files posted to customFormService');
                        }
                    }
                }, function (err) {
                    deferred.reject(err);
                });
                return deferred.promise;
            }
//Here's the file-select method:
            self.fileSelect = function (e) {
                for (var x = 0; x < e.length; x++) {
                    fileList.push(e[x]);
                }
            }

抱歉,這很long。 有沒有一種方法可以使用Angular控制器獲取實際的文件對象(而不僅僅是JSON字符串),並使用C#訪問該對象? 謝謝!

基本上,您需要提交一個包含文件輸入的表單,然后在服務器上將其作為多部分表單數據進行處理。 這些文件將作為流出現。

這是一個示例代碼,可以幫助您入門:

http://www.strathweb.com/2012/08/a-guide-to-asynchronous-file-uploads-in-asp-net-web-api-rtm/

下面列出了該問題的完整解決方案:

//get files from custom form controls
self.fileSelect = function (files) {
    var reader = new FileReader();
    reader.onload = function (e) {
        console.log("about to encode");
        $scope.encoded_file = btoa(e.target.result.toString());
    };
    reader.readAsBinaryString(files[0]);
    self.file = files[0];
    filesFromFileSelect.push(files[0]);
}

//need to post files one at a time. a loop iterates through the files array.
customFormService.postFiles(filesFromFileSelect[i], formDataForFile, self.formId, strResult, formFieldId)
    .success(function (data) {
        self.submitted = true;
        console.log('file posted', data);
    })
    .error(function (data) {
        self.submitted = false;
        console.log('error posting file. Message: ', data);
    });

//inside the service posting the files...
function postFiles(postfile, formData, formId, strResult, formFieldId) {
    var fd = new FormData();
    fd.append("data", JSON.stringify(formData));
    fd.append('file', postfile);

    return $http.post('/api/customformfile/post?id=' + formId + '&submissionGuid=' + strResult + '&formFieldId=' + formFieldId, fd, {
                withCredentials: false,
                headers: {
                    'Content-Type': undefined
                },
                transformRequest: angular.identity
            });
    }

//essential parts of the server-side controller handling the files...
var httpPostedFile = HttpContext.Current.Request.Files["file"];
if (httpPostedFile != null) {
    var savePath = "\\someFile\someOtherFile";
}

try {
    var uploadsDirectory = savePath;
    string pathToCheck = savePath + fileName;
    char[] charsToTrim = { '"', '\\', '/' };
    string trimmedFileName = fileName.Trim(charsToTrim).Replace(' ', '_');
    string tempFileName = trimmedFileName;

    if (File.Exists(pathToCheck))
    {
        int copyCount = 2;
        while (File.Exists(pathToCheck))
        {
            //insert copy number of file before file extension
            if (tempFileName.IndexOf('.') != -1)
            {
                tempFileName = trimmedFileName.Insert(trimmedFileName.IndexOf('.'), "_(" + copyCount + ")");
            }

            pathToCheck = savePath + tempFileName;
            copyCount++;
        }
        httpPostedFile.SaveAs(Path.Combine(uploadsDirectory, tempFileName));
    }
    else
    {
    httpPostedFile.SaveAs(Path.Combine(uploadsDirectory, trimmedFileName));
    }
}
catch(Exception fileEx) {
    //log the error
    return Request.CreateResponse(HttpStatusCode.InternalServerError, exc.Message);
}

一次處理一個文件是一種丑陋的方式,但是現在可以使用。 將來將研究其他方式來處理整個文件陣列而不是一次處理一個文件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM