在.netcore api中不使用模型的情况下验证查询参数

Aus*_*haw 2 c# asp.net-core asp.net-core-2.0

是否可以在不使用模型的情况下验证操作的查询参数?我的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)
Run Code Online (Sandbox Code Playgroud)

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

Kar*_*ral 5

从Asp.Net Core 2.1开始,有一个内置参数[BindRequired]可自动执行此验证。

public async Task<ActionResult<string>> CleanStatusesAsync([BindRequired, 
    FromQuery]string collection, [BindRequired, FromQuery]string repository,
       [BindRequired, FromQuery]int pullRequestId)
{
    // all parameters are bound and valid
}
Run Code Online (Sandbox Code Playgroud)

如果您在不带参数的情况下调用此方法,则会返回ModelState错误:

{
"collection": [
  "A value for the 'collection' parameter or property was not provided."
],
"repository": [
  "A value for the 'repository' parameter or property was not provided."
],
"pullRequestId": [
  "A value for the 'pullRequestId' parameter or property was not provided."
],
}
Run Code Online (Sandbox Code Playgroud)

您可以在这篇出色的文章中找到更多详细信息。


Aus*_*haw 2

这是我最终使用的解决方案。将属性添加到名为 [RequiredParm] 的参数。我松散地基于其他人对不同问题的回答,但我目前似乎找不到它,向你道歉,无论你是谁,如果我能找到它,我会更新这个答案以获取信用。

编辑:找到它,由 @James Law 回答 - Web Api 必需参数

用法:

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

动作过滤器属性:

[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
{
}
Run Code Online (Sandbox Code Playgroud)