首页 > 解决方案 > 验证 API 中返回的行数

问题描述

我有一个从请求中获取模型的 API。它将其转移到一个小型存储过程。该 SP 通过使用模型的一些参数来选择一些记录。它将匹配的记录作为对象列表返回。最后控制器返回响应。

简化示例:

public IHttpActionResult Get([FromBody]TestModel testModel)
{
    var responseList = _testService.GetResponse(testModel);
    return Ok(responseList );
}

API 一次不应返回超过 500 条记录。如果我们有更多,API 应该返回错误:“您的请求将返回超过 500 条记录”。

为检索到的记录数量添加验证的最佳解决方案是什么?

标签: c#sqlapi

解决方案


通常,当您使用 REST API 时,有太多方法可以做到这一点。

方法#1:

一种是在 SQL 级别,您需要将分页参数传递给您的 sql 逻辑,例如

public int PageNumber { get; set; } = 1;
private int PageSize = 500;

因此,您可以选择并跳过所需的元素数量。这样做有什么好处?您可以在 SQL 查询中添加一些执行计划,查看缺少哪些索引,您可以主要在 SQL 端优化您的查询。DBA 通常在大型组织中负责这些方法。

方法#2

您仍然可以从后端编写查询,至少这个很简单,它将在 SQL 服务器端执行,下面是您可以使用的扩展方法。

    public static IQueryable<T> PageBy<T>(this IQueryable<T> query, int skipCount, int maxResultCount)
    {
       if (query == null)
       {
            throw new ArgumentNullException("query");
       }
       return query.Skip(skipCount).Take(maxResultCount);
    }

方法#3:

将数据放入内存(在这种情况下将在服务器端执行,而不是在 SQL 服务器中)并从那里进行分页。您唯一需要做的就是调用 ToList() ,这将实现您的查询并将其带入内存,您可以在其中使用与方法 #2相同的想法。

方法#4:

此示例将适用于 .Net Core,但肯定有一个版本的包可以为 .NetFramework 做同样的事情。使用 OData 块包

Install-Package Microsoft.AspNetCore.OData

Add EnableQueryAttributeand pass ODataQueryOptions<TestModel> options, Odata 使用了一些扩展方法IQueryble

[EnableQuery]
public IHttpActionResult Get(ODataQueryOptions<TestModel> options)
{
    //this should return an IQueryble<T>
    var responseList = _testService.GetResponse(testModel);  
    var ret= options.ApplyToWithDefaultTop(responseList, ignoreQueryOptions);
    return Ok(ret);
}

这是我的扩展方法,用于应用默认的元素计数

public static IQueryable ApplyToWithDefaultTop<T>(this ODataQueryOptions<T> options, 
            IQueryable<T> query, AllowedQueryOptions ignoreQueryOptions)
        {
            if (options.Top == null)
            {
                //this is the default
                query = query.Take(500);
            }

            //odata extension method
            return options.ApplyTo(query, ignoreQueryOptions);
        }

这将与方法 #2做同样的事情,但您不必担心参数模型,它们是 Odata 语法的一部分,例如,这里我返回该资源的 40 个元素并跳过前 2 页.

https://localhost:44335/api/weather_forecast?$top=40&$skip=2

只需添加 4 行代码,您就可以将 Odata 语法放在您的 API 之上,在您的 Configure 方法中

   app.UseMvc(routerBuilder =>
    {
        routerBuilder.EnableDependencyInjection();
        //adding MaxTop from appsettings with a value of 100
        //routerBuilder.Select().OrderBy().Filter().Count().MaxTop(Configuration.GetValue<int>("Odata:MaxTop"));
        routerBuilder.Expand().Select().Count().OrderBy().Filter().MaxTop(Configuration.GetValue<int>("500"));
    });

ConfigureServices添加services.AddOData();

有关更多参考资料,请参阅这篇文章:OData 文章

推荐

如果您的 API 超过 500,您不应该向客户端抛出错误,只需给他前 500 此外,您可以传递 PageSize 并验证该数字,而无需进入您的数据库并返回错误以防万一您仍然想去用这种方法。当您可以验证输入时,不要让应用程序失败。您也可以使用 FluentValidation nugget 包来验证您的DTOs

希望这可以帮助


推荐阅读