验证api中返回的行数

piv4azn7  于 2021-07-26  发布在  Java
关注(0)|答案(3)|浏览(293)

关闭。这个问题是基于意见的。它目前不接受答案。
**想改进这个问题吗?**更新这个问题,这样就可以通过编辑这篇文章用事实和引文来回答。

10个月前关门了。
改进这个问题
我有一个api,它从请求中获取它的模型。它将其传输到一个小的存储过程。sp通过使用模型的一些参数来选择一些记录。它以对象列表的形式返回匹配的记录。最后,控制器返回响应。
简化示例:

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

api一次返回的记录不应超过500条。如果我们有超过这个数量,api应该返回一个错误:“您的请求将返回超过500条记录”。
为检索到的记录数添加验证的最佳解决方案是什么?
两个选择具有相同的条件和联接,但其中一个只返回 count(*) ?
或者将所有数据返回到应用程序,然后在那里进行计数?
或者别的什么?

nwlls2ji

nwlls2ji1#

通常,当您在执行restapi时,有太多的方法可以做到这一点。
进近#1:
一种是在sql级别,您需要传递给sql逻辑分页参数,如

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

因此,您可以选择并跳过所需的元素数。那有什么好处?您可以在sql查询中添加一些执行计划,查看缺少哪些索引,您可以在sql端优化查询。DBA通常负责大型组织中的这些方法。
进近#2
您仍然可以从后端编写查询,至少这个查询很简单,它将在sql server端执行,下面是一个扩展方法,您可以使用它来执行。

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 server中)并从此处开始分页。唯一需要做的就是调用tolist(),它将具体化查询并将其放入内存,在内存中您可以使用相同的方法2。
进近#4:
此示例将适用于.NETCore,但请确保有一个版本的包可以对.netframework执行相同的操作。使用odata nugget包

Install-Package Microsoft.AspNetCore.OData

添加 EnableQueryAttribute 然后传球 ODataQueryOptions<TestModel> options ,odata使用了一些扩展方法 IQueryble ```
[EnableQuery]
public IHttpActionResult Get(ODataQueryOptions options)
{
//this should return an IQueryble
var responseList = _testService.GetResponse(testModel);
var ret= options.ApplyToWithDefaultTop(responseList, ignoreQueryOptions);
return Ok(ret);
}

下面是我的扩展方法,用于应用要带来的元素的默认计数

public static IQueryable ApplyToWithDefaultTop(this ODataQueryOptions options,
IQueryable 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("Odata:MaxTop"));
routerBuilder.Expand().Select().Count().OrderBy().Filter().MaxTop(Configuration.GetValue("500"));
});

而且在 `ConfigureServices` 添加 `services.AddOData();` 有关更多参考资料,请参阅本文:odata article
推荐
如果你的api有超过500个错误,你不应该向客户端抛出一个错误,只要给他前500个,你也可以传递pagesize并验证这个数字,而不必去你的数据库,如果你仍然想用这种方法返回错误。当您可以验证输入时,不要让应用程序失败。您也可以使用fluentvalidation nugget包来验证您的 `DTOs` 希望这有帮助
v2g6jxz6

v2g6jxz62#

你可以通过考试 Output 设置为 count 大于500并选择记录,否则不要在sp中执行任何操作。在c代码中,只需首先检查输出值,然后进行相应的处理。

oiopk7p5

oiopk7p53#

正如@viveknuna指出的,您可以使用out参数来指示检索到的行计数。
我想对他的建议补充几点:
1) 建议仅在超过预定义阈值时设置该参数。我建议每次都设置它,并在应用程序代码中检查它。它给你更多的灵活性。
2) 您不需要使用两个选择。 @@ROWCOUNT 或者 ROWCOUNT_BIG() 我建议读一读这篇关于这个主题的优秀文章。

相关问题