مطالب
روش یکی کردن پروژه‌های React و ASP.NET Core
یک روش کار کردن با پروژه‌های SPA، توسعه‌ی مجزای قسمت‌های front-end و back-end است. برای مثال پروژه‌ی React را به صورت جداگانه‌ای توسعه می‌دهیم، پروژه‌ی ASP.NET Core را نیز به همین صورت. هنگام آزمایش برنامه، در یکی دستور npm start را اجرا می‌کنیم تا وب سرور آزمایشی React، آن‌را در آدرس http://localhost:3000 قابل دسترسی کند و در دیگری دستور dotnet watch run را صادر می‌کنیم تا برنامه‌ی وب ASP.NET Core را بر روی آدرس https://localhost:5001 مهیا کند. سپس برای اینکه از پورت 3000 بتوان با پورت 5001 کار کرد، نیاز خواهد بود تا CORS را در برنامه‌ی ASP.NET Core فعالسازی کنیم. در حین ارائه‌ی نهایی برنامه نیز هر کدام را به صورت مجزا publish کرده و بعد هم خروجی نهایی پروژه‌ی SPA را در پوشه‌ی wwwroot برنامه‌ی وب کپی می‌کنیم تا قابل دسترسی و استفاده شود. روش دیگری نیز برای یکی/ساده سازی این تجربه وجود دارد که در این مطلب به آن خواهیم پرداخت.


پیشنیاز: ایجاد یک برنامه‌ی خالی React و ASP.NET Core

یک پوشه‌ی خالی را ایجاد کرده و در آن دستور dotnet new react را صادر کنید، تا قالب خاص پروژه‌های React یکی سازی شده‌ی با پروژه‌های ASP.NET Core، یک پروژه‌ی جدید را ایجاد کند.


همانطور که در تصویر فوق نیز مشاهده می‌کنید، این پروژه از دو برنامه تشکیل شده‌است:
الف) برنامه‌ی SPA که در پوشه‌ی ClientApp قرار گرفته‌است و شامل کدهای کامل یک برنامه‌ی React است.
ب) برنامه‌ی سمت سرور ASP.NET Core که یک برنامه‌ی متداول وب، به همراه فایل Startup.cs و سایر فایل‌های مورد نیاز آن است.

در ادامه نکات ویژه‌ی ساختار این پروژه را بررسی خواهیم کرد.


تجربه‌ی توسعه‌ی برنامه‌ها توسط این قالب ویژه

اکنون اگر این پروژه‌ی وب را برای مثال با فشردن دکمه‌ی F5 و یا اجرای دستور dotnet run، اجرا کنیم، چه اتفاقی رخ می‌دهد؟
- به صورت خلاصه برنامه‌ی ASP.NET Core شروع به کار کرده و سبب ارائه همزمان برنامه‌ی SPA نیز خواهد شد.
- پورتی که برنامه‌ی وب بر روی آن قرار دارد، با پورتی که برنامه‌ی React بر روی روی آن ارائه می‌شود، یکی است. یعنی نیازی به تنظیمات CORS را ندارد.
- در این حالت اگر در برنامه‌ی React تغییری را ایجاد کنیم (در هر قسمتی از آن)، hot reloading آن هنوز هم برقرار است و سبب بارگذاری مجدد برنامه‌ی SPA در مرورگر خواهد شد و برای اینکار نیازی به توقف و راه اندازی مجدد برنامه‌ی ASP.NET Core نیست.

اما این تجربه‌ی روان کاربری و توسعه، چگونه حاصل شده‌است؟


بررسی ساختار فایل Startup.cs یک پروژه‌ی مبتنی بر dotnet new react

برای درک نحوه‌ی عملکرد این قالب ویژه، نیاز است از فایل Startup.cs آن شروع کرد.
// ...
using Microsoft.AspNetCore.SpaServices.ReactDevelopmentServer;

namespace dotnet_template_sample
{
    public class Startup
    {
        // ...

        public void ConfigureServices(IServiceCollection services)
        {

            services.AddControllersWithViews();

            // In production, the React files will be served from this directory
            services.AddSpaStaticFiles(configuration =>
            {
                configuration.RootPath = "ClientApp/build";
            });
        }
در ابتدا تعریف فضای نام SpaServices را مشاهده می‌کنید. بسته‌ی متناظر با آن در فایل csproj برنامه به صورت زیر ثبت شده‌است:
<ItemGroup>
   <PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="3.1.2" />
</ItemGroup>
این بسته، همان بسته‌ی جدید SpaServices است و در NET 5x. نیز پشتیبانی خواهد شد .

در متد ConfigureServices، ثبت سرویس‌های مرتبط با فایل‌های استاتیک پروژه‌ی SPA، توسط متد AddSpaStaticFiles صورت گرفته‌است. در اینجا RootPath آن، به پوشه‌ی ClientApp/build اشاره می‌کند. البته این پوشه هنوز در این ساختار، قابل مشاهده نیست؛ اما زمانیکه پروژه‌ی ASP.NET Core را برای ارائه‌ی نهایی، publish کردیم، به صورت خودکار ایجاد شده و حاوی فایل‌های قابل ارائه‌ی برنامه‌ی React نیز خواهد بود.

قسمت مهم دیگر کلاس آغازین برنامه، متد Configure آن است:
// ...
using Microsoft.AspNetCore.SpaServices.ReactDevelopmentServer;

namespace dotnet_template_sample
{
    public class Startup
    {
        // ...

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            // ...
            app.UseStaticFiles();
            app.UseSpaStaticFiles();

            app.UseRouting();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller}/{action=Index}/{id?}");
            });

            app.UseSpa(spa =>
            {
                spa.Options.SourcePath = "ClientApp";

                if (env.IsDevelopment())
                {
                    spa.UseReactDevelopmentServer(npmScript: "start");
                }
            });
        }
    }
}
در اینجا ثبت سه میان افزار جدید را مشاهده می‌کنید:
- متد UseSpaStaticFiles، سبب ثبت میان‌افزاری می‌شود که امکان دسترسی به فایل‌های استاتیک پوشه‌ی ClientApp حاوی برنامه‌ی React را میسر می‌کند؛ مسیر این پوشه را در متد ConfigureServices تنظیم کردیم.
- متد UseSpa، سبب ثبت میان‌افزاری می‌شود که دو کار مهم را انجام می‌دهد:
1- کار اصلی آن، ثبت مسیریابی معروف catch all است تا مسیریابی‌هایی را که توسط کنترلرهای برنامه‌ی ASP.NET Core مدیریت نمی‌شوند، به سمت برنامه‌ی React هدایت کند. برای مثال مسیر https://localhost:5001/api/users به یک کنترلر API برنامه‌ی سمت سرور ختم می‌شود، اما سایر مسیرها مانند https://localhost:5001/login قرار است صفحه‌ی login برنامه‌ی سمت کلاینت SPA را نمایش دهند و متناظر با اکشن متد خاصی در کنترلرهای برنامه‌ی وب ما نیستند. در این حالت، کار این مسیریابی catch all، نمایش صفحه‌ی پیش‌فرض برنامه‌ی SPA است.
2- بررسی می‌کند که آیا شرایط IsDevelopment برقرار است؟ آیا در حال توسعه‌ی برنامه هستیم؟ اگر بله، میان‌افزار دیگری را به نام UseReactDevelopmentServer، اجرا و ثبت می‌کند.

برای درک عملکرد میان‌افزار ReactDevelopmentServer نیاز است به سورس آن مراجعه کرد. این میان‌افزار بر اساس پارامتر start ای که دریافت می‌کند، سبب اجرای npm run start خواهد شد. به این ترتیب دیگر نیازی به اجرای جداگانه‌ی این دستور نخواهد بود و همچنین این اجرا، به همراه تنظیمات proxy مخصوصی نیز هست تا پورت اجرایی برنامه‌ی React و برنامه‌ی ASP.NET Core یکی شده و دیگر نیازی به تنظیمات CORS مخصوص برنامه‌های React نباشد. بنابراین hot reloading ای که از آن صحبت شد، توسط ASP.NET Core مدیریت نمی‌شود. در پشت صحنه همان npm run start اصلی برنامه‌های React، در حال اجرای وب سرور آزمایشی React است که از hot reloading پشتیبانی می‌کند.

یک مشکل: با این تنظیم، هربار که برنامه‌ی ASP.NET Core اجرا می‌شود (به علت تغییرات در کدها و فایل‌های پروژه)، سبب اجرای مجدد و پشت صحنه‌ی react development server نیز خواهد شد که ... آغاز برنامه را در حالت توسعه، کند می‌کند. برای رفع این مشکل می‌توان این وب سرور توسعه‌ی برنامه‌های React را به صورت جداگانه‌ای اجرا کرد و فقط تنظیمات پروکسی آن‌را در اینجا ذکر نمود:
// replace
spa.UseReactDevelopmentServer(npmScript: "start");
// with
spa.UseProxyToSpaDevelopmentServer("http://localhost:3000");
در اینجا فقط کافی است سطر UseReactDevelopmentServer را با تنظیم UseProxyToSpaDevelopmentServer که به آدرس وب سرور توسعه‌ی برنامه‌های React اشاره می‌کند، تنظیم کنیم. بدیهی است در اینجا حالت باید از طریق خط فرمان به پوشه‌ی clientApp وارد شد و دستور npm start را یکبار به صورت دستی اجرا کرد، تا این وب سرور، راه اندازی شود.


تغییرات ویژه‌ی فایل csproj برنامه

اگر به فایل csproj برنامه دقت کنیم، دو تغییر جدید نیز در آن قابل مشاهده هستند:
الف) نصب خودکار وابستگی‌های برنامه‌ی client
  <Target Name="DebugEnsureNodeEnv"
     BeforeTargets="Build" 
     Condition=" '$(Configuration)' == 'Debug' And !Exists('$(SpaRoot)node_modules') ">
    <!-- Ensure Node.js is installed -->
    <Exec Command="node --version" ContinueOnError="true">
      <Output TaskParameter="ExitCode" PropertyName="ErrorCode" />
    </Exec>
    <Error Condition="'$(ErrorCode)' != '0'" Text="Node.js is required to build and run this project. To continue, please install Node.js from https://nodejs.org/, and then restart your command prompt or IDE." />
    <Message Importance="high" Text="Restoring dependencies using 'npm'. This may take several minutes..." />
    <Exec WorkingDirectory="$(SpaRoot)" Command="npm install" />
  </Target>
در این تنظیم، در حالت build و debug، ابتدا بررسی می‌کند که آیا پوشه‌ی node_modules برنامه‌ی SPA وجود دارد؟ اگر خیر، ابتدا مطمئن می‌شود که node.js بر روی سیستم نصب است و سپس دستور npm install را صادر می‌کند تا تمام وابستگی‌های برنامه‌ی client، دریافت و نصب شوند.

ب) یکی کردن تجربه‌ی publish برنامه‌ی ASP.NET Core با publish پروژه‌های React
  <Target Name="PublishRunWebpack" AfterTargets="ComputeFilesToPublish">
    <!-- As part of publishing, ensure the JS resources are freshly built in production mode -->
    <Exec WorkingDirectory="$(SpaRoot)" Command="npm install" />
    <Exec WorkingDirectory="$(SpaRoot)" Command="npm run build" />

    <!-- Include the newly-built files in the publish output -->
    <ItemGroup>
      <DistFiles Include="$(SpaRoot)build\**" />
      <ResolvedFileToPublish Include="@(DistFiles->'%(FullPath)')" Exclude="@(ResolvedFileToPublish)">
        <RelativePath>%(DistFiles.Identity)</RelativePath>
        <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
        <ExcludeFromSingleFile>true</ExcludeFromSingleFile>
      </ResolvedFileToPublish>
    </ItemGroup>
  </Target>
میان‌افزار ReactDevelopmentServer کار اجرا و پروکسی دستور npm run start را در حالت توسعه انجام می‌دهد. اما در حالت ارائه‌ی نهایی چطور؟ در اینجا نیاز است دستور npm run build اجرا شده و فایل‌های مخصوص ارائه‌ی نهایی برنامه‌ی React تولید و سپس به پوشه‌ی wwwroot، کپی شوند. تنظیم فوق، دقیقا همین کار را در حین publish برنامه‌ی ASP.NET Core، به صورت خودکار انجام می‌دهد و شامل این مراحل است:
-  ابتدا npm install را جهت اطمینان از به روز بودن وابستگی‌های برنامه مجددا اجرا می‌کند.
- سپس npm run build را برای تولید فایل‌های قابل ارائه‌ی برنامه‌ی React اجرا می‌کند.
- در آخر تمام فایل‌های پوشه‌ی ClientApp/build تولیدی را به بسته‌ی نهایی توزیعی برنامه‌ی ASP.NET Core، اضافه می‌کند.
اشتراک‌ها
بررسی Blazor United در دات نت 8

ASP.NET Community Standup - Blazor United in .NET 8
The Blazor team shares early thoughts on Blazor United in .NET 8, an effort to create a single unified model for all your web UI scenarios that combines the best of Razor Pages, Blazor Server, and Blazor WebAssembly.
 

بررسی Blazor United در دات نت 8
اشتراک‌ها
Angular v13 منتشر شد
Angular v13 is now Available. We’re back with the brand new release… | by Mark Thompson (@marktechson) | Nov, 2021 | Angular Blog
Angular v13 منتشر شد
نظرات اشتراک‌ها
خلاصه اخبار کنفرانس 21 ژانویه مایکروسافت در مورد ویندوز 10
موارد خیلی جالبی بود
فیلم هاش رو میتونید از آدرس‌های زیر دریافت کنید
لینک‌های یوتیوب رو مستقیم کردم. تقریبا یک هفته ای لینک‌ها اعتبار دارن از الان
دانلود زیرنویس تنها 4 عدد از ویدیو‌ها زیرنویس داشتند 
اشتراک‌ها
بررسی تغییرات ASP.NET Core در NET 8 Preview 6.

Here’s a summary of what’s new in this preview release:

  • Improved startup debugging experience
  • Blazor
    • Form model binding & validation with server-side rendering
    • Enhanced page navigation & form handling
    • Preserve existing DOM elements with streaming rendering
    • Specify component render mode at the call site
    • Interactive rendering with Blazor WebAssembly
    • Sections improvements
    • Cascade query string values to Blazor components
    • Blazor Web App template option for enabling server interactivity
    • Blazor template consolidation
  • Metrics
    • Testing metrics in ASP.NET Core apps
    • New, improved, and renamed counters
  • API authoring
    • Complex form binding support in minimal APIs
  • Servers & middleware
    • HTTP.sys kernel response buffering
    • Redis-based output-cache
     
بررسی تغییرات ASP.NET Core در NET 8 Preview 6.
اشتراک‌ها
Entity Framework Core 5.0 Preview 5 منتشر شد

Database collations

The default collation for a database can now be specified in the EF model.
This will flow through to generated migrations to set the collation when the database is created.
For example:

 modelBuilder.UseCollation("German_PhoneBook_CI_AS");
Entity Framework Core 5.0 Preview 5 منتشر شد
اشتراک‌ها
بی‌جهت لینوکسی‌ها را بخاطر باگ bash شرمنده نکنید

This is a defense of the most prolific and dedicated public servant that has graced the world in my lifetime. One man has added hundreds of billions, if not trillions of dollars of value to the global economy. This man has worked tirelessly for the benefit of everyone around him. It is impossible to name a publicly traded company that has not somehow benefited from his contributions, and many have benefited to the tune of billions. In return for the countless billions of wealth that people made from the fruits of his labor, he was rewarded with poverty and ridicule. Now that the world is done taking from him, they are heading to the next step of vilifying him as incompetent.

بی‌جهت لینوکسی‌ها را بخاطر باگ bash شرمنده نکنید
اشتراک‌ها
بهبودهای کارآیی LINQ در دات‌نت 9
.NET 9.0 LINQ Performance Improvements

With .NET 9, LINQ becomes faster in several common scenarios. As with every new version of .NET, you simply need to migrate and recompile to take advantage of these improvements. Additionally, LINQ has been optimized in other ways: SIMD is utilized whenever possible, such as when summing a sequence of integers. Moreover, enumerating empty sequences incurs lower costs due to early detection.
بهبودهای کارآیی LINQ در دات‌نت 9