我正在设法弄清如何满足我的服务消费者的需求。
在POST正文中,我发送了一个json对象。不需要任何字段。它们都是可选的。但是,消费者希望检测到空的{}或假的{{adaf:“ 32345”}实体并返回错误。
我目前正在使用ActionFilterAttribute来捕获必填字段,但是当这两种情况通过此行时,我无法弄清楚如何处理这两种情况:
varvalidationAttribute = attributeInstance作为ValidationAttribute;
因为它们是可选的,因此没有ValidationAttribute
有效的POST正文json是这两者之一...或无关紧要:
{
amount: 123.45,
age: 65
}
我的api签名:
[HttpPost]
[Route("/....blah")]
[ValidateModelState]
public async Task<Resp> AgePost([FromBody]AgeMoney)
{ .... }
我的ValidationFilter:
public class ValidateModelStateAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
// Per https://blog.markvincze.com/how-to-validate-action-parameters-with-dataannotation-attributes/
var descriptor = context.ActionDescriptor as ControllerActionDescriptor;
if (descriptor != null)
{
foreach (var parameter in descriptor.MethodInfo.GetParameters())
{
object args = null;
if (context.ActionArguments.ContainsKey(parameter.Name))
{
args = context.ActionArguments[parameter.Name];
}
ValidateAttributes(parameter, args, context.ModelState);
}
}
if (!context.ModelState.IsValid)
{
throw new BadRequestException("The following fields from the request body failed model validation: " + string.Join(", ", context.ModelState.Keys));
}
}
private void ValidateAttributes(ParameterInfo parameter, object args, ModelStateDictionary modelState)
{
foreach (var attributeData in parameter.CustomAttributes)
{
var attributeInstance = parameter.GetCustomAttribute(attributeData.AttributeType);
var validationAttribute = attributeInstance as ValidationAttribute;
if (validationAttribute != null)
{
var isValid = validationAttribute.IsValid(args);
if (!isValid)
{
modelState.AddModelError(parameter.Name, validationAttribute.FormatErrorMessage(parameter.Name));
}
}
}
}
}
}
任何想法都值得赞赏。 TIA
答案 0 :(得分:0)
我想出了一种使用反射的方法。随时发表评论/改进。总是渴望学习。
public class ValidateModelStateAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
//snipped for brevity. See OP for full implementation
IsAllNullOrEmpty(args);
ValidateAttributes(parameter, args, context.ModelState);
}
}
public void IsAllNullOrEmpty(object myObject)
{
//Get the object so we don't have to keep calling reflection
var obj = myObject.GetType();
//Get a count of how many properties there are
var propCount = obj.GetProperties().Count();
var areAllNullOrEmpty = obj.GetProperties()
.Select(pi => pi.GetValue(myObject))
.Count(value => value == null);
if (areAllNullOrEmpty == propCount)
{ throw new BadRequestException("The request body failed model validation."); }
}