Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Upload image to Web Api 2 Using angular 5

I have looked at several SO question and answer but not able to solve my problem. My code is like below:

HTML

 <input type="file" id="file" accept="image/*" name="File" (change)="handleFileInput($event.target.files)">
 <button type="button" mat-raised-button color="primary" (click)="uploadFileToActivity()">Upload</button>

Component

  handleFileInput(files: FileList) {
    this.fileToUpload = files.item(0);
  }

  uploadFileToActivity() {

    this._dishAddService.postFile(this.fileToUpload).subscribe(data => {

      }, error => {
        console.log(error);
      });
  }

Service

 postFile(fileToUpload: File): Observable<boolean> {
    const formData: FormData = new FormData();
    formData.append('fileKey', fileToUpload, fileToUpload.name);
    let headers = new Headers({ 'Content-Type': 'application/json' });    
    headers.append('Content-Type', 'multipart/form-data');

    let options = new RequestOptions({ headers: headers, method: 'post' });
    return this.http.post(this.httpRequestUrl + 'api/dish/UploadDishImage', formData, options)
      .map(
        (response => response.json()))
      .catch(CommonFunctionService.handleError);
  }

API

   [HttpPost]
    [ActionName("UploadDishImage")]
    public HttpResponseMessage UploadJsonFile()
    {
        HttpResponseMessage response = new HttpResponseMessage();
        var httpRequest = HttpContext.Current.Request;
        if (httpRequest.Files.Count > 0)
        {
            foreach (string file in httpRequest.Files)
            {
                var postedFile = httpRequest.Files[file];
                var filePath = HttpContext.Current.Server.MapPath("~/UploadFile/" + postedFile.FileName);
                postedFile.SaveAs(filePath);
            }
        }
        return response;
    }

When request hit the API, files count is 0. I have spent whole two days to figure out what is going wrong but also not able to figure out wrong. I don't think there is wrong with the code because for some other it is working. I took code from different SO accepted answer. Could anybody help me figure out what might have gone wrong?

like image 873
Amir Avatar asked Feb 12 '18 12:02

Amir


2 Answers

This way I implement upload image to web API in project.

I share for whom concern.

    const formData: FormData = new FormData();
    formData.append('Image', image, image.name);
    formData.append('ComponentId', componentId);
    return this.http.post('/api/dashboard/UploadImage', formData);

Step by step

[HttpPost]
[Route("api/dashboard/UploadImage")]
public HttpResponseMessage UploadImage()
        {
            string imageName = null;
            var httpRequest = HttpContext.Current.Request;
            //Upload Image
            var postedFile = httpRequest.Files["Image"];
            //Create custom filename
            if (postedFile != null)
            {
                imageName = new String(Path.GetFileNameWithoutExtension(postedFile.FileName).Take(10).ToArray()).Replace(" ", "-");
                imageName = imageName + DateTime.Now.ToString("yymmssfff") + Path.GetExtension(postedFile.FileName);
                var filePath = HttpContext.Current.Server.MapPath("~/Images/" + imageName);
                postedFile.SaveAs(filePath);
            }
}

HTML form

<form #imageForm=ngForm (ngSubmit)="OnSubmit(Image)">

                    <img [src]="imageUrl" class="imgArea">
                    <div class="image-upload">
                        <label for="file-input">
                            <img src="upload.jpg" />
                        </label>

                        <input id="file-input" #Image type="file" (change)="handleFileInput($event.target.files)"/>
                        <button type="submit" class="btn-large btn-submit" [disabled]="Image.value=='' || !imageForm.valid"><i class="material-icons">save</i></button>
                    </div>
                </form>

TS file to use API

OnSubmit(Image) {
    this.dashboardService.uploadImage(this.componentId, this.fileToUpload).subscribe(
      data => {
        console.log('done');
        Image.value = null;
        this.imageUrl = "/assets/img/logo.png";
      }
    );
  }

Service TS

uploadImage(componentId, image) {
        const formData: FormData = new FormData();
        formData.append('Image', image, image.name);
        formData.append('ComponentId', componentId);
        return this.http.post('/api/dashboard/UploadImage', formData);
    }
like image 51
Hien Nguyen Avatar answered Oct 13 '22 06:10

Hien Nguyen


FileUpload is super easy with angular. You can either use this description here or follow my steps.

In your component template just attach a change event to your input and let it call a function which handles the files to upload. $event.target.files includes your files.

<input type="file" (change)="upload($event.target.files)">

in your components class you need to import your files.service.ts (or what ever you called it) and provide it either in your regarding module or in the component itself if you don't want to reuse it.

import { FilesService } from 'PATHTO/files.service';
[...]
contructor(private filesService: FilesService) { }

Then you can implement the following function in your component class for a single file upload, otherwise cycle through files.item and attach it to formData

upload(files: FileList) {
  const file = files.item(0);

  this.filesService.upload(file).subscribe(
    res => /* Place your success actions here */,
    error => /* Place your error actions here */
  );
}

Make sure you have defined an url attribute in your environment or replace the post url with a static one. The files.service.ts for example can look like this

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

import { Observable } from 'rxjs/Observable';
import { environment } from 'PATHTO/environments/environment';

@Injectable()
export class FilesService {

  constructor(private http: HttpClient) { }

  upload(file: File): Observable<Object> {
    const formData: FormData = new FormData();
    formData.append('avatar', file, file.name);

    return this.http.post(`${environment.url}avatar.php`, formData);
  }
}

For example on php server side you are then able to catch those files with $_FILES variable. Don't know very much about Asp.net but I think there has to be an equivalence.

Hope this helps, have a nice day! Cheers.

like image 2
Felix Lemke Avatar answered Oct 13 '22 06:10

Felix Lemke