【问题标题】:Angular Post Error Incorrect Content-Type: application/jsonAngular Post 错误内容类型不正确:application/json
【发布时间】:2021-07-27 19:29:50
【问题描述】:

我正在使用 .Net Core Web api 和 Angular 构建一个 POST 请求,其中我将一个带有上传文件的 json 对象发送到服务器。在 Postman 中一切正常,但是当我从 Angular 应用程序发出相同的请求时,我收到以下错误。 System.InvalidOperationException: Incorrect Content-Type: application/json 我的用户界面代码... `` // 显示键/值对 console.log(Object.entries(frmData));//返回一个空数组! 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
  }
)

``

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

这是我的标题的屏幕截图。

更新 httpheader 后收到其他错误...

在这里我更新了标头以包含 responseType,但我仍然收到相同的 Failed to read the request form 错误。

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

设置'Content-Type': undefined 而不是'Content-Type': 'multipart/form-data',可以防止请求完全发送到服务器!

更新响应类型...

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

【问题讨论】:

  • 从角度你是附加文件然后向服务器发布请求吗?
  • 您确实应该提供有关您尝试过的其他信息。没有任何示例,我猜这与您通过 Angular 请求发送的标头有关,默认情况下,Angular 发送 application/json 作为内容类型。
  • 我更新了我的问题以包含我的标题的屏幕截图。
  • @carltonstith 您的 api 会为您提供文本响应,因此您还需要在 post 请求中设置 response:text。或者,如果您有表单,那么您也可以使用 formData ,并将此表单数据传递给发布请求
  • @carltonstith 'Content-Type': 'multipart/form-data') 你只需要设置这个,也可以为你工作

标签: .net angular asp.net-core-webapi


【解决方案1】:

Content-Type 标头指示您在请求中“发送”的数据类型。

您最初将其设置为“multipart/form-data”,但随后将其覆盖为 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
}

您的端点需要表单数据,因为您在参数中使用了 [FromForm]。

您的屏幕截图显示“application/json”的标头不正确。

记住 Content-Type 告诉您发送的内容,Accept 告诉您期望返回的内容。

所以在这种情况下,您的 Content-Type 应该是“multipart/form-data”,如果您希望返回 json,那么您的 Accept 应该是“application/json”。

此外,如果您想从端点返回 json,我通常喜欢返回 ObjectResult 而不是 Ok,如下所示:

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

我发现返回 ObjectResult 可以正确设置响应标头。同样,建议总是从 json 端点返回一些类。

例如,我总是创建一个类:

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

我所有的 api 端点都返回那个类,这样我就可以有一个“标准”的方式从我的 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);
            //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);
        }
    }
}

最后,如果你所有的端点都返回 json,我会像这样装饰我的控制器:

[ApiController]
[Produces("application/json")]//this also helps with the response headers
public class MyController: ControllerBase
{
//a bunch of cool endpoint here
}

【讨论】:

  • 我更新了 UI 代码,然后是服务器代码。每次更改我都会收到以下错误{ "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 您能否更新问题中的代码以反映这些更改,以便我查看代码并尝试重现。我很乐意帮助您进一步解决此问题。
猜你喜欢
  • 2015-08-13
  • 2018-03-22
  • 1970-01-01
  • 2015-09-07
  • 2013-06-28
  • 1970-01-01
  • 1970-01-01
  • 2020-04-21
  • 2022-12-22
相关资源
最近更新 更多