【问题标题】:Failed to load resource: the server responded with a status of 400 () error: Angular asp.net core 5 api加载资源失败:服务器响应状态为 400 () 错误:Angular asp.net core 5 api
【发布时间】:2021-09-05 00:49:31
【问题描述】:

我正在开发一个前端使用 Angular 12 和 API 中使用 ASP.net core 5 的应用程序。调用 HttpPost API 时出现错误加载资源失败:服务器响应状态为 400 ()

如果我使用字符串或整数参数,则没有问题,并且 API 被正确调用。但只有当我使用实体类传递值时,我才会收到此错误。

这是我在 asp.net core 中的实体类

public class FrontEnd
{ 
  public class SendOTPReq
    {
        public string MobileNo { get; set; }
        public string Email { get; set; }
        public int Type { get; set; }
    }
}

这里是 API

    [Route("SendOTP")]
    [HttpPost]
    public async Task<object> SendOTP(SendOTPReq otpReq)
    {
        try
        {
            CommonApiResponse commonResponse = new CommonApiResponse();

            if (!ModelState.IsValid)
            {
                return new APIResponse(406, "", ModelState.Select(t => new { t.Key, t.Value.Errors[0].ErrorMessage }));
            }
            var Result = await _IFrontEndRepository.SendOTP(otpReq);
            if (Result != null)
            {
                commonResponse.Status = "Success";
                commonResponse.ErrorMsg = "";
                commonResponse.ResultData = Result;
                return new APIResponse(200, "Request Success", commonResponse);
            }
            else
            {
                commonResponse.Status = "Failed";
                commonResponse.ErrorMsg = Result.Message;
                commonResponse.ResultData = Result;
                return new APIResponse(204, "Request Failed", commonResponse);
            }
        }
        catch (Exception e)
        {

            throw new Exception(e.Message);
        }

    }

这是我的 angular component.ts 代码:

const otpReq = new SendOTPReq();

otpReq.MobileNo = this.registerForm.controls['phoneNo'].value;
otpReq.Email = this.registerForm.controls['email'].value;
otpReq.Type = 2; //2 is or email and 1 is for sms

this.accountsService.sendOTP(otpReq).subscribe(      
  (data) => {
         //do stuff here
    
         });

Angular 服务方法:

export class AccountsService {

constructor(private httpClient: HttpClient,
private _router: Router) { }

 sendOTP(otpReq: SendOTPReq): Observable<SendOTPReq> {
  debugger;
  return this.httpClient.post<SendOTPReq>(environment.ApiUrl + 'FrontEnd/SendOTP', otpReq)
    .pipe(
      catchError(this.errorHandler),
    );
}


errorHandler(error: { error: { message: string; }; status: undefined; message: any; }) {
  debugger;
  let errorMessage = '';
  if (error.error instanceof ErrorEvent) {
    // Get client-side error
    errorMessage = error.error.message;
  } else {
    // Get server-side error
    if(error.status == undefined)
    {
      errorMessage = "The server connection with the application is showing error. Close the application and restart again."
    }else{
    errorMessage = `Error Code: ${error.status}\nMessage: ${error.message}`;
    }
  }      
  return throwError(errorMessage);
}

}

角度模型类:

export class SendOTPReq
{
  MobileNo!:string;
  Email!: string;
  Type!: number;
}

可能出了什么问题?

【问题讨论】:

  • 为什么将 SendOTPReq 作为嵌套类?尝试从类 FrontEnd 中删除它

标签: angular asp.net-core-webapi http-status-code-400 asp.net-core-5.0 angular12


【解决方案1】:

您的 POST 请求的返回类型错误。当您的 Angular httpClient 要求返回 SendOTPReq 时,您不能让控制器返回 object

所以你需要

return this.httpClient.post<MyActualReturnType>(environment.ApiUrl + 'FrontEnd/SendOTP', otpReq)

【讨论】:

  • 感谢您的回复。我认为我犯了一个多么愚蠢的错误,但即使在更正之后,它也不起作用。
  • 嗯.. 我可以看到您也没有在请求选项中添加观察:'body'。不过,这个错误只会导致客户端错误,而不是我所知道的 400 响应。你可以试试
  • 试过..不工作..我需要在 API 端更改什么吗?
【解决方案2】:

尝试在您的 API 中添加一个 [FromBody] 装饰器,如下所示:

public async Task<object> SendOTP([FromBody]SendOTPReq otpReq)

更新:基于这个和其他答案的 cmets,似乎设置一些错误处理以及在您的 POST 请求中更详细一点可能会更清楚地了解导致问题的原因。假设你的 API 中有我上面描述的 [FromBody] 装饰器,让我们进一步增强专注于返回类型的 API,以及使用 RxJs 的 Angular 中的服务函数,看看我们是否能以某种方式从中提取更有用的响应.

为了清晰和总结,取消嵌套您的 SendOtpReq 类:

public class SendOTPReq
{
    public string MobileNo { get; set; }
    public string Email { get; set; }
    public int Type { get; set; }
}

接下来,我们将控制器 POST 方法的返回类型调整为 IActionResult:

[Route("SendOTP")]
[HttpPost]
public async Task<IActionResult> SendOTP([FromBody]SendOTPReq otpReq)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }

    try
    {                
        var Result = await _IFrontEndRepository.SendOTP(otpReq);
        if (Result != null)
        {
            return Ok(Result);                       
        }

        return BadRequest($"Fail to POST");    
     }
     catch (Exception ex)
     {    
         return BadRequest($"Fail to POST");
     }

 }

现在,让我们使用您的角度服务来观察 API 的整个响应,而不仅仅是正文:

public sendOTP(otpReq: SendOTPReq): Observable<HttpResponse<SendOTPReq>> {
  return this.httpClient.post<SendOTPReq>(environment.ApiUrl +
             'FrontEnd/SendOTP', otpReq { observe: "response" })
             .pipe(
             catchError(this.errorHandler),
    );
}

【讨论】:

  • 是的,我做到了..仍然无法正常工作...如果我通过 rcv 字符串或整数,它可以正常工作
  • 为什么将 SendOTPReq 作为嵌套类?尝试将其从 FrontEnd 类中删除 - Per Serge 对您的原始问题的评论。
  • 是的,我做到了..但它仍然无法正常工作。
  • 谢谢@cklimowski.. 绝对可以从中学到很多东西.. 实现这个..
【解决方案3】:

所以,最后,我修复了它。评论属性和取消评论一个接一个。当我从“mobileNo”字段中获取数据时,我没有将其转换为字符串。将手机号码转换为字符串。

我换行了:

otpReq.MobileNo = this.registerForm.controls['phoneNo'].value;

otpReq.MobileNo = this.registerForm.controls['phoneNo'].value.toString();

【讨论】:

    猜你喜欢
    • 2021-04-12
    • 1970-01-01
    • 2022-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-17
    • 2016-09-19
    • 2020-09-21
    相关资源
    最近更新 更多