4

I have Angular CLI application and Dot net core 2.0 Web API. which I need to upload the file from Angular to Web API. from Web API to Server. When I use Http its working fine. When using HttpClient, it's not working. Here is my component.ts code:

fileChange(event, grdvalue) {
debugger;
let fileList: FileList = event.target.files;
if (fileList.length > 0) {
  let file: File = fileList[0];
  const formData: FormData = new FormData();
  let GridName = grdvalue;

  formData.append('file', file, file.name);
  formData.append('Id', this.userId);
  formData.append('GridValue', GridName)

  this.myService.PostFileToAzure(formData).subscribe(details => {
    debugger;
  },
    (error) => {
      debugger;
    })
  }
 }

here is My Service Code:

 PostFileToAzure(form) {
    debugger;
    var body = JSON.stringify(form);
    return this.http.post(this.baseApiURL + '/Interpretation/InterpreterFileUpload', form);
}

Here is my Web API code:

[HttpPost("InterpreterFileUpload")]
    public async Task<IActionResult> InterpreterFileUpload()
    {
        try
        {

            var file = Request.Form.Files[0];
            HttpRequest formData = HttpContext.Request;
        }
    }

How to do send the file using HttpClient From Angular to Web API. Am getting an error in web API like 'Incorrect Content-Type: application/json'

1
  • 2
    Do not JSON.stringify your form Commented Dec 4, 2018 at 13:18

3 Answers 3

13

At angular site use this code

file: any;

onSelectFile($event, file) {
    this.file = file;
  }


  uploadImage() {
    if (this.file.length === 0) {
      return;
    }

    const formData = new FormData();

    for (let file of this.file)
      formData.append(file.name, file);

    const uploadReq = new HttpRequest('POST', `api/FileUpload`, formData, {
      reportProgress: true,
    });

    this.http.request(uploadReq).subscribe(event => {
      if (event.type === HttpEventType.UploadProgress) {
        this.progress = Math.round(100 * event.loaded / event.total);
      }
    });
  }

here onSelectFile should be called on input like this

<input #file type='file' multiple (change)="onSelectFile($event, file.files)">

And at your asp.net site use this code

[Produces("application/json")]
    [Route("api/[controller]")]
    public class FileUploadController : Controller
    {
    private IHostingEnvironment _hostingEnvironment;

    public FileUploadController(IHostingEnvironment hostingEnvironment)
    {
      _hostingEnvironment = hostingEnvironment;
    }

    [HttpPost, DisableRequestSizeLimit]
    public ObjectResult UploadFile()
    {
      try
      {
        var file = Request.Form.Files[0];
        string folderName = "Upload";
        string webRootPath = _hostingEnvironment.WebRootPath;
        string newPath = Path.Combine(webRootPath, folderName);
        if (!Directory.Exists(newPath))
        {
          Directory.CreateDirectory(newPath);
        }
        string fileName = "";
        if (file.Length > 0)
        {
          fileName = ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Trim('"');
          string fullPath = Path.Combine(newPath, fileName);
          using (var stream = new FileStream(fullPath, FileMode.Create))
          {
            file.CopyTo(stream);
          }
        }

        return Ok(fileName);
      }
      catch (System.Exception ex)
      {
        return BadRequest(ex.Message);
      }
    }
  }

Thanks

Sign up to request clarification or add additional context in comments.

4 Comments

This is time saving answer Mr.
hi,how can i access response from server?
@Ali7091 the uploaded file will be uploaded inside wwwroot folder so you can access that file directly from there. Example locahost:66363/Upload/filename.png
@ElonMusk no, i mean final response from server, i found my answer, it is in event.body, thank you
1

https://github.com/BhadraAnirban/angular_file_upload_net_core

The process is to send the base64 string from Angular using POST call in the FormBody and at .net core convert the string to byte.

Note - FormData will not work in AWS Lambda properly, it will corrupt the file. So this is a better approach to send mail or upload file in AWS as well.

HTML -

<form class="row">
    <input id="{{id}}" type="file" (change)="FileSelected($event.target.files);">
</form>
<div id="hidden_upload_item" style="display: none;"></div>

Typescript -

FileSelected(files){
    this.fileData = <File>files[0];
    this.FileName = this.fileData.name;
    let reader = new FileReader();
    var selectedFile = <File>files[0];

    reader.onload = function (readerEvt: any) {
        var arrayBuffer = readerEvt.target.result.toString().split('base64,')[1];     
        document.querySelector('#hidden_upload_item').innerHTML = arrayBuffer;
        this.Proceed();
    }.bind(this);
    reader.readAsDataURL(selectedFile);

  }

  Proceed()
  {
    var item = document.querySelector('#hidden_upload_item').innerHTML;
    let formdata = new UploadFile();
    formdata.data = item;
    formdata.name = this.FileName;
    this.UploadDocument(formdata)
      .subscribe(event => {
        // Perform other operations
      }, err => {
        this.InProgress = false;
      });
  }

  UploadDocument(formData){
        const httpOptions = {
          headers: new HttpHeaders({
            'Content-Type': 'application/json'
          })
        };
        return this.http.post('/api/document/uploaddocument', formData, httpOptions);
      } 

.net Core -

[HttpPost("uploaddocument"), DisableRequestSizeLimit]
public IActionResult UploadDocument([FromBody] FileModel fileModel)
        {
            try
            {
                    var value = fileModel.Data;
                    var byteArray = Convert.FromBase64String(value);
                    var fileExtension = Path.GetExtension(fileModel.Name);
                    var fileName = fileModel.Name;

                    /// Now save in Database or AWS

                }
                return Ok();
            }
            catch (Exception e)
            {
                throw e;
            }

        }        

 public class FileModel
{
    public string Data { get; set; }
    public string Name { get; set; }
}

1 Comment

var byteArray = Convert.FromBase64String(value); will cause an exception if it is not a base64 string.
0

I had used the solution of @Elon Musk but Request.Form.Files[0]gives me the Evaluation timeout exception, so to handle it, I have added the Iformfile parameter in Actionmethod in .net side

public IActionResult UploadFile(IFormFile formfile)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.