.Net Core 2.1在Validate(...)方法之外验证模型

时间:2018-12-17 19:16:51

标签: c# asp.net-core .net-core

因此,我正在.NET Core 2.1中构建API,并希望在模型更新之前对其进行验证。因此,我决定实现IValidatableObject,该方法对简单模型非常有效。

但是,我现在想验证开发者发送给我的请求的格式;也就是说,我希望验证器不仅验证Validate方法,而且还捕获可能已在对象其他位置产生的ValidationResult对象。

我的课程:

public class Dad : IValidatableObject
{
    public long Id { get; set; }
    [Required]
    public Kid Kid { get; set; }

    public IEnumerable<ValidationResult> UpdateProperties(JObject props)
    {
        if (props["Kid"]["Id"] == null)
            yield return new ValidationResult("The correct format to set the Kid of Dad is {\"Kid\":{\"Id\":100}}");
    }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        if (Kid.Height <= 170)
            yield return new ValidationResult("Kids need to be taller than 170.")
    }
}

public class Kid
{
    public long Id { get; set; }
    public int Height { get; set; } = 180;
}

我的控制器:

[HttpPatch("{id}")]
public async Task<IActionResult> PatchDad([FromRoute] long id, [FromBody] JObject props)
{
    Dad dad = _context.Dads.Find(id);

    dad.UpdateProperties(props);

    List<ValidationResult> Errors = new List<ValidationResult>();
    bool IsValid = Validator.TryValidateObject(dad, new ValidationContext(dad, serviceProvider: null, items: null), Errors);

    // I need the Validator to catch errors that occur in the Dad.UpdateProperties field !

    if (!IsValid)
        return BadRequestObjectResult(Errors);

        return NoContent();
    }

使用原始数据发送请求PUT /Dad/19{"KidId":100}会产生两个错误。第一个说参数格式不正确,第二个说要求Kid

1 个答案:

答案 0 :(得分:0)

好的-如果你们想出更好/更清洁的东西,我很乐意将其标记为该问题的答案,但是与此同时,如果有人登陆此页面,我只是简单地实现了使用ValidationResult的私有列表进行的肮脏解决方案,该列表可以从任何地方更新:

public class Dad : IValidatableObject
{
    public long Id { get; set; }
    [Required]
    public Kid Kid { get; set; }

    [NotMapped, JsonIgnore]
    pricate List<ValidationResult> ValidationResults = new List<ValidationResult>();
    public void UpdateProperties(JObject props)
    {
        if (props["Kid"]["Id"] == null)
            ValidationResults.Add(new ValidationResult("The correct format to set the Kid of Dad is {\"Kid\":{\"Id\":100}}", new string[] { "Kid" }));
    }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        if (Kid.Height <= 170)
            yield return new ValidationResult("Kids need to be taller than 170.")

        if (ValidationResults.Count > 0)
                foreach (ValidationResult r in ValidationResults)
                    yield return r;
    }
}