我有一个 .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 时,我都不会收到错误消息。
我错过了什么?
使用下面的代码对我来说工作得很好:
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; }
}
}
输出:
如果给空 {} 它给出:
如果我们输入的类型为空:
{
"appointment": {
"type": "",
"publicId":"8"
}
}
如果我们输入的 publicId 为空:
{
"appointment": {
"type": "create",
"publicId":""
}
}
如果我们正确给出所有值: