如何正确加载重型收藏?

问题描述 投票:1回答:1

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

我想做什么

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

  • 分析
  • 性能

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

问题

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

第二个问题:在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
1个回答
1
投票

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

首先,创建一个目录调用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 integration的完整文档。 。

最后,如果这是您不需要实时数据的情况,您还可以将IDistributedCache的实例注入到视图组件中,并添加逻辑以设置API调用的结果,并在此之前从中检索它再次拨打电话,可以显着降低应用和API的负载(特别是如果有适用速率限制的话)。

© www.soinside.com 2019 - 2024. All rights reserved.