0

I'm using the following POST in order to send both Files and some data(type: 'application/json').

This is my code where sending the data :

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);
  }
  

Then, I'm trying to extract the data in my server side.

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);
                        }
                    }
                }
             }

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

R. Richards
  • 24,603
  • 10
  • 64
  • 64
JumpIntoTheWater
  • 1,306
  • 2
  • 19
  • 46

2 Answers2

1

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

Based on your Angular client side code, we can find that the data field's value is a Blob that represents a file-like object of immutable, raw data.

And if you capture request and check the actual form data you posted in browser developer tool Network tab, you can find the value of data field is treated as binary data, like below.

represents a file-like object of immutable, raw data.

To achieve the requirement, you can extract data from Files collection in your server side action method, like below.

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);
    }

Test Result

enter image description here

Besides, if possible, you can modify the client side code to pass name as string through formdata.

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

On server side, to extract data using following code snippet.

var name = formdata["name"].ToString();
Fei Han
  • 26,415
  • 1
  • 30
  • 41
-1

We can handle forms two ways:

  • Template-driven
  • Reactive

Here I am sharing code for simple template-driven forms. If you want to do it using reactive forms then check this link: Angular2 reactive form confirm equality of values

Your module file should have these:

        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)

Simple registration html file:

<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>

Now your registration.ts file should be like this:

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.
  }
}
Kavinda Senarathne
  • 1,813
  • 13
  • 15
  • sorry, but how is this answering my question regarding the `null` value posted to my server? I am also using Template Driven in this case by the way. – JumpIntoTheWater Nov 26 '20 at 18:45