使用Angular 5 Reactive Form和ASP.NET Core Web API进行文件上载

时间:2018-01-26 09:13:02

标签: angular asp.net-core angular5 asp.net-core-webapi

我有一个有两个嵌套F​​ormGroup的复杂形式。每个嵌套的FormGroup包含一个文件输入字段以及其他6个输入字段如下:

在组件中:

updateEmployeeNomineeForm: FormGroup;

ngOnInit() {
   this.updateEmployeeNomineeForm = this.formBuilder.group({
      employeeNominee1: this.formBuilder.group({
        employeeId: [employeeId],
        nomineeName: [],
        nomineeRelation: [],
        nomineeContactNo: [],
        nomineeNationalId: [],
        nomineePicture: [], // This is the file input
        additionalInfo: []
      }),
      employeeNominee2: this.formBuilder.group({
        employeeId: [employeeId],
        nomineeName: [],
        nomineeRelation: [],
        nomineeContactNo: [],
        nomineeNationalId: [],
        nomineePicture: [], // This is the file input
        additionalInfo: []
      })
    });
  }

HTML表单如下所示:

<div *ngIf="updateEmployeeNomineeForm">
    <form [formGroup]="updateEmployeeNomineeForm" (ngSubmit)="updateEmployeeNominees()">
      <div class="row">
        <div class="col-md-6">
          <div class="card">
            <div class="card-header">
              <strong>Nominee-1</strong>
            </div>
            <div formGroupName="employeeNominee1" class="card-body">

             //Other inputs omitted for Clarity

              <div class="form-group row">
                <label class="col-md-4 col-form-label">Nominee Picture</label>
                <div class="custom-file col-md-8">
                  <input type="file"  #nomineePicture1 formControlName="nomineePicture" class="form-control">
                </div>
              </div>
            </div>
          </div>
        </div>
        <div class="col-md-6">
          <div class="card">
            <div class="card-header">
              <strong>Nominee-2</strong>
            </div>
            <div formGroupName="employeeNominee2" class="card-body">

              //Other inputs omitted for Clarity

              <div class="form-group row">
                <label class="col-md-4 col-form-label">Nominee Picture</label>
                <div class="custom-file col-md-8">
                  <input type="file" #nomineePicture2 formControlName="nomineePicture" class="form-control">
                </div>
              </div>

            </div>
          </div>
        </div>
      </div>
      <br />
      <div class="text-center">
        <button type="submit" [disabled]="!updateEmployeeNomineeForm.valid" class="btn btn-success text-white"><i class="fa fa-floppy-o" aria-hidden="true"></i> Submit</button>

    </form>

  </div>

现在,Component中的 updateEmployeeNominees()方法如下:

updateEmployeeNominees(): void {
    this.employeeService.updateEmployeeNominees(this.updateEmployeeNomineeForm.value).subscribe((updateStatus) => {
      if (updateStatus) {
        this.resetUpdateEmployeeNominees();
        this.updateSuccessMessage = "Employee Nominees updated successfully!";
        setTimeout(() => {
          this.updateSuccessMessage = null;
        }, 4000);
      }
    }, (error) => {
      this.serverErrorMessage = this.errorMessageService.getServerErrorMessageText();
    });
  }

现在 EmployeeService 中的updateEmployeeNominees()方法如下:

updateEmployeeNominees(employeeNominees: any): Observable<any> {
    const body = JSON.stringify(employeeNominees);
    const headerOptions = new HttpHeaders({ 'Content-Type': 'application/json' });
    return this.http.put<any>(this.baseUrl + 'UpdateEmployeeNominees/'+ employeeId, body, {
      headers: headerOptions
    }).catch(this.handleError);
  }

在ASP.NET Core Web Api控制器中:

[HttpPut("{id}")]
public async Task<IActionResult> UpdateEmployeeNominees([FromRoute] int id,[FromBody] EmployeeNomineesViewModel employeeNominees)
{
            //Necessary operation goes here
            return Ok(true);
}

除了nomineePictures上传之外,一切都按预期工作。在将表单发布到ASP.NET Web API控制器方法时,是否有人帮我将图像文件绑定到输入字段。

2 个答案:

答案 0 :(得分:0)

你无法直接获取图像。要获得图像,你必须采取一些解决方法。添加(change)事件进行输入

html

<div class="custom-file col-md-8">
                  <input type="file" (change)="getfile($event)" formControlName="nomineePicture" class="form-control">
                </div>

ts档案

public file: File;

getfile(e: any) {

  const fileList: FileList = e.target.files;
        this.file = fileList[0];

}

updateEmployeeNominees(): void {

console.log(this.file); // this will give you the file
console.log(this.updateEmployeeNomineeForm.value); this will give you formdata

}

答案 1 :(得分:0)

使用本机浏览器FileReader来读取文件的内容。重量免责声明:这些代码都没有经过测试,我只是在记事本中写出来了。你应该知道如果copypaste不起作用,intellisense将帮助其他人。 ; d

模板

<input #fileInput type="file"/>

component.ts

@ViewChild('fileInput') fileInput: ElementRef;
get files() {
    return this.fileInput.nativeElement.files;
}
async submit() {
    if (!this.files.length) {
        console.error('Please select a file');
        return;
    }
    const fileContents = (await Promise.all(
        this.files.map(file => this.readFile(file))
    ).map(dataUrl => this.stripDataUrl(dataUrl));
    // Each item in FileContents is now a Base64 encoded string.
    // Post 'em to server and convert them there to a blob for saving as a file, or whatever you like.     
    // If you want to know the MIME type before posting, 
    // scrap that stripDataUrl() method and extract mime from the dataUrl.
    // DataUrls are formatted like 'data:image/png;base64,xxxxxxzzz'
}

/**
 *  @return a string without the encoding type and mime
 */
stripDataUrl(dataUrl) {
    return dataUrl.split(',')[1];
}

readFile(file) {
    return new Promise((resolve, reject) => {
        var reader = new FileReader();
        reader.onload = (e: any) => {
            resolve(e.target.result);
        };
        reader.readAsDataURL(file);
    });
}

您还可以显示所选图像的预览:

模板

<img *ngIf="(thumb$|async); let thumb" [src]="thumb" class="thumbnail" />

component.ts

thumb$: Observable<string>;
ngOnInit() {
    this.thumb$ = Observable.fromEvent(this.fileInput.nativeElement, 'change')
        .filter(event => !!event.target.files.length)
        .switchMap(event => Observable.fromPromise(this.readFile(event.target.files[0])))
        .filter(dataUrl => /image/i.test(dataUrl));
}