首页 > 解决方案 > 如何正确加载重集?

问题描述

我正在学习ASP.NET Core,我对加载大量记录有一些疑问,让我更好地解释一下。

我正在尝试做的事情

在我的应用程序中,登录执行后,用户将重定向到Dashboard Home View. 这Dashboard是包含用户所有功能的地方。还有Dashboard Controller其他Views类似的:

现在每个View需要向用户显示一个Table包含一个列表的列表Products,在这个列表的底部Table是 的内容View

问题

第一个问题:是Table冗余代码,我解决了创建一个包含_PartialView要显示的产品的。来自 c# + WPF 我使用了相同的逻辑htmlTableUserControl,所以这对我来说是一个很好的解决方案。

第二个问题:要在里面显示的产品Table,这些产品是从一个下载的API,现在就像我之前说的,这些记录必须总是显示在产品中Table(在不同View的使用中可用_PartialView)。想象一下,每次用户点击一个Dashboard项目(加载一个Dashboard View),Dashboard Controller都会调用这个方法:

 public async Task<List<Products>> GetProducts(string date)
 {
    var client = new RestClient(Url);

    var request = new RestRequest("product/get_products/{date}", Method.GET);
    request.AddUrlSegment("date", date);

    var cancellationTokenSource = new CancellationTokenSource();
    var response = await client.ExecuteTaskAsync(request, cancellationTokenSource.Token);

    List<Products> products =  JsonConvert.DeserializeObject<List<Product>>(response.Content);
    return products;
 }

对我来说,这不是一个很好的做法,因为每次_PartialView都会调用这个方法并重新加载数据,所以我需要以某种方式存储这些数据(临时存储)。如何将这些记录存储到用户会话而不在每次_PartialView调用时重新加载?

之间,我对方法有些疑问API:我应该将所有API调用都放在Service文件夹中吗?Repository文件夹?还是Controller文件夹?

文件夹树

View <- Folder
    Dashboard <- Folder
        Home
        Analysis 
        Performance
       _ProductsTable

View Home, Analysis, Performance负载_ProductsTable方式如下:

@await Html.PartialAsync("_LeftSidebar")

标签: c#asp.net-core

解决方案


使用视图组件。它们本质上是返回视图的自包含功能模块,您可以将其嵌入到其他视图中,而无需主视图或操作了解其中任何一个。

首先,创建一个目录调用ViewComponents。在里面添加新的类,比如ProductsViewComponent. 然后,你会想要这样的东西:

public class ProductsViewComponent : ViewComponent
{
    private readonly HttpClient _client;

    public ProductsViewComponent(HttpClient client)
    {
        _client = client ?? throw new ArgumentNullException(nameof(client));
    }

    public async Task<IViewComponentResult> InvokeAsync(string date)
    {
       using (var response = await _client.GetAsync($"/"product/get_products/{date}"))
       {
           response.EnsureSuccessStatusCode();
           var products = await response.Content.ReadAsAsync<List<Product>>();
           return View(products);
       }
    }
}

然后,创建视图,Views\Shared\Components\Products\Default.cshtml. 在里面,添加 HTML 以呈现您的产品列表。最后,您希望产品表出现的位置添加:

@await Component.InvokeAsync("Products", new { date = myDate })

上面的代码使用HttpClient而不是RestClient,因为老实说,此时完全没有必要拥有一个单独的库来进行 HTTP 调用。HttpClient是内置的,并且已经在 Core 中扩展了功能,使这更容易,例如ReadAsAsync上面使用的方法,它将您的 JSON 响应透明地反序列化为泛型类型参数。此外,您现在拥有诸如IHttpClientFactory确保您拥有适当范围的HttpClient实例之类的东西。因此,上面的代码还假设在您的 中添加如下内容Startup.cs

services.AddHttpClient<ProductsViewComponent>(c =>
{
    c.BaseAddress = new Uri('https://api.myservice.com');
    // add default headers and such if you need them
});

然后,您还可以使用 Polly 集成来设置自动重试、断路器等,从而允许您处理各种 API 场景,例如暂时不可用、速率限制等。有关更多信息,请参阅两者的完整文档IHttpClientFactory及其Polly 集成.

最后,如果这是您不需要实时数据的场景,您还可以IDistributedCache将再次调用,允许您显着减少应用程序和 API 的负载(特别是如果确实有应用速率限制的东西)。


推荐阅读