‫۳ سال قبل، دوشنبه ۱۸ مرداد ۱۴۰۰، ساعت ۱۱:۴۹
خیر. چیزی به اشتراک گذاشته نمی‌شود. از مقدمه: «... وضعیت این Context به حالت اولیه برگردانده شده ...» و سپس استفاده‌ی مجدد می‌شود.
یک نکته‌ی تکمیلی: روش سازگار کردن اعتبارسنجی فرم‌های استاندارد Blazor با کلاس‌های CSS بوت استرپ 4 و 5
زمانیکه از EditForm و کامپوننت‌های توکار Blazor استفاده می‌کنیم، اگر کامپوننتی در وضعیت اعتبارسنجی شده قرار داشته باشد، با کلاس valid:
class="modified valid form-control"
و اگر در وضعیت شکست اعتبارسنجی قرارگیرد، با کلاس invalid مزین می‌شود:
class="modified invalid form-control"
اما برای یکپارچه سازی آن با کلاس‌های اعتبارسنجی بوت استرپ 4 و 5، نیاز است از کلاس‌های is-valid و is-invalid بجای valid و invalid استفاده شود. این تغییر نیاز به استفاده از «یک نکته‌ی تکمیلی: امکان اعتبارسنجی دستی فرم‌ها در Blazor» را دارد؛ چون با دسترسی به EditContext است که می‌توان CSS provider آن‌را سفارشی سازی کرد؛ برای مثال:
EditContext = new EditContext(Model);
EditContext.SetFieldCssClassProvider(new BootstrapFieldCssClassProvider());
که سفارشی ساز مخصوص بوت استرپ، به صورت زیر قابل تعریف است:
using System;
using System.Linq;
using Microsoft.AspNetCore.Components.Forms;

namespace BlazorComponents
{
    /// <summary>
    /// Supplies CSS class names for form fields to represent their validation state or other state information from an EditContext.
    /// </summary>
    public class BootstrapFieldCssClassProvider : FieldCssClassProvider
    {
        /// <summary>
        /// Gets a string that indicates the status of the specified field as a CSS class.
        /// </summary>
        public override string GetFieldCssClass(EditContext editContext, in FieldIdentifier fieldIdentifier)
        {
            if (editContext == null)
            {
                throw new ArgumentNullException(nameof(editContext));
            }

            var isValid = !editContext.GetValidationMessages(fieldIdentifier).Any();

            if (editContext.IsModified(fieldIdentifier))
            {
                return isValid ? "is-valid" : "is-invalid";
            }
            return isValid ? "" : "is-invalid";
        }
    }
}
در اینجا در ابتدا بررسی می‌شود که آیا فیلد جاری معتبر است یا خیر و همچنین آیا ویرایش شده‌است یا خیر؟ سپس بر این اساس، کلاس‌های ویژه‌ی بوت استرپ، بجای کلاس‌های پیش‌فرض ارائه خواهند شد.
‫۳ سال قبل، یکشنبه ۱۷ مرداد ۱۴۰۰، ساعت ۱۳:۲۳
یک نکته‌ی تکمیلی: روش ارسال یک المان razor به کدهای جاوا اسکریپتی
فرض کنید قصد داریم قطعه کد جاوا اسکریپتی زیر را که یک المان را جهت هدایت فوکوس به آن، نیاز دارد، در کدهای #C فراخوانی کنیم:
window.setFocus = function (element) {
  element.focus();
};
برای مقدار دهی این element در کدهای #C باید به صورت زیر عمل کرد:
الف) در اینجا نیز از ref@ برای دسترسی به المان استفاده خواهیم کرد:
<input @ref="@ReferenceToInputControl" />
در این حالت input ای که توسط Blazor رندر می‌شود، چنین شکلی را پیدا می‌کند:
<input _bl_bc0f34fa-16bd-4687-a8eb-9e3838b5170d="">
هدف این است که بدون دستکاری Id المان، بتواند آن‌را به صورت منحصربفردی مشخص کند.

ب) سپس شیء ReferenceToInputControl را در کدهای کامپوننت به صورت زیر تعریف می‌کنیم:
private ElementReference ReferenceToInputControl;
که قابلیت ارسال به کدهای جاوا اسکریپتی را دارد:
await JSRuntime.InvokeVoidAsync("setFocus", ReferenceToInputControl);
در این قطعه کد، ReferenceToInputControl همان element ای است که تابع setFocus تعریف شده نیاز دارد.

توجه! اگر قصد دارید قطعه کد #C فوق را در روال‌های رویدادگردان چرخه‌ی حیات کامپوننت فراخوانی کنید، اینکار باید در OnAfterRender صورت گیرد؛ چون پیش از آن ref@ هنوز تشکیل نشده‌است.
‫۳ سال قبل، یکشنبه ۱۷ مرداد ۱۴۰۰، ساعت ۱۳:۰۴
نکته‌ای در مورد تگ text

فرض کنید قصد دارید یک تصویر SVG را که به همراه متن است، نمایش دهید. نمایش متن در این حالت، توسط تگ text انجام می‌شود:
<text x="50" y="50">Some text</text>
اگر در این حالت برنامه را کامپایل کنیم، با خطای زیر مواجه می‌شویم:
"<text>" and "</text>" tags cannot contain attributes
علت اینجا است که در دستور زبان Razor، واژه‌ی text، یک واژه‌ی کلیدی است و هدف آن، جدا کردن یک قطعه‌ی متنی، از قسمتی از کد #C نوشته شده‌ی در فایل‌های razor است. هدف اصلی آن، تعیین مرزی بین کد #C و یک متن خالص است. به همین جهت است که عنوان می‌کند، تگ text نمی‌تواند دارای attributes باشد. برای رفع این مشکل، روش escape کردن آن، قرار دادن این تگ مخصوص SVG، داخل یک تگ text دیگر است:
<text>
  <!-- Here are your actual Text tags -->
  <text x="50" y="50">Some text</text>  
</text>
‫۳ سال قبل، شنبه ۱۶ مرداد ۱۴۰۰، ساعت ۱۴:۴۴
روش درست کردن دمو برای پروژه‌های blazor در Github (یا روش توزیع پروژه‌های Blazor WASM در Github-Pages)

ابتدا فایل yml زیر را در پوشه‌ی github\workflows\deploy.yml. قرار دهید (پوشه‌ای را به این نام، در ریشه‌ی پروژه‌ی خود ایجاد کنید):
name: Deploy to GitHub Pages

# Run workflow on every push to the main branch
on:
  push:
    branches: [ main ]

jobs:
  deploy-to-github-pages:
    # use ubuntu-latest image to run steps on
    runs-on: ubuntu-latest
    steps:
    # uses GitHub's checkout action to checkout code form the main branch
    - uses: actions/checkout@v2
    
    # sets up .NET Core SDK
    - name: Setup .NET Core SDK
      uses: actions/setup-dotnet@v1
      with:
        dotnet-version: 5.0.302

    # publishes Blazor project to the release-folder
    - name: Publish .NET Core Project
      run: dotnet publish ./src/DNTPersianComponents.Blazor.WasmSample/Server/DNTPersianComponents.Blazor.WasmSample.Server.csproj -c Release -o release --nologo
    
    # changes the base-tag in index.html from '/' to 'DNTPersianComponents.Blazor' to match GitHub Pages repository subdirectory
    - name: Change base-tag in index.html from / to DNTPersianComponents.Blazor
      run: sed -i 's/<base href="\/" \/>/<base href="\/DNTPersianComponents.Blazor\/" \/>/g' release/wwwroot/index.html
    
    # copy index.html to 404.html to serve the same file when a file is not found
    - name: copy index.html to 404.html
      run: cp release/wwwroot/index.html release/wwwroot/404.html

    # add .nojekyll file to tell GitHub pages to not treat this as a Jekyll project. (Allow files and folders starting with an underscore)
    - name: Add .nojekyll file
      run: touch release/wwwroot/.nojekyll
      
    - name: Commit wwwroot to GitHub Pages
      uses: JamesIves/github-pages-deploy-action@3.7.1
      with:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        BRANCH: github-pages
        FOLDER: release/wwwroot
در این قالب، چهار مورد را باید ویرایش کنید:
- نام شاخه‌ی اصلی پروژه؛ که یا main است و یا master.
- شماره نگارش دات نت مورد استفاده.
- مسیر فایل csproj پروژه‌ی wasm.
- نام اصلی مخزن کد.


سپس آن‌را به مخزن کد خود commit کنید. بعد به قسمت settings->pages در github مراجعه کرده و source را بر روی نام شاخه‌ی جدید github-pages (فوق در قسمت آخر کار) قرار داده و آن‌را ذخیره کنید. الان سایت دموی شما در مسیری که در همین قسمت pages پس از ذخیره سازی، نمایش می‌دهد، آماده‌است.


یک نکته‌ی مهم

چون base href، توسط action فوق اصلاح می‌شود تا به پوشه‌ی نسبی محل قرارگیری برنامه اشاره کند، نیاز است navlink‌ها با href شروع شده‌ی با / نباشند؛ چون به ریشه‌ی سایت اشاره می‌کنند و نه مسیر نسبی محل قرارگیری برنامه. کلا در هر قسمتی از برنامه، این نکته باید رعایت شود. مثلا اگر فونت وبی را در فایل app.css تعریف کرده‌اید، مسیر آن نباید با / شروع شود؛ وگرنه یافت نخواهد شد. یک مثال:
فایل app.css برنامه در مسیر wwwroot\css\app.css قرار دارد و داخل آن فایل، فونت‌های پوشه‌ی دیگر wwwroot\lib\samim-font را به صورت زیر تعریف کرده‌ایم؛ که یعنی مسیر فونت را از ریشه‌ی سایت پیدا کن:
src: url('/lib/samim-font/Samim-Bold.eot?v=4.0.5');
این مسیر، باید به مسیر نسبی زیر که به یک پوشه‌ی بالاتر (از محل قرار گیری app.css) اشاره می‌کند، اصلاح شود:
src: url('../lib/samim-font/Samim-Bold.eot?v=4.0.5');
‫۳ سال و ۱ ماه قبل، دوشنبه ۱۱ مرداد ۱۴۰۰، ساعت ۱۹:۳۷
- اگر نیاز به فعالسازی سمت سرور بود، نیاز است یکسری میان‌افزار هم اضافه شوند.
همچنین ReponseCache در این موارد اثری ندارد:
  • حتما باید status-code خروجی 200 و یا Ok باشد.
  • نوع درخواست باید head و یا get باشد.
  • هدر از نوع  authorization نباید حضور داشته باشد.
  • اگر میان‌افزار فایل‌های ثابت، پیش از میان‌افزار کش فعال شود، عملیات کش رخ نخواهد داد.
  • در اینجا هدر تنظیم کوکی نباید حضور داشته باشد.
‫۳ سال و ۱ ماه قبل، پنجشنبه ۷ مرداد ۱۴۰۰، ساعت ۲۳:۳۳
مشکلی مشاهده نشد. ابتدا فایل جدید نمونه Areas\Identity\Controllers\DynamicPermissionsAreaSampleController.cs اضافه شد؛ با این محتوای فرضی:
namespace ASPNETCoreIdentitySample.Areas.Identity.Controllers
{  
    [Authorize(Policy = ConstantPolicies.DynamicPermission)]
    [Area(AreaConstants.IdentityArea)]
    [BreadCrumb(UseDefaultRouteUrl = true, Order = 0)]
    [DisplayName("کنترلر نمونه با سطح دسترسی پویا در یک ناحیه خاص")]
    public class DynamicPermissionsAreaSampleController : Controller
    {
        [DisplayName("ایندکس")]
        [BreadCrumb(Order = 1)]
        public IActionResult Index()
        {
            return View();
        }
    }
}
و نتیجه‌ی آن در قسمت مشاهده‌ی دسترسی‌های پویا مشخص است: