我正在学习ASP.NET Core
,并且对加载大量记录感到有些疑问,请允许我更好地解释。
我要做什么
在我的应用程序中,执行登录后,用户将重定向到Dashboard Home View
。 Dashboard
是包含用户所有功能的位置。 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
答案 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上的负载(尤其是在某些情况下需要应用速率限制)。