如何正确加载繁重的收藏?

时间:2018-09-03 15:10:47

标签: c# asp.net-core

我正在学习ASP.NET Core,并且对加载大量记录感到有些疑问,请允许我更好地解释。

我要做什么

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

  • 首页
  • 分析
  • 性能

现在每个View都需要向用户显示一个Table,其中包含Products的列表,在此Table的底部有{ {1}}。

问题

第一个问题:View冗余代码,我解决了这个问题,创建了一个Table,其中包含要显示的产品的_PartialView的{​​{1}}。来自c#+ WPF,我使用了html的相同逻辑,因此这对我来说是一个很好的解决方案。

第二个问题:要显示在Table内部的产品,这些产品是从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

1 个答案:

答案 0 :(得分: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方案,例如暂时不可用,速率限制等。请参见{{3} }及其IHttpClientFactory以获得更多信息。

最后,如果在这种情况下不需要实时数据,则还可以将IDistributedCache的实例注入到视图组件中,并在其中添加逻辑来设置API调用的结果,并且首先从该位置检索它,然后再进行调用,从而使您可以显着减少应用程序和API上的负载(尤其是在某些情况下需要应用速率限制)。