در ادامه افشای اطلاعات کاربران فضای مجازی طی روزهای اخیر که مربوط به لو رفتن اطلاعات کاربران نسخه غیررسمی اپلیکیشن تلگرام و یکی از بازارهای ایرانی نرم افزارهای آیفون میشد، شب گذشته نیز یک ربات تلگرامی، اطلاعات شناسنامه ای ۸۰ میلیون ایرانی را از طریق درج کد ملی هر شخص، در اختیار کاربران قرار داده است. ظاهرا تمامی دیتابیس سازمان ثبت احوال کپی برداری شده است و هکرهای آن مدعی فروش آن به ازای 10 بیت کوین شده اند.
در کشور بسیاری از اوقات دسترسی به پروتکل HTTPS به کندی صورت میگیرد. گاهی از اوقات نیز این دسترسی غیر ممکن میشود تا حد دریافت چند بایت در دقیقه. همین مساله تاکنون بر روی بسیاری از مسایل دیگر نیز تاثیر گذار بوده است؛ برای مثال اگر یک مخزن کد را مثلا در CodePlex یا GitHub داشته باشید، چون تمام Commitها از طریق همین پروتکل امن صورت میگیرد، کار کردن با آنها بسیار مشکل خواهد شد. نمونهی دیگر آن دسترسی به NuGet است. فید NuGet در VS.NET به Https تنظیم شده است. اگر دسترسی به Https برای شما به کندی صورت میگیرد فقط کافی است مسیر فید آنرا در منوی Tools، گزینهی Options، ذیل قسمت Package manager یافته و به http://nuget.org/api/v2 تغییر دهید؛ یعنی به Http خالی، بجای Https؛ تا سرعت دریافت بستههای NuGet مورد نظر افزایش یابند.
دریافت مستقیم بستههای نیوگت
برای دریافت بستههای نیوگت که دارای پسوند nupkg هستند، اما در اصل یک فایل zip بیشتر نیستند، الزامی به استفاده از ابزار و افزونه نیوگت در VS.NET نیست. میتوان این بستهها را به صورت مستقیم نیز دریافت کرد. برای مثال اگر آدرس بستهای در سایت NuGet به صورت زیر است:
https://www.nuget.org/packages/PropertyChanged.Fody
برای دریافت مستقیم آن کافی است آدرس ذیل را درخواست کنید:
https://www.nuget.org/api/v2/package/PropertyChanged.Fody/1.42.0
یک api/v2 به این لینک اضافه میشود به همراه شماره نگارش مدنظر برای دریافت:
https://www.nuget.org/api/v2/package/{packageID}/{packageVersion}
به صورت خلاصه:
لینک اصلی کتابخانه: https://www.nuget.org/packages/Twitter.Bootstrap.RTL.Less/3.0.0
لینک دانلود آن: https://www.nuget.org/api/v2/package/Twitter.Bootstrap.RTL.Less/3.0.0
راه دیگر، ساخت دستی این آدرس است:
https://az320820.vo.msecnd.net/packages/propertychanged.fody.1.42.0.nupkg
که در حقیقت تشکیل شده است از:
https://az320820.vo.msecnd.net/packages/{name}.{version}.nupkg
اهمیت تنظیمات IE
اگر پیام قطع شدن اتصال یا مشکلات DNS را در کنسول NuGet در VS.NET دریافت میکنید، ابتدا سعی کنید همان روش ذکر شده در ابتدای بحث را امتحان کنید. اگر کار نکرد احتمالا مشکل از تنظیمات IE است. برای مثال اگر بر روی تنظیمات اتصالی شما در IE یک پروکسی غیرقابل دسترسی در زمان جاری، تنظیم شده باشد، این مساله مستقیما بر روی اتصالات برنامههای دات نتی نیز تاثیر گذار است. بنابراین ابتدا لینک nupkg را که ساختهاید یکبار با IE امتحان کنید. اگر قابل دریافت نبود یعنی تنظیمات آن به هم ریخته است و این مساله بر روی بسیاری از برنامههای دیگر نیز تاثیر گذار است.
در قسمت اول با مفاهیم اولیه Class و Object آشنا شدیم.
Messages and Methods
Objectها باید مانند ماشینهایی تلقی شوند که عملیات موجود در واسط عمومی خود را برای افرادی که درخواست مناسبی ارسال کنند، اجرا خواهند کرد. با توجه به اینکه یک object از استفاده کننده خود مستقل است و وابستگی به او ندارد و همچنین توجه به ساختار نحوی (syntax) برخی از زبانهای شیء گرای جدید، عبارت «sending a message» برای توصیف اجرای رفتاری از مجموعه رفتارهای object، استفاده میشود.
به محض اینکه پیغامی (Message) به سمت object ارسال شود، ابتدا باید تصمیم بگیرد که این پیغام ارسالی را درک میکند. فرض کنیم این پیغام قابل درک است. در این صورت object مورد نظر، همزمان با نگاشت پیغام به یک فراخوانی تابع (function call)، خود را به صورت ضمنی به عنوان اولین آرگومان ارسال میکند. تصمیم گرفتن در رابطه با قابل درک بودن یک پیغام، در زبانهای مفسری در زمان اجرا و در زبانهای کامپایلری در زمان کامپایل، انجام میگرد.
نام (یا prototype) رفتار یک وهله، Message (پیغام) نامیده میشود. بسیاری از زبانهای شیء گرا مفهموم Overloaded Functions Or Operators را پشتیبانی میکنند. در این صورت میتوان در سیستم دو تابعی داشت که با نام یکسان، یا انواع مختلف آرگومان (intraclass overloading) داشته باشند یا در کلاسهای مختلفی (interclass overloading) قرار گیرند.
ممکن است کلاس ساعت زنگدار، دو پیغام set_time که یکی از آنها با دو آرگومان از نوع عدد صحیح و دیگری یک آرگومان رشتهای است داشته باشد.
void AlarmClock::set_time(int hours, int minutes); void AlarmClock::set_time(String time);
در مقابل، کلاس ساعت زنگدار و کلاس ساعت مچی هر دو messageای به نام set_time با دو آرگومان از نوع عدد صحیح دارند.
void AlarmClock::set_time(int hours, int minutes); void Watch::set_time(int hours, int minutes);
باید توجه کنید که یک پیغام، شامل نام تابع، انواع آرگومان، نوع بازگشتی و کلاسی که پیغام به آن متصل است، میباشد. این اطلاعاتی که مطرح شد، بخش اصلی چیزی است که کاربر یک کلاس نیاز دارد در مورد آنها آگاهی داشته باشد.
در برخی از زبانها و یا سیستمها، اطلاعات دیگری مانند: انواع استثناءهایی که از سمت پیغام پرتاب میشوند تا اطلاعات همزمانی (پیغام به صورت همزمان است یا ناهمزمان) را برای استفاده کننده مهیا کنند. از طرفی پیاده سازی کنندگان یک کلاس باید از پیاده سازی پیغام آگاه باشند. جزئیات پیاده سازی یک پیغام -کدی که پیغام را پیاده سازی میکند- Method (متد) نامیده میشود. آنگاه که نخ (thread) کنترل درون متد باشد، برای مشخص کردن اینکه پیغام رسیده برای کدام وهله ارسال شدهاست، ارجاعی به وهله مورد نظر و به عنوان اولین آرگومان، به صورت ضمنی ارسال میشود. این آرگومان ضمنی، در بیشتر زبانها Self Object نامیده میشود (در سی پلاس پلاس this object نام دارد). در نهایت، مجموعه پیغامهایی که یک وهله میتواند به آنها پاسخ دهد، Protocol (قرارداد) نام دارد.
دو پیغام خاصی که کلاسها یا وهلهها میتوانند به آنها پاسخ دهند، اولی که استفاده کنندگان کلاس برای ساخت وهلهها از آن استفاده میکنند، Constructor (سازنده) نام دارد. هر کلاسی میتواند سازندههای متعددی داشته باشد که هر کدام مجموعه پارامترهای مختلفی را برای مقدار دهی اولیه میپذیرند. دومین پیغام، عملیاتی است که وهله را قبل از حذف از سیستم، پاک سازی میکند. این عملیات، Destructor (تخریب کننده) نام دارد. بیشتر زبانهای شیء گرا، برای هر کلاس تنها یک تخریب کننده دارند. این پیغامها را به عنوان مکانیزم مقدار دهی اولیه و پاک سازی در پارادایم شیء گرا در نظر بگیرید.
قاعده شهودی 2.2
استفاده کنندگان از کلاس باید به واسط عمومی آن وابسته باشند، اما یک کلاس نباید به استفاده کنندگان خود، وابسته باشد. (Users of a class must be dependent on its public interface, but a class should not be dependent on its users)
منطق پشت این قاعده، یکی از شکلهای قابلیت استفاده مجدد (resuability) میباشد. یک ساعت زنگدار ممکن است توسط شخصی در اتاق خواب او استفاده شود. واضح است که شخص مورد نظر به واسط عمومی ساعت زنگدار وابسته میباشد. به هر حال، ساعت زنگدار نباید به شخصی وابسته باشد. اگر ساعت زنگدار به شخصی وابسته باشد، بدون مهیا کردن یک شخص، نمیتوان از آن برای ساخت یک TimeLockSafe استفاده کرد. این وابستگیها برای مواقعیکه میخواهیم امکان این را داشته باشیم تا کلاس ساعت زنگدار را از دامین (domain) خود خارج کرده و در دامین دیگری، بدون وابستگی هایش مورد استفاده قرار دهیم، نامطلوب هستند.
شکل 2.4 The Use Of Alarm Clocks
قاعده شهودی 2.3
تعداد پیغامهای موجود در قرارداد یک کلاس را کمینه سازید. (Minimize the number of messages in the protocol of a class)
چندین سال قبل، مطلبی منتشر شد که کاملا متضاد این قاعده شهودی میباشد. طبق آن، پیاده سازی کننده یک کلاس میتواند یکسری عملیات را با فرض اینکه در آینده مورد استفاده قرار گیرند، برای آن در نظر بگیرد. ایراد این کار چیست؟ اگر شما از این قاعده پیروی کنید، حتما کلاس LinkedList من، توجه شما را جلب خواهد کرد؛ این کلاس در واسط عمومی خود 4000 عملیات را دارد. فرض کنید قصد ادغام دو وهله از این کلاس را داشته باشید. در این صورت حتما فرض شما این است که عملیاتی تحت عنوان merge در این کلاس تعبیه شده است. بعد از جستجوی بین این تعداد عملیات، در نهایت این عملیات خاص را پیدا نخواهید کرد. چراکه این عملیات متأسفانه به صورت یک overloaded plus operator پیاده سازی شده است. مشکل اصلی واسط عمومی با تعداد زیادی عملیات این است که فرآیند یافتن عملیات مورد نظرمان را خیلی سخت یا حتی ناممکن خواهد کرد و مشکلی جدی برای قابلیت استفاده مجدد تلقی میشود.
با کمینه نگه داشتن تعداد عملیات واسط عمومی، سیستم، قابل فهمتر و همچنین مولفههای (components) آن به راحتی قابل استفاده مجدد خواهند بود.
قاعده شهودی 2.4
پیاده سازی یک واسط عمومی یکسان کمینه برای همه کلاسها (Implement a minimal public interface that all classes understand [e.g., operations such as copy (deep versus shallow), equality testing, pretty printing, parsing from an ASCII description, etc.].)
مهیا کردن یک واسط عمومی مشترک کمینه برای کلاسهایی که توسط یک توسعه دهنده پیاده سازی شده و قرار است توسط توسعه دهندگان دیگر مورد استفاده قرار گیرد، خیلی مفید خواهد بود. این واسط عمومی، حداقل عاملیتی را که به طور منطقی از هر کلاس میشود انتظار داشت، مهیا خواهد ساخت. واسطی که میتواند از آن به عنوان مبنای یادگیری درباره رفتارهای کلاسها در پایه نرم افزاری با قابلیت استفاده مجدد، بهره برد.
به عنوان مثال کلاس Object در دات نت به عنوان کلاس پایه ضمنی با یکسری از متدهای عمومی (برای مثال ToString)، نشان دهنده تعریف یک واسط عمومی مشترک برای همه کلاسها در این فریمورک، میباشد.
public class Object { public Object(); public static bool Equals(Object objA, Object objB){...} public static bool ReferenceEquals(Object objA, Object objB){...} public virtual bool Equals(Object obj){...} public virtual int GetHashCode(){...} public Type GetType(){...} public virtual string ToString(){...} protected Object MemberwiseClone(){...} }
قاعده شهودی 2.5
جزئیات پیاده سازی، مانند توابع خصوصی common-code ( توابعی که کد مشترک سایر متدهای کلاس را در بدنه خود دارند) را در واسط عمومی یک کلاس قرار ندهید. (Do not put implementation details such as common-code private functions into the public interface of a class)
این قاعده برای کاهش پیچیدگی واسط عمومی کلاس برای استفاده کنندگان آن، طراحی شده است. ایده اصلی این است که استفاده کنندگان کلاس تمایلی ندارند به اعضایی دسترسی داشته باشند که از آنها استفاده نخواهند کرد؛ این اعضا باید به صورت خصوصی در کلاس قرار داده شوند. این توابع خصوصی common-code، زمانیکه متدهای یک کلاس، کد مشترکی را داشته باشند، ایجاد خواهند شد. قرار دادن این کد مشترک در یک متد، معمولا روش مناسبی میباشد. نکته قابل توجه این است که این متد، عملیات جدیدی نمیباشد؛ بله جزئیات پیاده سازی دو عملیات دیگر از کلاس را ساده کرده است.
شکل 2.5 Example of a common-code private function
مثال واقعی
فرض کنید در شکل بالا، کلاس X معادل یک LinkedList کلاس، f1و f2 به عنوان توابع insert و remove و تابع f به عنوان تابع common-code که عملیات یافتن آدرس را برای درج و حذف انجام میدهد، میباشند.
قاعده شهودی 2.6
واسط عمومی کلاس را با اقلامی که یا استفاده کنندگان از کلاس توانایی استفاده از آن را نداشته و یا تمایلی به استفاده از آنها ندارند، آمیخته نکنید. (Do not clutter the public interface of a class with items that users of that class are not able to use or are not interested in using )
این قاعده شهودی با قاعده قبلی که با قرار دادن تابع common-code در واسط عمومی کلاس، فقط باعث در هم ریختن واسط عمومی شده بود، مرتبط میباشد. در برخی از زبانها مانند C++، برای مثال این امکان وجود دارد که سازنده یک کلاس انتزاعی (abstract) را در واسط عمومی آن قرار دهید؛ حتی با وجود اینکه در زمان استفاده از آن سازنده با خطای نحوی روبرو خواهید شد. این قاعده شهودی کلی، برای کاهش این مشکلات در نظر گرفته شده است.
سؤال: چگونه میتوان این مجوزها را با کدنویسی دریافت یا تعیین اعتبار کرد؟
قطعه کد زیر، نحوه دریافت مجوز SSL یک سایت را نمایش میدهد:
using System; using System.Diagnostics; using System.IO; using System.Net; using System.Security.Cryptography.X509Certificates; namespace DownloadCerts { class Program { static void Main(string[] args) { // صرفنظر از خطاهای احتمالی مجوز ServicePointManager.ServerCertificateValidationCallback = delegate { return true; }; var url = "https://pdfreport.codeplex.com"; var request = WebRequest.Create(url) as HttpWebRequest; request.Method = WebRequestMethods.Http.Head; using (var response = request.GetResponse()) { /* در اینجا مجوز، در صورت وجود دریافت شده */ } if (request.ServicePoint.Certificate == null) return; // ذخیره سازی مجوز در فایل var cert = new X509Certificate2(request.ServicePoint.Certificate); Console.WriteLine("Expiration Date: {0}", cert.GetExpirationDateString()); var data = cert.Export(X509ContentType.Cert); File.WriteAllBytes("site.cer", data); Process.Start(Environment.CurrentDirectory); } } }
سپس یک درخواست ساده را به آدرس سرور مورد نظر ارسال میکنیم. پس از پایان درخواست، خاصیت request.ServicePoint.Certificate با مجوز SSL یک سایت مقدار دهی شده است. در ادامه نحوه ذخیره سازی این مجوز را با فرمت cer مشاهده میکنید.
احراز هویت و اعتبارسنجی کاربران در برنامههای Angular - قسمت چهارم - به روز رسانی خودکار توکنها
- dotnet-ignore : این ابزار جهت دریافت فایلهای gitignore. کاربرد داشته و از یک مخزن عمومی گیت هاب جهت دریافت این فایلها استفاده میکند. این مخزن شامل انواع قالبهای gitignore در پروژههای متفاوت میباشد. با استفاده از این ابزار، ایجاد فایل gitignore راحتتر و سریعتر امکانپذیر میباشد.
- dotnet-serve : میزبانی و نمایش لیست فایلهای استاتیک محلی و اجرای آنها را در بستر http، فراهم مینماید.
- dotnet-cleanup : جهت پاکسازی محیط بیلد مانند دایرکتوریهای bin و obj میباشد. همان کار گزینه clean در منوی بیلد را بازی میکند.
- dotnet-warp : این ابزار در واقع پروژه Warp است که برای ایجاد یک تک فایل اجرایی جهت انتقال راحتتر فایل پروژه صورت میگیرد که همه وابستگیهای آن در همان تک فایل قرار میگیرد.
- Amazon.ECS.Tools , Amazon.ElasticBeanstalk.Tools و Amazon.Lambda.Tools : این ابزارها که به صورت رسمی از طرف آمازون ارائه شدهاند که جهت deploy شدن راحتتر پروژه به محیطهای توسعه وب آمازون مورد استفاده قرار میگیرند.
dotnet tool install -g dotnet-ignore
dotnet tool list -g
dotnet tool update -g dotnet-ignore
dotnet tool uninstall -g dotnet-ignore
<PropertyGroup> <PackAsTool>true</PackAsTool> <ToolCommandName>dotnet-mytool</ToolCommandName> <PackageOutputPath>./nupkg</PackageOutputPath> </PropertyGroup>
dotnet tool install --global --add-source ./nupkg globaltools
dotnet-mytool
https://www.nuget.org/packages/McMaster.Extensions.CommandLineUtils
[Command(Description="Add a new note")] public class NewNote { [Required] [Option(Description="title of note")] public string Title{ get; set; } [Option(Description="content of note")] public string Body{ get; set; } }
[Command(Description="Add a new note")] public class NewNote:BaseClass { [Required] [Option(Description="title of note")] public string Title{ get; set; } [Option(Description="content of note")] public string Body{ get; set; } public void OnExecute(IConsole console) { var dir = GetBaseDirectory(); if(!Directory.Exists(dir)) { Directory.CreateDirectory(dir); } var filePath = Path.Combine(dir, Title + ".txt"); File.WriteAllText(filePath, Body); console.WriteLine("the note is saved"); } }
public class BaseClass { protected string GetBaseDirectory(){ var baseDirectory = Environment.CurrentDirectory; return (Path.Combine(baseDirectory, "notes")); } }
public class List:BaseClass { [Option(Description="search a phrase in notes title")] public string Grep{ get; set; } public void OnExecute(IConsole console) { try { var baseDirectory = GetBaseDirectory(); var dir = new DirectoryInfo(baseDirectory); var files = dir.GetFiles(); foreach(var file in files) { if(!String.IsNullOrEmpty(Grep) && !file.Name.Contains(Grep)) continue; console.WriteLine(Path.GetFileNameWithoutExtension(file.Name)); } } catch (Exception e) { console.WriteLine(e.Message); } } }
[Command(Description="show contnet of note")] public class Show:BaseClass { [Required] [Option(Description="title of note")] public string Title{ get; set; } public void OnExecute(IConsole console){ var baseDirectory = GetBaseDirectory(); var file = Path.Combine(baseDirectory, Title+".txt"); if(!File.Exists(file)) { console.WriteLine("The Note NotFound..."); return; } console.WriteLine(File.ReadAllText(file)); } }
[Command(Description="An Immediate Note Saver")] [Subcommand(typeof(NewNote),typeof(List),typeof(Show))] class Program { static int Main(string[] args) { return CommandLineApplication.Execute<Program>(args); } public int OnExecute(CommandLineApplication app, IConsole console) { console.WriteLine("You must specify a subcommand."); console.WriteLine(); app.ShowHelp(); return 1; } }
static int Main(string[] args) { return CommandLineApplication.Execute<Program>(args); }
PS D:\projects\Samples\globaltools> dotnet-notes new-note -t "sample1" -b "this is body" the note is saved PS D:\projects\Samples\globaltools> dotnet-notes new-note -t "test1" -b "this is body of another note" the note is saved PS D:\projects\Samples\globaltools> dotnet-notes list sample1 test1 PS D:\projects\Samples\globaltools> dotnet-notes list -g sa sample1 PS D:\projects\Samples\globaltools> dotnet-notes show -t sample1 this is body
ASP.NET MVC #4
اینها خراب نیستند. روش CodePlex این است که بدون تنظیم Mime type خاصی، یک فایل را به درون مرورگر کاربر flush میکند. به این ترتیب کاربر فکر میکند که با یک سری اطلاعات باینری خراب شده طرف است که اینطور نیست.
روی لینک کلیک راست کنید و گزینه save as رو انتخاب کنید. به این صورت درست دریافت خواهد شد.
اما در یک سیستم فروشگاهی حذف و اضافه شدن کالا در سبد خرید بصورت مکرر انجام میشود و برای اینکه شما چه کاربران مهمان و چه کاربران عضو را مدیریت نموده و بتوانید ترافیک روی بانک اطلاعاتی خود را کاهش دهید میتوانید از Session استفاده نمایید . ( بطور مثال اگر 1000 نفر دریک سایت فروشگاهی که حداقل 100 کالا ارائه شده است را به سبد خرید خود اضافه یا تعداد و ... آنها را ویرایش نمایند در بهترین حال 100000 درخواست به بانک اطلاعاتی ارسال و دریافت خواهد شد)
سلام
زمانی که کاربر یک درخواست از نوع POST را به API ارسال میکنه، نتیجه انجام عملیات در متغیری با نام IsSuccess برگردانده میشه. اگر مقدار این متغیر برابر false باشه یعنی متغیر ErrorList حاوی پیغام است.
سناریو:
- نام Entity در این مثال Product هست که پنج Navigation Property داره که با Entityهای دیگر دارای Relation هستند.
- لایه Application قبل از اینکه در Entity یک ردیف جدید ثبت کنه ابتدا با دستور Any مقدار یکی از Propertyها را بررسی میکنه و اگر وجود نداشت، یک Error در ErrorList اضافه میکنه و نتیجه را بصورت IsSeccess=false بر میگردونه.
- در واقع حالا کاربر مطلع هست که مثلا ProductTypeId اشتباه است و اصلا ProductTypeی با این شناسه وجود نداره.
سوال:
- آیا ضروریه تا به ازای هر کلید خارجی که در Entity تعریف شده بدین صورت اعتبار تمام آنها بررسی و به کلاینت اعلام شود؟
- اگر تعداد کلیدهای خارجی در یک Entity زیاد باشد راه حل چیست؟
- آیا اگر اطلاعات را مستقیما به بانک اطلاعاتی ارسال کنیم تا خود بانک اطلاعاتی صحت وجود این کلیدها را بررسی کند بهتر است یا خیر؟
- اگر برعهده بانک اطلاعاتی بگذاریم چطور باید به کلاینت و به ازای هر کلید خارجی که باعث بروز Exception شده اطلاع رسانی کنیم؟
- در مجموع روش مناسب کدام است؟
تشکر