0

I'm building a POST request using .Net Core web api and Angular where I'm sending a json object with an uploaded filed to the server. Everything works fine in Postman but when I make the same request from the Angular application, I'm getting the following error. System.InvalidOperationException: Incorrect Content-Type: application/json My UI code... `` // Display the key/value pairs console.log(Object.entries(frmData));//returns an empty array! var options = {content: frmData};

//submit this after the job id is returned
let httpOptions = {
  headers: new HttpHeaders(
      { 
        //'Content-Type': 'application/json',
        'Content-Type': 'multipart/form-data',
        'Referer': 'http://localhost:4200',
        'Origin': 'http://localhost:4200',
        //'Accept': 'application/json',
        'Accept': '*/*',
        'Authorization':'Bearer '+ this.loadToken()
      }
    ).set('content-type','application/json').set('content-length','6')
};
this.httpService.post("http://localhost:63052/api/Document_ADD", options,httpOptions).subscribe(
  data => {
    debugger
    console.log(data);
  },
  (err: HttpErrorResponse) => {
    console.log(err.message); //Show error, if any
  }
)

``

Web API

[HttpPost]
    public async Task<IActionResult> InsertCustomer_Document_ADDResult([FromForm] Customer_Document_ADD customer_Document_ADDED)
    {
        var reqFile = Request.Form.Files.First();

        using (Stream stream = reqFile.OpenReadStream())
        {
            using (var binaryReader = new BinaryReader(stream))
            {
                var fileContent = binaryReader.ReadBytes((int)stream.Length);
                customer_Document_ADDED.file_data = fileContent;
                var result = await _repository.InsertCustomer_Document_ADDResult(customer_Document_ADDED);
                return Ok(result);
            }
        }

        //return Ok(await _repository.InsertCustomer_Document_ADDResult(customer_Document_ADDED));
    }

Here is a screenshot of my headers. enter image description here

Additional error received after updating httpheader...

enter image description here

Here I've updated the headers to include responseType, but I'm still getting the same Failed to read the request form error.

//submit this after the job id is returned
let httpOptions = {
  headers: new HttpHeaders(
      { 
        //'Content-Type': 'application/json',
        'Content-Type': 'multipart/form-data',
        'Referer': 'http://localhost:4200',
        'Origin': 'http://localhost:4200',
        'Accept': 'application/json',
        //'Accept': '*/*',
        'Authorization':'Bearer '+ this.loadToken()
      }
    ),responseType: 'text' as 'text'
    //.set('content-type','application/json').set('content-length','6')
};
this.httpService.post("http://localhost:63052/api/Customer_Document_ADD", options,httpOptions).subscribe(
  data => {
    debugger
    console.log(data);
  },
  (err: HttpErrorResponse) => {
    console.log(err.message); //Show error, if any
  }
)

Setting 'Content-Type': undefined instead of 'Content-Type': 'multipart/form-data', prevents the request getting sent to the server completely!

Updated responseType...

console.log(Object.entries(frmData));//returns an empty array!
    var options = {content: frmData};

    //submit this after the job id is returned
    let httpOptions = {
      headers: new HttpHeaders(
          { 
            //'Content-Type': 'application/json',
            'Content-Type': 'multipart/form-data',
            // 'Content-Type': undefined,//this disables this request from being sent
            'Referer': 'http://localhost:4200',
            'Origin': 'http://localhost:4200',
            'Accept': 'application/json',
            //'Accept': '*/*',
            'Authorization':'Bearer '+ this.loadToken()
          }
        ),responseType: 'text' as const
        //.set('content-type','application/json').set('content-length','6')
    };
    this.httpService.post("http://localhost:63052/api/Customer_Document_ADD", options,httpOptions).subscribe(
      data => {
        debugger
        console.log(data);
      },
      (err: HttpErrorResponse) => {
        console.log(err.message); //Show error, if any
      }
    )
9
  • from angular are you attaching file and then to post request to server ? Commented May 5, 2021 at 13:06
  • You really should provide additional information on what you've tried. Without any examples, I'd guess it would be to do with the headers you're sending with the Angular request, by default angular sends application/json as the content type. Commented May 5, 2021 at 13:08
  • I updated my question to include a screen shot of my headers. Commented May 5, 2021 at 13:19
  • 1
    @carltonstith your api gives you text response, so you need to set response:text in post request too. and and alternatively if you have form then you can use formData too , and pass this form data to post request Commented May 5, 2021 at 14:15
  • @carltonstith 'Content-Type': 'multipart/form-data') you need to set only this and will work for you too Commented May 5, 2021 at 14:21

1 Answer 1

2

Content-Type header indicates what kind of data you are "sending" in the request.

You are originally setting it to 'multipart/form-data' but then you overwrite it to application/json.

let httpOptions = {
  headers: new HttpHeaders(
      { 
        //'Content-Type': 'application/json',
        'Content-Type': 'multipart/form-data',//here you set it to form data
        'Referer': 'http://localhost:4200',
        'Origin': 'http://localhost:4200',
        //'Accept': 'application/json',
        'Accept': '*/*',
        'Authorization':'Bearer '+ this.loadToken()
      }
    ).set('content-type','application/json').set('content-length','6')// here you overwrite it to application/json
}

Your endpoint expects form data because you are using [FromForm] in the parameter.

Your screenshot shows that the incorrect header of "application/json" is being sent.

Remember Content-Type tells what you are sending and Accept tells what you expect back.

So in this case your Content-Type should be 'multipart/form-data' and if you expect json back your Accept should be 'application/json'.

Also if you want to return json from your endpoint i usually like to return ObjectResult instead of Ok like this:

return new ObjectResul(result);//this is better for returning json from an api endpoint. It will properly set the header in the response

I have found that returning an ObjectResult properly sets the response headers. Also just as little piece of advice it is better to always return some class from a json endpoint.

For example I always create a class like:

public class DataResult<TResult>
{
    public bool Success { get; set; }
    public TResult Content { get; set; }
}

The all my api endpoints return that class that way I can have a "standard" way to get "responses" from my api.

In this case the pseudo code looks something like this:

[HttpPost]
public async Task<IActionResult> InsertCustomer_Document_ADDResult([FromForm] Customer_Document_ADD customer_Document_ADDED)
{
    var reqFile = Request.Form.Files.First();

    using (Stream stream = reqFile.OpenReadStream())
    {
        using (var binaryReader = new BinaryReader(stream))
        {
            var fileContent = binaryReader.ReadBytes((int)stream.Length);
            customer_Document_ADDED.file_data = fileContent;
            var result = await _repository.InsertCustomer_Document_ADDResult(customer_Document_ADDED);
            //lets imagine that result is a strin but it can be anything
            var dataResult = new DataResult<string> { Success = true, Content = result };
            return new ObjectResult(dataResult);
        }
    }
}

And last if all your endpoints return json I would decorate my controllers like this:

[ApiController]
[Produces("application/json")]//this also helps with the response headers
public class MyController: ControllerBase
{
//a bunch of cool endpoint here
}
Sign up to request clarification or add additional context in comments.

2 Comments

I updated the UI code, then the server code. With each change I'm getting the following error { "errors": { "": [ "Failed to read the request form. Missing content-type boundary." ] }, "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1", "title": "One or more validation errors occurred.", "status": 400, "traceId": "|6471eeca-47a2c60ff554f308." }
@carltonstith can you please update your code in the question to reflect these changes so I can take a look at the code and try to reproduce. I will be happy to help you further to fix this issue.

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.