بررسی تغییرات Blazor 8x - قسمت چهاردهم - امکان استفاده از کامپوننتهای Blazor در برنامههای ASP.NET Core 8x
نویسنده: وحید نصیری
تاریخ: ۱۴۰۲/۰۸/۲۷ ۱۰:۵
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
dotnet new blazor --interactivity None
@page "/ssr-page/{Data:int}"
<PageTitle>An SSR component</PageTitle>
<h1>An SSR component rendered by a Minimal-API!</h1>
<div>
Data: @Data
</div>
@code {
[Parameter]
public int Data { get; set; }
}
var builder = WebApplication.CreateBuilder(args);
// ...
builder.Services.AddRazorComponents();
// ...
// http://localhost:5227/ssr-component?data=2
// or it can be called directly http://localhost:5227/ssr-page/2
app.MapGet("/ssr-component",
(int data = 1) =>
{
var parameters = new Dictionary<string, object?>
{
{ nameof(SsrTest.Data), data },
};
return new RazorComponentResult<SsrTest>(parameters);
});
app.UseStaticFiles();
app.UseAntiforgery();
app.MapRazorComponents<App>();
app.Run();
// ... <LayoutView Layout="@typeof(MainLayout)">
<PageTitle>Home</PageTitle>
<h2>Welcome to your new app.</h2>
</LayoutView> // ...
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
// ...
app.MapRazorComponents<App>().AddInteractiveServerRenderMode();
// ... <script src="_framework/blazor.web.js"></script>
@rendermode InteractiveServer
<h1>Counter</h1>
<p role="status">Current count: @_currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int _currentCount;
private void IncrementCount()
{
_currentCount++;
}
} // http://localhost:5227/server-interactive-component
app.MapGet("/server-interactive-component", () => new RazorComponentResult<Counter>()); <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Interactive server component</title>
<base href="/"/>
</head>
<body>
<h1>Interactive server component</h1>
<Counter/>
<script src="_framework/blazor.web.js"></script>
</body>
</html> // http://localhost:5227/server-interactive-component
app.MapGet("/server-interactive-component", () => new RazorComponentResult<CounterInteractive>()); using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
namespace WebApi8x.Services;
public class BlazorStaticRendererService
{
private readonly HtmlRenderer _htmlRenderer;
public BlazorStaticRendererService(HtmlRenderer htmlRenderer) => _htmlRenderer = htmlRenderer;
public Task<string> StaticRenderComponentAsync<T>() where T : IComponent
=> RenderComponentAsync<T>(ParameterView.Empty);
public Task<string> StaticRenderComponentAsync<T>(Dictionary<string, object?> dictionary) where T : IComponent
=> RenderComponentAsync<T>(ParameterView.FromDictionary(dictionary));
private Task<string> RenderComponentAsync<T>(ParameterView parameters) where T : IComponent =>
_htmlRenderer.Dispatcher.InvokeAsync(async () =>
{
var output = await _htmlRenderer.RenderComponentAsync<T>(parameters);
return output.ToHtmlString();
});
} builder.Services.AddScoped<HtmlRenderer>(); builder.Services.AddScoped<BlazorStaticRendererService>();
app.MapGet("/static-renderer-service-test",
async (BlazorStaticRendererService renderer, int data = 1) =>
{
var parameters = new Dictionary<string, object?>
{
{ nameof(SsrTest.Data), data },
};
var html = await renderer.StaticRenderComponentAsync<SsrTest>(parameters);
return Results.Content(html, "text/html");
}); یک نکتهی تکمیلی: استفاده از BlazorStaticRendererService جهت تولید یک کامپوننت کش کردن قسمتی از محتوای صفحه در برنامههای Blazor SSR
فرض کنید هر کدام از آیتمهای منوی سمت راست صفحه، به همراه آماری مرتبط هم هستند که باید جداگانه محاسبه شوند. اگر قرار باشد بهازای هر کاربر و هر بازدید صفحهای، این اطلاعات دوباره محاسبه شوند، بار قابل توجهی به برنامه و سرور وارد خواهد شد و همچنین مرور صفحات هم بهشدت کند میشوند؛ چون قسمت منوی سمت راست صفحه، هربار باید از ابتدا رندر شود. در این مطلب، با سرویس BlazorStaticRendererService آشنا شدیم که کار آن، رندر کردن محتوای یک کامپوننت و بازگشت رشتهی نهایی معادل آن است. اگر این مورد را به همراه IMemoryCache توکار داتنت، ترکیب کنیم، به کامپوننتی شبیه به cache tag helper توکار ASP.NET Core میرسیم:
<cache expires-after="@TimeSpan.FromMinutes(10)">
@Html.Partial("_WhatsNew")
*last updated @DateTime.Now.ToLongTimeString()
</cache>کدهای کامل آنرا در اینجا (^ و ^) میتوانید مطالعه کنید که به این صورت مورد استفاده قرار گرفتهاست تا فقط قسمتی از صفحه را کش کند و نه کل آنرا.
جالب توجهاست که OutputCache مخصوص ASP.NET Core، در Blazor SSR هم کار میکند. برای استفادهی از آن در Blazor SSR، پس از انجام تنظیمات ابتدایی میانافزار مخصوص آن که ترتیب افزودن آن باید به صورت زیر باشد:
app.UseStaticFiles(); app.UseSession(); app.UseRouting(); app.UseAntiforgery(); app.UseOutputCache(); app.MapRazorComponents<App>(); app.MapControllers(); app.Run();
فقط کافی است ویژگی OutputCache را به نحو زیر به فایل razor. خود اضافه کنید:
@attribute [OutputCache(Duration = 1000)]
که البته کار آن، کش کردن محتوای کل یک صفحهاست و نه فقط قسمتی از آن.