在.netcore api中不使用模型的情况下验证查询参数 [英] Validate query parameters without using a model in .netcore api

查看:504
本文介绍了在.netcore api中不使用模型的情况下验证查询参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以在不使用模型的情况下验证操作的查询参数?我的API中的许多调用都是一次性的,如果只使用一次,我看不出为它们创建模型的意义.

我看了下面的文章,似乎正是我所需要的,只是我不希望它在不存在所需的parm的情况下返回404,我希望它返回类似错误消息的对象进行模型验证的过程-实际上,我只是希望将参数像模型一样对待,而无需实际创建模型.

https://www.strathweb.com/2016/09/required-query-string-parameters-in-asp-net-core-mvc/

 [HttpPost]
public async Task<IActionResult> Post(
    [FromQueryRequired] int? Id,
    [FromQuery] string Company)
 


[FromQueryRequired]是一个自定义ActionConstraint,如果缺少ID参数,则抛出404(直接从文章中获取).但是,我不需要404,而是想要一个对象,该对象的信息为{MESSAGE:"ID is required"}.我认为问题是我无法从操作约束中访问Response上下文.

解决方案

这是我最终使用的解决方案.将属性添加到名为[RequiredParm]的参数中.我大致基于其他人对另一个问题的答案,但我目前似乎找不到它,对任何人都表示歉意,如果可以找到,我会以信誉为目的来更新此答案.

找到它,由@James Law回答-"Web API必需参数"

用法:

[HttpPost]
public async Task<IActionResult> Post(
    [FromQuery, RequiredParm] int? Id,
    [FromQuery] string Company)

ActionFilterAttribute:

[AttributeUsage(AttributeTargets.Method)]
public sealed class CheckRequiredParmAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        var requiredParameters = context.ActionDescriptor.Parameters.Where(
            p => ((ControllerParameterDescriptor)p).ParameterInfo.GetCustomAttribute<RequiredParmAttribute>() != null).Select(p => p.Name);

        foreach (var parameter in requiredParameters)
        {
            if (!context.ActionArguments.ContainsKey(parameter))
            {
                context.ModelState.AddModelError(parameter, $"The required argument '{parameter}' was not found.");
            }
            else
            {
                foreach (var argument in context.ActionArguments.Where(a => parameter.Equals(a.Key)))
                {
                    if (argument.Value == null)
                    {
                        context.ModelState.AddModelError(argument.Key, $"The requried argument '{argument.Key}' cannot be null.");
                    }
                }
            }
        }

        if (!context.ModelState.IsValid)
        {
            context.Result = new BadRequestObjectResult(context.ModelState);
            return;
        }

        base.OnActionExecuting(context);
    }
}

/// <summary>
/// Use this attribute to force a [FromQuery] parameter to be required. If it is missing, or has a null value, model state validation will be executed and returned throught the response. 
/// </summary>  
[AttributeUsage(AttributeTargets.Parameter)]
public sealed class RequiredParmAttribute : Attribute
{
}

Is it possible to validate query parameters on an action without using a model? A lot of the calls in my API are one-offs and I don't see a point in making models for them if they will only be used one time.

I saw the following article, which seemed like it was exactly what I needed, except I don't want it to return a 404 if the required parm doesn't exist, I want it to return an object of error messages similar to the baked in model validation - really, I just want the parameters to be treated like a model, without actually having to make a model.

https://www.strathweb.com/2016/09/required-query-string-parameters-in-asp-net-core-mvc/

[HttpPost]
public async Task<IActionResult> Post(
    [FromQueryRequired] int? Id,
    [FromQuery] string Company)

EDIT:
The [FromQueryRequired] is a custom ActionConstraint that throws a 404 if the ID parm is missing (this was taken directly from the article). However I don't want the 404, I want an object that has a message that says {MESSAGE: "ID is required"}. I think the issue is that i can't access the Response context from within an Action Constraint.

解决方案

Here is the solution I ended up using. Add an Attribute to the parms named [RequiredParm]. I loosely based it on someone else's answer for a different question, but I can't seem to find it at the moment, apologies to whoever you are, if I can find it I'll update this answer for credit.

EDIT: Found it, answered by @James Law - Web Api Required Parameter

Usage:

[HttpPost]
public async Task<IActionResult> Post(
    [FromQuery, RequiredParm] int? Id,
    [FromQuery] string Company)

ActionFilterAttribute:

[AttributeUsage(AttributeTargets.Method)]
public sealed class CheckRequiredParmAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        var requiredParameters = context.ActionDescriptor.Parameters.Where(
            p => ((ControllerParameterDescriptor)p).ParameterInfo.GetCustomAttribute<RequiredParmAttribute>() != null).Select(p => p.Name);

        foreach (var parameter in requiredParameters)
        {
            if (!context.ActionArguments.ContainsKey(parameter))
            {
                context.ModelState.AddModelError(parameter, $"The required argument '{parameter}' was not found.");
            }
            else
            {
                foreach (var argument in context.ActionArguments.Where(a => parameter.Equals(a.Key)))
                {
                    if (argument.Value == null)
                    {
                        context.ModelState.AddModelError(argument.Key, $"The requried argument '{argument.Key}' cannot be null.");
                    }
                }
            }
        }

        if (!context.ModelState.IsValid)
        {
            context.Result = new BadRequestObjectResult(context.ModelState);
            return;
        }

        base.OnActionExecuting(context);
    }
}

/// <summary>
/// Use this attribute to force a [FromQuery] parameter to be required. If it is missing, or has a null value, model state validation will be executed and returned throught the response. 
/// </summary>  
[AttributeUsage(AttributeTargets.Parameter)]
public sealed class RequiredParmAttribute : Attribute
{
}

这篇关于在.netcore api中不使用模型的情况下验证查询参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆