网站搜索

c# - 尝试 httppost 时即时状态:400 “错误请求”


我已经翻遍了各处(Google/StackOverflow)寻找我的代码可能出错的地方……但是一整天都没有结果,所以现在我转向自己提出一个问题:我的服务类中有两个几乎相同的函数,它们会向我的 API/后台发送一个 POST 请求(而在后台/API 中也包含两个几乎相同的函数来接收这些请求)。一个工作得完美无缺,而另一个甚至在前端触发之前就生成了“status: 400”。在我的后台/API 中:

[HttpPost("Patients/update")] //not working
        public async Task<IActionResult> UpdatePatientAsync(Patient editedPatient)
        {
            try
            {
                _logger.LogDebug("APIController.UpdatePatientAsync() was called...");
                var updated = await _dbHandler.UpdatePatientAsync(editedPatient);
                if (updated)
                {
                    return Ok(updated);
                }
                else
                {
                    return BadRequest("Patient not updated!");
                }
            }
            catch
            {
                throw;
            }

        }
[HttpPost("Patients/comment/update")] //works GREAT!
        public async Task<IActionResult> UpdatePatientCommentAsync(PatientComment editedComment)
        {
            try
            {
                _logger.LogDebug("APIController.UpdatePatientComment() was called...");
                var updated = await _dbHandler.UpdatePatientCommentAsync(editedComment);
                if (updated)
                {
                    return Ok(editedComment);
                }
                else
                {
                    return BadRequest("Comment not updated.");
                }
            }
            catch
            {
                throw;
            }
        }

在我的服务中:

updatePatient(editedPatient: Patient): Observable<Patient> { //not working at all
        return this.http.post<Patient>(ConfigService.Config.apiBaseUrl + "/Patients/update", editedPatient).pipe(
            catchError(this.rHndlr.handleError("updatePatient", this.updatedPatient))
        )
    }
updatePatientComment(editedComment: PatientComment): Observable<PatientComment>{ //works (again) GREAT!
        return this.http.post<PatientComment>(ConfigService.Config.apiBaseUrl + "/Patients/comment/update", editedComment).pipe(
            catchError(this.rHndlr.handleError("updatePatientComment", this.updatedComment))
        )
    }

以及它们是如何被称呼的:

updatePatient(updatedPatient: Patient): Promise<Patient> {
        this.loading = {
            loadingText: "Updating patient",
            errorText: "Comment update failed, try something else.",
            errorTextVisible: false
        }

        const promise = new Promise<Patient>((resolve, reject) => {
            this.patientSvc.updatePatient(updatedPatient).subscribe({ //NOT EVEN CLOSE TO WORKING!!!
                next: (data: Patient) => {
                    if (JSON.stringify(updatedPatient) === JSON.stringify(data)) {
                        console.log("Success updating patient!")
                    }
                },
                error: (err) => {
                    alert("Error updating patient data!\n" + JSON.stringify(err));
                },
                complete: () => {
                    resolve(this.patient);
                }
            })
        });
        return promise;
    }
updatePatientComment(editedComment: PatientComment): Promise<PatientComment> {
        this.loading = {
            loadingText: "Updating comment",
            errorText: "Comment update failed, try something else.",
            errorTextVisible: false
        }

        const promise = new Promise<PatientComment>((resolve, reject) => {
            this.patientSvc.updatePatientComment(editedComment).subscribe({ //WORKING!!!
                next: (data: PatientComment) => {
                    if(JSON.stringify(editedComment) === JSON.stringify(data)){
                        console.log("Success updating comment!");
                        this.commentChanged = false;
                    }
                },
                error: (err) => {
                    alert("Error updating comment! \n" + JSON.stringify(err));
                },
                complete: () => {
                    resolve(this.patientComment);
                }
            })
        });
        return promise;
    }

以及手头上的两个物体:

export interface Patient {
    id: number;
    socialSecurityNumber: string;
    firstName: string;
    lastName: string;
    diagnosisId: number;
    riskAssessmentId: number;
    deceasedDate?: number;
    commentId: number;
    clinicId: number;    
    active: boolean;
    staffId: number;
}
export interface PatientComment {
    id: number,
    commentText: string,
    commentDate: Date,
    signature: string
}

(发布的对象是从相应类的 get 函数中获取的相同对象,只是稍微修改了 lastName(针对 Patient)和 commentText(针对 PatientComment)) 我想我的问题是:我是否遗漏了什么显而易见的东西?是不是 Patient 对象的大小太大了呢?再次强调,在更新 Patient 时,我甚至在调用还没开始处理就收到了 400 状态码……并且后端的 post 方法甚至没有被触发——而对于 PatientComment 一切正常,并且每当我调用端点时,我可以在后端的方法上触发断点。我已经使用 Swagger 和 Postman 测试了 API,它们在那里似乎都能工作(虽然我对它们的使用经验不是特别丰富,所以我可能漏掉了什么)。有什么想法吗?

我已经使用 Swagger/Postman 触发了两个 API 方法,并且我在 VS Code 中调试了这个过程——对服务类中 'catchError' 提供的错误消息的每一部分都进行了谷歌搜索:

{"headers":{"normalizedNames":{},"lazyUpdate":null},"status":400,"statusText":"错误的请求","url":"https://localhost:62006/api/Patients/update","ok":false,"name":"HttpErrorResponse","message":"对 https://localhost:62006/api/Patients/update 的 HTTP 失败响应:400 错误的请求","error":{"type":"https://tools.ietf.org/html/rfc7231#section-6.5.1","title":"发生了一个或多个验证错误。"}} ","状态":400,"追踪ID":"00-f1e88aa13075736f6590b352c4afe68f-64f8c787e1bbcc8b-00","错误":{"工作人员":["工作人员字段为必填项。"],"诊所":["诊所字段为必填项。"],"诊断":["诊断字段为必填项。"],"患者评论":["患者评论字段为必填项。"],"风险评估":["风险评估字段为必填项。"]}}}

我已经尝试了太多的解决方案,甚至数都数不过来(大多数来自 StackOverflow 上的其他帖子),即使它们只是类似的问题。API 的地址(localhost:whatever)对两个调用都是一样的,完全正确,并且端点已经从后端复制粘贴过来了以防万一。我尝试过提供预检数据({headers: {'Content-Type':"application/json"}})、用 .put 代替 .post、更改端点地址设置、尝试其他本地主机端口、将 JSON.stringify(editedPatient) 作为请求体……但是没有任何效果(显然)。我唯一能收集到的信息是,由于后端的断点从未触发,这应该是一个前端相关的问题……但此刻,我几乎都不确定自己的名字了 :P

答案#1

在错误响应中,它说明 Patient 类的一些字段是必填的,所以当它尝试将响应体绑定到你的端点的 editedPatient 参数时,你会在方法甚至执行之前就收到 400 错误。

所以我猜测你很可能在 POST 请求的正文中缺少一些 Patient 属性。

答案#2

回复包含请求被拒绝的原因:

"errors": {
    "Staff": [
        "The Staff field is required."
    ],
    "Clinic": [
        "The Clinic field is required."
    ],
    "Diagnosis": [
        "The Diagnosis field is required."
    ],
    "PatientComment": [
        "The PatientComment field is required."
    ],
    "RiskAssessment": [
        "The RiskAssessment field is required."
    ]
}

在 pdatePatientAsync(Patient editedPatient) 中设置断点,找出对象未完全填充的原因。