从 FormData 中提取数据

extracting data from FormData

我正在使用以下 POST 来发送 Files 和一些数据 (type: 'application/json')

这是我发送数据的代码:

save(data: IRishum, filesA: File[]): Observable<any> {
    const formData = new FormData();
  
    // add the files
    if (filesA && filesA.length) {
      Array.from(filesA).forEach(file => formData.append('filesA', file));
    }
  
    // add the data object
    formData.append('data', new Blob([JSON.stringify(data)], {type: 'application/json'}));
    console.log(formData.getAll("filesA"));
    return this._httpClient.post<IRishum>(this.apiUrl, formData);
  }
  

然后,我尝试在我的服务器端提取数据。

public async Task<ResultOfOperation<int>> Rishum(IFormCollection formdata)
        {
            
            var result =  new ResultOfOperation<int>();
            try
            {
                var name = formdata["data"];

                var files = HttpContext.Request.Form.Files;
                foreach (var file in files)
                {
                    var uploads = Path.Combine(_environment.ContentRootPath, "Images");
                    if (file.Length > 0)
                    {
                        string FileName = Guid.NewGuid().ToString(); // Give file name
                        using (var fileStream = new FileStream(Path.Combine(uploads, FileName), FileMode.Create))
                        {
                            await file.CopyToAsync(fileStream);
                        }
                    }
                }
             }

但是,name 为空。所以可能我做错了什么。

我们可以通过两种方式处理表单:

  • 模板驱动
  • 被动

我在这里分享简单的模板驱动表单的代码。如果你想使用反应形式来做,那么检查这个 link:

你的模块文件应该有这些:

        import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'
        import { ReactiveFormsModule, FormsModule } from '@angular/forms';
        import { MyApp } from './components'
        
        @NgModule({
          imports: [
            BrowserModule,
            FormsModule,
            ReactiveFormsModule
          ],
          declarations: [MyApp],
          bootstrap: [MyApp]
        })
    
    export class MyAppModule { }

platformBrowserDynamic().bootstrapModule(MyAppModule)

简单注册html文件:

<form #signupForm="ngForm" (ngSubmit)="registerUser(signupForm)">
  <label for="email">Email</label>
  <input type="text" name="email" id="email" ngModel>

  <label for="password">Password</label>
  <input type="password" name="password" id="password" ngModel>

  <button type="submit">Sign Up</button>
</form>

现在你的 registration.ts 文件应该是这样的:

import { Component } from '@angular/core';
import { NgForm } from '@angular/forms';

@Component({
  selector: 'register-form',
  templateUrl: 'app/register-form.component.html',
})
export class RegisterForm {
  registerUser(form: NgForm) {
    console.log(form.value);
    // {email: '...', password: '...'}
    // ... <-- now use JSON.stringify() to convert form values to json.
  }
}

name is null. So probably I'm doing something wrong.

根据您的 Angular 客户端代码,我们可以发现 data 字段的值是一个 Blob,表示不可变原始数据的类文件对象。

如果您捕获请求并检查您在浏览器开发人员工具网络选项卡中发布的实际表单数据,您会发现 data 字段的值被视为二进制数据,如下所示。

为达到要求,您可以在服务器端操作方法中从文件集合中提取 data,如下所示。

public async Task<ResultOfOperation<int>> Rishum(IFormCollection formdata)
{
    //...

    using (var sr = new StreamReader(formdata.Files["data"].OpenReadStream()))
    {
        var data = await sr.ReadToEndAsync();

        var name = System.Text.Json.JsonSerializer.Deserialize<string>(data);
    }

测试结果

此外,如果可能,您可以修改客户端代码以通过 formdata 将名称作为字符串传递。

formData.append("name","name_here");

在服务器端,使用以下代码片段提取数据。

var name = formdata["name"].ToString();