当反序列化因缺少必填字段而失败时,是否有比 500 响应更合适的方式在 ASP.NET 中给出验证错误?

问题描述 投票:0回答:1

设置上下文:

  1. 我有一个 yaml oapi 文件
  2. 我使用 OpenAPI 生成器创建 C# 类
  3. 某些属性具有
    [IsRequired = true]
    属性

当请求中未包含必需的属性时,反序列化将失败并返回 500 响应。在这种情况下,我的代码甚至从未被命中。

我相信,如果问题是缺少字段,则应给出 400 响应,并且理想情况下,应包含问题字段的描述。

我想到的这个问题的第一个解决方案是简单地删除

[IsRequired = true]
属性并自行验证,这就是我目前正在做的事情。但是,我不喜欢这个解决方案,因为如果更新了 oapi 规范,那么我将想要再次运行 OpenAPI 生成器,这会将其恢复到原始状态。另外,这样做会导致我丢失有关我的应用程序中需要哪些字段的元数据,这在我自己进行验证时实际上很有用。

  1. 是否有适当的“微软”方式来处理这个问题?
  2. 如果没有,开发人员通常可以处理此问题是否有任何标准或准标准方法?

这似乎是一个相当常见的场景,我很难相信每个人都满足于让服务器返回 500 个错误,只是因为序列化器的默认行为是在缺少必填字段时抛出异常...并且该步骤发生在您的代码被命中之前,因此您无能为力。

或者也许3)我有办法拦截反序列化过程来处理此类异常吗?

c# azure-functions deserialization httpresponse
1个回答
0
投票

当请求中未包含必需的属性时,反序列化将失败并返回 500 响应。在这种情况下,我的代码甚至从未被命中。 我相信,如果问题是缺少字段,则应给出 400 响应,并且理想情况下,应包含问题字段的描述

是的,默认情况下,如果不发送所需参数,就会出现 500 错误。

为了避免我使用自定义异常处理,如下所示:

using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System;

namespace FunctionApp83
{
    public static class Function1
    {
        public class RithwikModel
        {
            [Required(ErrorMessage = "The 'name' field is required.")]
            public string Id { get; set; }

        }

        [FunctionName("Function1")]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");

            try
            {
                string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
                RithwikModel res = JsonConvert.DeserializeObject<RithwikModel>(requestBody);

                var validationResults = new List<ValidationResult>();
                if (!Validator.TryValidateObject(res, new ValidationContext(res), validationResults, true))
                {
                    var errors = new BadRequestObjectResult(validationResults);
                    return errors;
                }

                string responseMessage = $"Hello Rithwik, {res.Id}. This HTTP triggered function executed successfully.";
                return new OkObjectResult(responseMessage);
            }
            catch (Exception ex)
            {
                log.LogError($"Error processing request: {ex.Message}");
                return new BadRequestObjectResult("Hello Rithwik Invalid request payload");
            }
        }
    }
}

Output:

当您不发送(任何主体)所需参数时:

enter image description here

当您发送一些不同于所需的有效负载时:

enter image description here

当您发送所需参数时:

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.