How can I fix 415 unsupported media type on file upload in Angular 6

14,526

Solution 1

Follow steps below for a working demo:

  1. Controller

    [HttpPut("[Action]/{id}")]
    public async Task<ActionResult> LinkItemToIcon(int id, IFormFile file)
    {
        //your operation
    }
    
  2. Angular

    selectedFile : File = null;
    onSelectedFile(e){
        this.selectedFile = e.target.files[0];
    }
    linkItem(){
        var formData = new FormData();
        formData.append("file", this.selectedFile, this.selectedFile.name)
        this.LinkItemToIcon(1, formData).subscribe(
        r => console.log(r),
        err => console.log(err)
        )
    }
    LinkItemToIcon(id, formData) {
        return this.http.put(`api/SampleData/LinkItemToIcon/` + id, formData);
    }
    

Solution 2

Do you have to send it through javascript/Angular? There's a much less convoluted way to send it straight from the form:

<form id="yourid" action=".../yourpath/LinkItemToIcon" method="PUT" enctype="multipart/form-data">
 <input type="file" name="file"/>
 <input type="hidden" name="id" value="yourID"/>
 <button type="submit">
  <span>Submit</span>
 </button>
</form>

And if you have trouble with the id being passed you can just pass that via Attribute Routing

Share:
14,526
user10863293
Author by

user10863293

Updated on June 13, 2022

Comments

  • user10863293
    user10863293 almost 2 years

    I work on a .Net Core Web Api and an Angular application. I created a controller which links an image to an item in database:

    [HttpPut("[Action]/{id}")]
    public async Task<ActionResult<Item>> LinkItemToIcon(int id, IFormFile file)
    {
        var items = await _context.Items.FirstOrDefaultAsync(t => t.Id == id);
    
        if (items == null)
        {
            return BadRequest("item null");
        }
    
        if (file.Length <= 0)
        {
            return BadRequest("fileEmpty");
        }
    
        using (var memoryStream = new MemoryStream())
        {
            await file.CopyToAsync(memoryStream);
            Item item = new Item() { Id = items.Id, Icon = memoryStream.ToArray() };
            _context.Entry(items).CurrentValues.SetValues(item);
            _context.SaveChanges();
    
            return Ok(file);
        }
    }
    

    It works well in Postman, but when I want to use the controller, I get an error:

    Headers: HttpHeaders {normalizedNames: Map(0), lazyUpdate: null, headers: Map(0)} message: "Http failure response for https://localhost:5001/api/LinkItemToIcon: 415 Unsupported Media Type"
    name: "HttpErrorResponse"
    ok: false
    status: 415
    statusText: "Unsupported Media Type"
    url: "https://localhost:5001/api/LinkItemToIcon"

    You can see my html in my angular application :

    <input type="file" (change)="onSelectedFile($event) name="file">
    <input type="button" (click)="linkItem()">
    

    You can see my component :

    this.selectedFile : File = null ;
    onSelectedFile(e){
        this.selectedFile = e.target.files[0]
    }
    LinkItem(){
        var formData = new FormData();
        formData.append("file",this.selectedFile, this.selectedFile.name)
        this.administrator.LinkItemToIcon(1,formData).subscribe(
           r => console.log(r),
           err => console.log(err)
        )
    }
    

    And now my service:

      LinkItemToIcon(id,file){
    return this.http.put<UploadFile>(`${this.config.catchApiUrl()}Item/LinkItemToIcon/`+ id, file
    ,{
      headers : new HttpHeaders({
        'Content-Type' : 'application/json'
      })}
    )
    

    }

    My breakpoint result :

    Think you for your help. breakpoint result

    And I have an error message when I want to subscribe to linkItemToIcon

    FormData is not defined

    Moreover I can change in my code my content-type which is application/json to multipart/form-data because I have an

    PUT https://localhost:5001/api/Item/LinkItemToIcon/1 500 (Internal Server Error)

    Access to XMLHttpRequest at 'https://localhost:5001/api/Item/LinkItemToIcon/1' from origin 'http://localhost:4200' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

    HttpErrorResponse {headers: HttpHeaders, status: 0, statusText: "Unknown Error", url: null, ok: false, …}

  • CryptoChrisJames
    CryptoChrisJames over 5 years
    What happened? Was it the same error? What kind of file is it and what is the size?
  • CryptoChrisJames
    CryptoChrisJames over 5 years
    Okay, I just noticed that you are already using attribute routing for your action, so you can actually leave out that hidden field and change the method to method=".../yourpath/LinkItemToIcon/yourid". Did you try that?