نظرات مطالب
Kendo UI MVVM
از رخداد change باید استفاده کنید و یا رخداد requestEnd:
var dsReviewList = new kendo.data.DataSource({
    // ....
    change: function (e) {
        // change event is wired to success of the request.
       // `e.action` with possible values: "itemchange", "add", "remove" and "sync".
    },
    error: function (xhr, error) {
       // error event will be triggered if any error occurred for the request.
        console.debug(xhr); 
        console.debug(error);
    },
    requestEnd: function(e) {
      // Fired when a remote service request is finished.
      var response = e.response;
      var type = e.type;
      console.log(type);
      if (type == "undefined") {
         showError();
      }
      else {
         showSuccess(type);
     }
  }
});
اشتراک‌ها
Angular 7 در راه است

Today Angular Team released Angular 7 beta.0 release. Many of us will be curious about the kind of features and bug fixes that we can see in this beta release. 

Angular 7 در راه است
اشتراک‌ها
بررسی متد Array.prototype.includes

One of the two features that will be part of ECMAScript 2016 is the new Array.prototype.includes method. It determines whether an array contains a certain element and returns either true or false. 

بررسی متد Array.prototype.includes
اشتراک‌ها
افزایش کارایی برنامه های ASP.NET

we will look at some of the approaches that you can take to make optimized and better performing ASP.NET web sites. Some of these principles can also be applied to websites created in a technology other than ASP.NET.

افزایش کارایی برنامه های  ASP.NET
اشتراک‌ها
مقایسه‌ای بین سرعت NET 4.7.2. و NET Core 2.1.

.NET 4.7.2 is for streaming data into memory between 2% (Unsafe Parse x86), 7% (Unsafe Parse x64) and 40% (Span Parse x64) slower than .NET Core. Especially the 40% speed drop for Span based Apis due to the lack of JIT support by the .NET Runtime is unfortunate.  

مقایسه‌ای بین سرعت NET 4.7.2. و NET Core 2.1.
اشتراک‌ها
دوره پیاده سازی minimal API با دات نت 7

.NET 7 minimal API from scratch | FULL COURSE | clean architecture, repository pattern, CQRS MediatR

In this course I want to provide you a project structure and code organization to get you started with real .NET 7 minimal API projects. It's a full course on this topic where I start from creating and explaining the project structure, setting up different layers using EF Core, repository pattern, CQRS and MediatR. The biggest part of the video is however around the .NET 7 minimal API, taking you from the initial setup, explaining route handlers, implementing all CRUD operations and so on. Last but not least, this course walks you through the process of refactoring the .NET 7 minimal API so that it becomes readable, maintainable and scalable. At the end, you'll have a full project structure organized according to modern architectural patterns that you can take as a template for your own projects.

Contents
1. Intro: 00:00
2. Structuring the solution: 01:00
3. Coding the domain layer: 05:25
4. Coding the data access layer: 08:22
5. Creating repositories: 11:17
6. Adding migrations and database update: 22:30
7. CQRS with MediatR: 29:07
8. Route and rout handlers: 52:06
9. Dependency injection: 55:52
10. Implementing GET by ID : 57:40
11. Implementing POST route: 01:00:26
12. Implementing GET all route: 01:03:41
13. Implement PUT and DELETE: 01:04:57
14. Testing with Postman: 01:09:01
15. Is there a problem? 01:12:41
16. Refactoring service registrations: 01:15:49
17. Refactoring route registrations: 01:20:01
18. Automatic registration of endpoints: 01:26:28
19. Introducing route groups:  01:31:43
20. Extract lambdas into instance methods: 01:34:31
21: Model validation with endpoint filters: 01:45:58
22. Global exception handling: 01:55:10
23. Conclusions: 01:59:49 

دوره پیاده سازی minimal API با دات نت 7
مطالب
معادل‌های چندسکویی اجزای فایل web.config در ASP.NET Core
هنوز هم اجزای مختلف فایل web.config در ASP.NET Core قابل تعریف و استفاده هستند؛ اما اگر صرفا بخواهیم از این نوع برنامه‌ها در ویندوز و به کمک وب سرور IIS استفاده کنیم. با انتقال برنامه‌های چندسکویی مبتنی بر NET Core. به سایر سیستم عامل‌ها، دیگر اجزایی مانند استفاده‌ی از ماژول فشرده سازی صفحات IIS و یا ماژول URL rewrite آن و یا تنظیمات static cache تعریف شده‌ی در فایل web.config، شناسایی نشده و تاثیری نخواهند داشت. به همین جهت تیم ASP.NET Core، معادل‌های توکار و چندسکویی را برای عناصری از فایل web.config که به IIS وابسته هستند، تهیه کرده‌است که در ادامه آن‌‌ها را مرور خواهیم کرد.


میان‌افزار چندسکویی فشرده سازی صفحات در ASP.NET Core

پیشتر مطلب «استفاده از GZip توکار IISهای جدید و تنظیمات مرتبط با آن‌ها» را در سایت جاری مطالعه کرده‌اید. این قابلیت صرفا وابسته‌است به IIS و همچنین در صورت نصب بودن ماژول httpCompression آن کار می‌کند. بنابراین قابلیت انتقال به سایر سیستم عامل‌ها را نخواهد داشت و هرچند تنظیمات فایل web.config آن هنوز هم در برنامه‌های ASP.NET Core معتبر هستند، اما چندسکویی نیستند. برای رفع این مشکل، تیم ASP.NET Core، میان‌افزار توکاری را برای فشرده سازی صفحات ارائه داده‌است که جزئی از تازه‌های ASP.NET Core 1.1 نیز به‌شمار می‌رود.
برای نصب آن دستور ذیل را در کنسول پاورشل نیوگت، اجرا کنید:
 PM> Install-Package Microsoft.AspNetCore.ResponseCompression
که معادل است با افزودن وابستگی ذیل به فایل project.json پروژه:
{
    "dependencies": {
        "Microsoft.AspNetCore.ResponseCompression": "1.0.0"
    }
}

مرحله‌ی بعد، افزودن سرویس‌های و میان افزار مرتبط، به کلاس آغازین برنامه هستند. همیشه متدهای Add کار ثبت سرویس‌های میان‌افزار را انجام می‌دهند و متدهای Use کار افزودن خود میان‌افزار را به مجموعه‌ی موجود تکمیل می‌کنند.
public void ConfigureServices(IServiceCollection services)
{
    services.AddResponseCompression(options =>
    {
        options.MimeTypes = Microsoft.AspNetCore.ResponseCompression.ResponseCompressionDefaults.MimeTypes;
    });
}
متد AddResponseCompression کار افزودن سرویس‌های مورد نیاز میان‌افزار ResponseCompression را انجام می‌دهد. در اینجا می‌توان تنظیماتی مانند MimeTypes فایل‌ها و صفحاتی را که باید فشرده سازی شوند، تنظیم کرد. ResponseCompressionDefaults.MimeTypes به این صورت تعریف شده‌است:
namespace Microsoft.AspNetCore.ResponseCompression
{
    /// <summary>
    /// Defaults for the ResponseCompressionMiddleware
    /// </summary>
    public class ResponseCompressionDefaults
    {
        /// <summary>
        /// Default MIME types to compress responses for.
        /// </summary>
        // This list is not intended to be exhaustive, it's a baseline for the 90% case.
        public static readonly IEnumerable<string> MimeTypes = new[]
        {
            // General
            "text/plain",
            // Static files
            "text/css",
            "application/javascript",
            // MVC
            "text/html",
            "application/xml",
            "text/xml",
            "application/json",
            "text/json",
        };
    }
}
اگر علاقمند بودیم تا عناصر دیگری را به این لیست اضافه کنیم، می‌توان به نحو ذیل عمل کرد:
services.AddResponseCompression(options =>
{
    options.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(new[]
                                {
                                    "image/svg+xml",
                                    "application/font-woff2"
                                });
            });
در اینجا تصاویر از نوع svg و همچنین فایل‌های فونت woff2 نیز اضافه شده‌اند.

به علاوه options ذکر شده‌ی در اینجا دارای خاصیت options.Providers نیز می‌باشد که نوع و الگوریتم فشرده سازی را مشخص می‌کند. در صورتیکه مقدار دهی نشود، مقدار پیش فرض آن Gzip خواهد بود:
services.AddResponseCompression(options =>
{
  //If no compression providers are specified then GZip is used by default.
  //options.Providers.Add<GzipCompressionProvider>();

همچنین اگر علاقمند بودید تا میزان فشرده سازی تامین کننده‌ی Gzip را تغییر دهید، نحوه‌ی تنظیمات آن به صورت ذیل است:
services.Configure<GzipCompressionProviderOptions>(options =>
{
  options.Level = System.IO.Compression.CompressionLevel.Optimal;
});

به صورت پیش‌فرض، فشرده سازی صفحات Https انجام نمی‌شود. برای فعال سازی آن تنظیم ذیل را نیز باید قید کرد:
 options.EnableForHttps = true;

مرحله‌ی آخر این تنظیمات، افزودن میان افزار فشرده سازی خروجی به لیست میان افزارهای موجود است:
public void Configure(IApplicationBuilder app)
{
   app.UseResponseCompression()  // Adds the response compression to the request pipeline
   .UseStaticFiles(); // Adds the static middleware to the request pipeline  
}
در اینجا باید دقت داشت که ترتیب تعریف میان‌افزارها مهم است و اگر UseResponseCompression پس از UseStaticFiles ذکر شود، فشرده سازی صورت نخواهد گرفت؛ چون UseStaticFiles کار ارائه‌ی فایل‌ها را تمام می‌کند و نوبت اجرا، به فشرده سازی اطلاعات نخواهد رسید.


تنظیمات کش کردن چندسکویی فایل‌های ایستا در ASP.NET Core

تنظیمات کش کردن فایل‌های ایستا در web.config مخصوص IIS به صورت ذیل است :
<staticContent>
   <clientCache httpExpires="Sun, 29 Mar 2020 00:00:00 GMT" cacheControlMode="UseExpires" />
</staticContent>
معادل چندسکویی این تنظیمات در ASP.NET Core با تنظیم Response.Headers میان افزار StaticFiles انجام می‌شود:
public void Configure(IApplicationBuilder app,
                      IHostingEnvironment env,
                      ILoggerFactory loggerFactory)
{
    app.UseResponseCompression()
       .UseStaticFiles(
           new StaticFileOptions
           {
               OnPrepareResponse =
                   _ => _.Context.Response.Headers[HeaderNames.CacheControl] = 
                        "public,max-age=604800" // A week in seconds
           })
       .UseMvc(routes => routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}"));
}
در اینجا پیش از آماده شدن یک فایل استاتیک برای ارائه‌ی نهایی، می‌توان تنظیمات Response آن‌را تغییر داد و برای مثال هدر Cache-Control آن‌را به یک هفته تنظیم نمود.


معادل چندسکویی ماژول URL Rewrite در ASP.NET Core

مثال‌هایی از ماژول URL Rewrite را در مباحث بهینه سازی سایت برای بهبود SEO پیشتر بررسی کرده‌ایم (^ و ^ و ^). این ماژول نیز همچنان در ASP.NET Core هاست شده‌ی در ویندوز و IIS قابل استفاده است (البته به شرطی که ماژول مخصوص آن در IIS نصب و فعال شده باشد). معادل چندسکویی این ماژول به صورت یک میان‌افزار توکار به ASP.NET Core 1.1 اضافه شده‌است.
برای استفاده‌ی از آن، ابتدا نیاز است بسته‌ی نیوگت آن‌را به نحو ذیل نصب کرد:
 PM> Install-Package Microsoft.AspNetCore.Rewrite
و یا افزودن آن به لیست وابستگی‌های فایل project.json:
{
    "dependencies": {
        "Microsoft.AspNetCore.Rewrite": "1.0.0"
    }
}

پس از نصب آن، نمونه‌ای از نحوه‌ی تعریف و استفاده‌ی آن در کلاس آغازین برنامه به صورت ذیل خواهد بود:
public void Configure(IApplicationBuilder app)
{
    app.UseRewriter(new RewriteOptions()
                            .AddRedirectToHttps()
                            .AddRewrite(@"app/(\d+)", "app?id=$1", skipRemainingRules: false) // Rewrite based on a Regular expression
                            //.AddRedirectToHttps(302, 5001) // Redirect to a different port and use HTTPS
                            .AddRedirect("(.*)/$", "$1")  // remove trailing slash, Redirect using a regular expression
                            .AddRedirect(@"^section1/(.*)", "new/$1", (int)HttpStatusCode.Redirect)
                            .AddRedirect(@"^section2/(\\d+)/(.*)", "new/$1/$2", (int)HttpStatusCode.MovedPermanently)
                            .AddRewrite("^feed$", "/?format=rss", skipRemainingRules: false));
این میان‌افزار نیز باید پیش از میان افزار فایل‌های ایستا و همچنین MVC معرفی شود.

در اینجا مثال‌هایی را از اجبار به استفاده‌ی از HTTPS، تا حذف / از انتهای مسیرهای وب سایت و یا هدایت آدرس قدیمی فید سایت، به آدرسی جدید واقع در مسیر format=rss، توسط عبارات باقاعده مشاهده می‌کنید.
در این تنظیمات اگر پارامتر skipRemainingRules به true تنظیم شود، به محض برآورده شدن شرط انطباق مسیر (پارامتر اول ذکر شده)، بازنویسی مسیر بر اساس پارامتر دوم، صورت گرفته و دیگر شرط‌های ذکر شده، پردازش نخواهند شد.

این میان‌افزار قابلیت دریافت تعاریف خود را از فایل‌های web.config و یا htaccess (لینوکسی) نیز دارد:
 app.UseRewriter(new RewriteOptions()
.AddIISUrlRewrite(env.ContentRootFileProvider, "web.config")
.AddApacheModRewrite(env.ContentRootFileProvider, ".htaccess"));
بنابراین اگر می‌خواهید تعاریف قدیمی <system.webServer><rewrite><rules> وب کانفیگ خود را در اینجا import کنید، متد AddIISUrlRewrite چنین کاری را به صورت خودکار برای شما انجام خواهد داد و یا حتی می‌توان این تنظیمات را در یک فایل UrlRewrite.xml نیز قرار داد تا توسط IIS پردازش نشود و مستقیما توسط ASP.NET Core مورد استفاده قرار گیرد.

و یا اگر خواستید منطق پیچیده‌تری را نسبت به عبارات باقاعده اعمال کنید، می‌توان یک IRule سفارشی را نیز به نحو ذیل تدارک دید:
public class RedirectWwwRule : Microsoft.AspNetCore.Rewrite.IRule
{
    public int StatusCode { get; } = (int)HttpStatusCode.MovedPermanently;
    public bool ExcludeLocalhost { get; set; } = true;
    public void ApplyRule(RewriteContext context)
    {
        var request = context.HttpContext.Request;
        var host = request.Host;
        if (host.Host.StartsWith("www", StringComparison.OrdinalIgnoreCase))
        {
            context.Result = RuleResult.ContinueRules;
            return;
        }
        if (ExcludeLocalhost && string.Equals(host.Host, "localhost", StringComparison.OrdinalIgnoreCase))
        {
            context.Result = RuleResult.ContinueRules;
            return;
        }
        string newPath = request.Scheme + "://www." + host.Value + request.PathBase + request.Path + request.QueryString;
 
        var response = context.HttpContext.Response;
        response.StatusCode = StatusCode;
        response.Headers[HeaderNames.Location] = newPath;
        context.Result = RuleResult.EndResponse; // Do not continue processing the request
    }
}
در اینجا تنظیم context.Result به RuleResult.ContinueRules سبب ادامه‌ی پردازش درخواست جاری، بدون تغییری در نحوه‌ی پردازش آن خواهد شد. در آخر کار، با تغییر HeaderNames.Locatio به مسیر جدید و تنظیم Result = RuleResult.EndResponse، سبب اجبار به بازنویسی مسیر درخواستی، به مسیر جدید تنظیم شده، خواهیم شد.

و سپس می‌توان آن‌را به عنوان یک گزینه‌ی جدید Rewriter معرفی نمود:
 app.UseRewriter(new RewriteOptions().Add(new RedirectWwwRule()));
کار این IRule جدید، اجبار به درج www در آدرس‌های هدایت شده‌ی به سایت است؛ تا تعداد صفحات تکراری گزارش شده‌ی توسط گوگل به حداقل برسد (یک نگارش با www و دیگری بدون www).

یک نکته: در اینجا در صورت نیاز می‌توان از تزریق وابستگی‌های در سازنده‌ی کلاس Rule جدید تعریف شده نیز استفاده کرد. برای اینکار باید RedirectWwwRule را به لیست سرویس‌های متد ConfigureServices معرفی کرد و سپس نحوه‌ی دریافت وهله‌ای از آن جهت معرفی به میان‌افزار بازنویسی مسیرهای وب به صورت ذیل درخواهد آمد:
 var options = new RewriteOptions().Add(app.ApplicationServices.GetService<RedirectWwwRule>());