即使应用了必需的属性,数据注释也无法按预期工作

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

我有一个 .NET 6.0 中的模型类并应用了数据注释。我有扩展类

ApiRequestValidation
,在检查请求正文中的 JSON 后返回
validationresults

using System.ComponentModel.DataAnnotations;
using Newtonsoft.Json;

public class ExternalNotificationRequest
{
    /// <summary>
    /// Appointment details
    /// </summary>
    [Required(AllowEmptyStrings = false, ErrorMessage = "Please provide a appointment object values.")]
    [JsonProperty("appointment")]
    public Appointment? Appointment { get; set; }
}

public class Appointment
{
    /// <summary>
    /// Notification type such as Create/Update/Delete
    /// </summary>
    [JsonProperty("type")]
    [Required(AllowEmptyStrings = false, ErrorMessage = "Please provide a appointment type. Valid values are  CREATE,UPDATE,DELETE.")]
    public string? Type { get; set; }

    /// <summary>
    /// appointment public id
    /// </summary>
    [JsonProperty("publicId")]
    [MaxLength(64)]
    [MinLength(64)]
    [Required(AllowEmptyStrings = false, ErrorMessage = "Please provide an appointment public id.")]
    public string? PublicId { get; set; }
}

 public static class ApiRequestValidation
 {
    public static bool IsValid(this object request, out ICollection<ValidationResult> validationResults)
    {
        validationResults = new List<ValidationResult>();
        return Validator.TryValidateObject(request, new ValidationContext(request), validationResults, true);
    }
 }

我在 Azure 函数中使用

ApiRequestValidation

ExternalNotificationRequest externalNotificationRequest = new ExternalNotificationRequest();
_logger.LogInformation("{FunctionName} Request Body: {requestBody}", functionName, requestBody);

externalNotificationRequest = 
    JsonConvert.DeserializeObject<ExternalNotificationRequest>(requestBody) 
        ?? new ExternalNotificationRequest();

// Validate Data Annotations.
if (!externalNotificationRequest.IsValid(validationResults: out var validationResults))
{
    return messageExtensions.RenderApiMessage(_logger, StatusCodes.Status400BadRequest, validationResults.Select(s => s.ErrorMessage).FirstOrDefault(), functionName, validationResults.Select(s => s.MemberNames.FirstOrDefault()).FirstOrDefault().ToString());
}

JSON 数据示例:

{
    "appointment": {
        "type": "create",
        "publicId": ""
    }
}

测试用例:使用此 JSON,我的数据注释无法正常工作。每当

publicId
为空或为 null 时,我都不会收到错误消息。

我错过了什么?

c# .net azure-functions data-annotations
1个回答
0
投票

使用下面的代码对我来说工作得很好:

using System.ComponentModel.DataAnnotations;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;

namespace FunctionApp159
{
    public class Function1
    {
        private readonly ILogger<Function1> rithlogger;

        public Function1(ILogger<Function1> logger)
        {
            rithlogger = logger;
        }

        [Function("Function1")]
        public async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequestData req)
        {
            rithlogger.LogInformation("Hello Rithwik Bojja!!! Function Started ");
            string rithrb = await new StreamReader(req.Body).ReadToEndAsync();
            rithlogger.LogInformation("Request Body: {requestBody}", rithrb);
            ExternalNotificationRequest ENR;
            try
            {
                ENR = JsonConvert.DeserializeObject<ExternalNotificationRequest>(rithrb);
            }
            catch (JsonException ex)
            {
                rithlogger.LogError(ex, "Hello Rithwik Bojja!!! Error deserializing request body.");
                return new BadRequestObjectResult("Hello Rithwik Bojja!!! Invalid JSON format.");
            }

            if (ENR.Appointment == null)
            {
                rithlogger.LogError("Hello Rithwik Bojja!!! Appointment object is missing.");
                return new BadRequestObjectResult("Hello Rithwik Bojja!!! Appointment object is missing. Please provide an appointment.");
            }

            ICollection<ValidationResult> validationResults;
            if (!ENR.IsValid(out validationResults))
            {
                var errMsg = validationResults.Select(vr => vr.ErrorMessage).FirstOrDefault();
                var memnam = validationResults.Select(vr => vr.MemberNames.FirstOrDefault()).FirstOrDefault()?.ToString();
                rithlogger.LogError("Hello Rithwik Bojja!!! Validation failed for {MemberName}: {ErrorMessage}", memnam, errMsg);
                return new BadRequestObjectResult($"Hello Rithwik Bojja!!! Validation failed for {memnam}: {errMsg}");
            }

            return new OkObjectResult("Hello Rithwik Bojja!!! Request processed successfully!");
        }
    }

    public class ExternalNotificationRequest
    {
        [Required(ErrorMessage = "Please provide an appointment.")]
        [MinLength(1, ErrorMessage = "Please provide an appointment public id.")]
        public RithAppoint? Appointment { get; set; }

        public bool IsValid(out ICollection<ValidationResult> validationResults)
        {
            validationResults = new List<ValidationResult>();
            if (Appointment != null)
            {
                return Validator.TryValidateObject(Appointment, new ValidationContext(Appointment), validationResults, true);
            }
            return false;
        }
    }

    public class RithAppoint
    {
        [Required(ErrorMessage = "Please provide an appointment type.")]
        [MinLength(1, ErrorMessage = "Please provide an appointment public id.")]
        public string? Type { get; set; }

        [Required(ErrorMessage = "Please provide an appointment public id.")]
        [MinLength(1, ErrorMessage = "Please provide an appointment public id.")]
        public string? PublicId { get; set; }
    }
}

输出:

如果给空 {} 它给出:

enter image description here

如果我们输入的类型为空:

{
    "appointment": {
        "type": "",
        "publicId":"8"
    }
}

enter image description here

如果我们输入的 publicId 为空:

{
    "appointment": {
        "type": "create",
        "publicId":""
    }
}

enter image description here

如果我们正确给出所有值:

enter image description here

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