在WebApi的Asp Core 2.2中创建自定义返回错误验证

时间:2019-03-24 08:53:09

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

我需要在WebApi的Asp Core 2.2中创建“创建自定义退货验证”。

第一步:

我在OnResultExecuting上创建了一个:

public override void OnResultExecuting(ResultExecutingContext context)
{
 if (context.Result is BadRequestObjectResult badRequestObjectResult)
        {
            var message = badRequestObjectResult.Value.ToString();
            if (badRequestObjectResult.Value is SerializableError errors)
            {
                var errorMessages = errors.SelectMany(p => (string[])p.Value).Distinct();
                message = string.Join(" | ", errorMessages);
            }
            context.Result = new JsonResult(new ReturnResult(false, ResultStatus.BadRequest, message))
            { StatusCode = badRequestObjectResult.StatusCode };
        }
}

第二步

i在IValidatableObject中创建一个UserDto

 public class UserDto : IValidatableObject
{
    [Required]
    public string Name { get; set; }
    [Required]
    public string Family { get; set; }
    [Required]
    public string Password { get; set; }
    [Required]
    public string Username { get; set; }
    [Required]
    public string Email { get; set; }
    [Required]
    public string Phone { get; set; }
    [Required]
    public GenderType Gender { get; set; }


    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        foreach (var item in ValidateList.UsernameBanList)
            if (Username.Equals(item, StringComparison.OrdinalIgnoreCase))
                yield return new ValidationResult("Username Invalid", new[] { nameof(Username) });
        foreach (var item in ValidateList.PasswordBanList)
            if (Password.Equals(item, StringComparison.OrdinalIgnoreCase))
                yield return new ValidationResult("Password Invalid, new[] { nameof(Password) });
        foreach (var item in ValidateList.EmailBanList)
            if (Email.Equals(item, StringComparison.OrdinalIgnoreCase))
                yield return new ValidationResult("Email Invalid", new[] { nameof(Email) });
    }
}

第三步

我创建了一个ReturnResult类:

public class ReturnResult
{
    public bool Success { get; }
    public ResultStatus Status { get; }
    public string Message { get; }

    public ReturnResult(bool Success, ResultStatus Status, string Message = null)
    {
        this.Success = Success;
        this.Status = Status;
        this.Message = Message ?? Status.ToDisplay();
    }

    #region implicit operator
    public static implicit operator ReturnResult(OkResult result)
    {
        return new ReturnResult(true, ResultStatus.Success);
    }

    public static implicit operator ReturnResult(BadRequestResult result)
    {
        return new ReturnResult(false, ResultStatus.BadRequest);
    }

    public static implicit operator ReturnResult(BadRequestObjectResult result)
    {
        var message = result.ToString();
        if (result.Value is SerializableError error)
        {
            var errorMessage = error.SelectMany(p => (string[])p.Value).Distinct();
            message = string.Join(" | ", errorMessage);
        }
        return new ReturnResult(false, ResultStatus.BadRequest, message);
    }

    public static implicit operator ReturnResult(ContentResult result)
    {
        return new ReturnResult(true, ResultStatus.Success, result.Content);
    }

    public static implicit operator ReturnResult(NotFoundResult result)
    {
        return new ReturnResult(false, ResultStatus.NotFound);
    }
    #endregion
}

现在按以下格式在Api中返回所有信息:

{
"success": true,
"status": 0,
"message": "success process"
 }

UserDto中,我为用户名,密码和电子邮件创建了一个验证人,然后我需要按以下格式返回它们的所有错误:

{
"success": true,
"status": 0,
"message": "Email Invalid | Password Invalid | Username Invalid"
 }

但没有以这种格式显示我,而是以这种格式显示:

{
"success": false,
"status": 2,
"message": "Microsoft.AspNetCore.Mvc.ValidationProblemDetails"
 }

我该如何解决这个问题??

1 个答案:

答案 0 :(得分:1)

尝试:

public static implicit operator ReturnResult(BadRequestObjectResult result)
        {
            System.Reflection.PropertyInfo pi = result.Value.GetType().GetProperty("Errors");
            Dictionary<string, string[]> errors = (Dictionary<string, string[]>)(pi.GetValue(result.Value, null));

            var message = result.ToString();
            var errorMessage = error.SelectMany(p => p.Value).Distinct();
            message = string.Join(" | ", errorMessage);
            return new ReturnResult(false, ResultStatus.BadRequest, message);
        }