angularJs2 formData 傳有附件的請求

最近項目中需要提交個form中有上傳附件功能的需求,項目用的angular2版本,UI用的PrimeNG開源框架,這裏的upload file的控件就是已經是框架提供了的。https://www.primefaces.org/primeng/#/setup  感興趣的可以去這個官網學習下。可以用npm命令去下載。


官方的原本控件應該是這個樣子,但是這個控件只能點擊Upload方法去提交附件,而且有些屬性在我的項目中並沒有起作用估計是我用的版本太低問題,比如customUpload,還有方法,導致很多功能不能用。不過最終我是在commponent引入Jquery,來做了這個需求。hidden upload的按鈕,在import頭上聲明 declare var $: any就可以了,之前頭文件必須添加jquery的引用。

最簡單的直接用css樣式,找到這個標籤然後display設置爲None.

 $("[icon='fa-upload']").css("display", "none");


在控件中加onSelect 和 onClear方法,做對fileList的保存還有清除。

      <p-fileUpload #uploadFileId name="UploadFiles[]" url="" multiple="multiple" accept="image/*" maxFileSize="5000000" 
                    (onSelect)="myUploader($event)" (onClear)="removeAll($event)" cancelLabel="Remove"></p-fileUpload>
                     <div class="ui-message ui-messages-error ui-corner-all" *ngIf="attachmentShowError">
                         <i class="fa fa-close"></i>
                             {{attachmentErrorMessage}}
                      </div>
    myUploader(event: any) {
        for (let file of event.files) {
            if (!this.validatorsService.isContains(this.uiConfigModel._acceptFileType, file.type)) {
                this.attachmentShowError = true;
                this.attachmentErrorMessage = 'allowed file types ' + this.uiConfigModel._acceptFileType;
            } else {
                this.attachmentShowError = false;
            }
            this.uploadedFiles.push(file);
        }
        setTimeout(function removeDeleteBtn() {
            if ($('div[class="ui-fileupload-row"]') && $('button[icon="fa-close"]')) {
                $('div[class="ui-fileupload-row"] button[icon="fa-close"]').css("display", "none");
            }
        }, 50)
    }

    removeAll(event: any) {
        this.uploadedFiles.splice(0, this.uploadedFiles.length);
        this.attachmentShowError = false;
    }
這樣在做submit的時候,就可以在component中拿到上傳的fileList了。這是以前的代碼,用的 http.post ng封裝好的post請求方法,不知道哪裏出錯,有文件的數據,傳出去怎麼都是接收不到,換了各種 Content-Type,都還是接收不到,通過F12看,才發現每次Ng都會自動給這個設置成 ‘application/json’的格式,無論用delete還是set都不行,設置Undefined也是自動用的json傳的數據。最終放棄用jquery ajax直接去發請求ok.

    saveAbsenceRequest(RequestModel: any) {
        let headers = new Headers();
        headers.append('X-Requested-With', 'XMLHttpRequest');
        //headers.append('Content-Type', 'application/x-www-form-urlencoded');
        //headers.set('Content-Type', undefined);
        headers.delete("Content-Type");
        //headers.append('Accept', 'application/json');
        let myOptions = new RequestOptions({ headers: headers });
        //return this.http.post('./LeaveInfo/SaveAbsenceRequest', { data: RequestModel }, myOptions).toPromise()
        //    .then(res => <AbsenceRequestModal>res.json().data)
        //    .then(data => { return data; });
    }

創建一個新的form用來穿formdata, 如果有file文件就append到form上。

var formData = new FormData();

this.absenceReuqest.Duration = value["duration"];

formData.append('RequestModel', JSON.stringify(this.absenceReuqest));       

  for (var i = 0; i < this.uploadedFiles.length; i++) {
                if (!this.validatorsService.isContains(this.uiConfigModel._acceptFileType, this.uploadedFiles[i].type))
                {
                    this.loading = false;
                    this.attachmentShowError = true;
                    this.attachmentErrorMessage = 'allowed file types ' + this.uiConfigModel._acceptFileType;
                    return false;
                }
                formData.append("UploadFiles", this.uploadedFiles[i]);
然後直接用ajax 發請求,然後順利拿到form的所有數據。還有 由於在TS裏直接用ajax中請求,js代碼就不會被編譯,所以在success 或者 error裏用 TS的屬性還有一些功能就不會生效了,所以要拿到外面,最好用同步發請求 這樣就可以拿到返回的值就可以做 成功還是失敗後的功能了。

 $.ajax({
                    url: './LeaveInfo/SaveRequest',
                    data: formData,
                    type: 'POST',
                    contentType: false,
                    processData: false,
                    async: false,
                    success: function (data: any) {
                        if (data.data.IsSuccess) {
                            messageFlag = "success";
                        } else {
                            messageFlag = "failure";
                        }
                    },
                    error: function (err: any) {
                        messageFlag = "failure";
                    }
                });

後臺C#code: 用json convert到自己的實體裏。如果有文件就加進一個list中。最終轉成base64 string存在數據庫中。

        public ActionResult SaveRequest()
        {
            if (Request.Form["RequestModel"] == null) return null;
            var absenceRequestModel = Newtonsoft.Json.JsonConvert.DeserializeObject<AbsenceRequestModel>(Request.Form["RequestModel"]);
            if (Request.Files.Count > 0)
            {
                var AttachmentFiles = new List<Attachmentfiles>();
                for (int i = 0; i < Request.Files.Count; i++)
                {
                    var attachment = new Attachmentfiles
                    {
                        FileContent = GetAttachmentContent(Request.Files[i]),
                        FileName = Request.Files[i].FileName
                    };
                    AttachmentFiles.Add(attachment);
                }
                absenceRequestList.Attachements = AttachmentFiles;
            }
}
        private string GetAttachmentContent(HttpPostedFileBase file)
        {
            byte[] fileContentData;
            using (var inputStream = file.InputStream)
            {
                var memoryStream = inputStream as MemoryStream;

                if (memoryStream == null)
                {
                    memoryStream = new MemoryStream();
                    inputStream.CopyTo(memoryStream);
                }

                fileContentData = memoryStream.ToArray();
            }
            var FileStr = Convert.ToBase64String(fileContentData);
            return FileStr;
        }


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章