The Intersection of Microservices, Domain-Driven Design and Entity Framework Core
Domain-Driven Design (DDD) provides much of the strategic design guidance that we can use to determine the boundaries around and interactions between Microservices in our solutions. DDD also follows up with tactical design patterns for your business logic. In this session we'll take a look at some of these patterns and how EF Core naturally, or with some additional configuration, persists the data that your microservices depend on.
مقاله درباره ViewModel
Use ViewModels to manage data & organize code in ASP.NET MVC applications
The concept of the ViewModel isn't just for ASP.NET MVC, as you'll see references to ViewModels throughout the web in articles and blog posts about the MVC, MVP, and MVVM patterns. Those posts and articles can center around any number of technologies such as ASP.NET, Silverlight, WPF, or MVC... This post will investigate ViewModels as they apply to the world of ASP.NET MVC.
Telerik UI برای UWP سورس باز شد
Third Party Site Cookies
In August 2020, Google announced their 'Privacy Sandbox' initiative, which aims to preserve and protect user's privacy. The cookie processing change is part of this initiative. An official blog post sheds some light on it.
Google will drop support for third-party cookies in the Chrome browser in two years. Also, the company will start limiting cross-site tracking by enforcing its new SameSite rules . This has already happened in Chrome 80.
The SameSite-by-default and SameSite=None-requires-Secure behaviors will begin rolling out to Chrome 80 Stable for an initial limited population starting the week of February 17, 2020.
This article dives into the mock questions I would ask, along with responses that are my personal best guess to the answers. Could my answers not reflect actual opinions shared by the team at Microsoft? Sure, but I'm hoping folks from the .NET team can jump in to correct me if I am way off base.
This is a rather interesting time for .NET – what's being done shapes the future of .NET for the next decade. Let's ask the honest questions and hopefully all of us will understand the new .NET ecosystem a little better.
1.Visual Studio 2017 15.7 منتشر شد
These are the customer-reported issues addressed in 15.7.1:
- This release includes a fix that reduces memory usage and GC pressure during solution load.
Microsoft Security Advisory for .NET Core Denial Of Service Vulnerability
CVE-2018-0765
Microsoft is releasing this security advisory to provide information about a vulnerability in .NET Core and .NET native version 2.0. This advisory also provides guidance on what developers can do to update their applications to remove this vulnerability.
Microsoft is aware of a denial of service vulnerability that exists when .NET Framework and .NET Core improperly process XML documents. An attacker who successfully exploited this vulnerability could cause a denial of service against a .NET Framework, .NET Core, or .NET native application.
The update addresses the vulnerability by correcting how .NET Framework, .NET Core, and .NET native applications handle XML document processing.
If your application is an ASP.NET Core application, developers are also advised to update to ASP.NET Core 2.0.8.
private Document oDoc; public void createdoc1() { var realpath="~/template"; var filePath = Path.Combine(HttpContext.Current.Server.MapPath("~/template"), Lcourseid.Text + ".doc"); var oWordApplication = new Application(); DirectoryInfo dir = new DirectoryInfo(Server.MapPath(realpath)); foreach (FileInfo files in dir.GetFiles()) { files.Delete(); } // To invoke MyMethod with the default argument value, pass // Missing.Value for the optional parameter. object missing = System.Reflection.Missing.Value; //object fileName = ConfigurationManager.AppSettings["DocxPath"];@"C:\DocXExample.docx"; string fileName = @"D:\template1.dot"; //string fileName1 = @"D:\sss.doc"; object newTemplate = false; object docType = 0; object isVisible = true; //System.Reflection.Missing.Value is used here for telling that method to use default parameter values when method execution oDoc = oWordApplication.Documents.Open(fileName, newTemplate, docType, isVisible, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing); // usable in earlier versions of Microsoft Word v2003 v11 // if(Convert.ToInt16(oWordApplication.Version) >=11) { //Sets or returns a Boolean that represents whether a document is being viewed in reading layout view. oDoc.ActiveWindow.View.ReadingLayout = false; } //The active window is the window that currently has focus.If there are no windows open, an exception is thrown. //microsoft.office.tools.word. oDoc.Activate(); if (oDoc.Bookmarks.Exists("Title")) { oDoc.Bookmarks["Title"].Range.Text = "Test Field Entry from webform"; oDoc.Bookmarks["Address"].Range.Text = "Address Field Entry from webform"; } oDoc.SaveAs(filePath, ref missing); oWordApplication.Documents.Close(ref missing, ref missing, ref missing); //oWordApplication.Quit(ref SaveChanges, ref missing, ref missing, ref missing); ProcessRequest(filePath, Lcourseid.Text);
اکنون در ادامه قصد داریم این موارد را تبدیل به چندین درخواست به هم مرتبط postman کرده و در نهایت آنها را به صورت یک collection قابل آزمایش مجدد، ذخیره کنیم.
مرحله 1: خاموش کردن بررسی مجوز SSL برنامه
چون مجوز SSL برنامههای ASP.NET Core که در حالت local اجرا میشوند از نوع self-signed certificate است، توسط postman پردازش نخواهند شد. به همین جهت نیاز است به منوی File -> Settings آن مراجعه کرده و این بررسی را خاموش کنیم:
مرحله 2: ایجاد درخواست login و دریافت توکنها
در اینجا این مراحل طی شدهاند:
- ابتدا آدرس درخواست به https://localhost:5001/api/account/login تنظیم شدهاست.
- سپس نوع درخواست نیز به Post تغییر کردهاست.
- چون اکنون نوع درخواست، Post است، میتوان بدنهی آنرا مقدار دهی کرد و چون نوع آن JSON است، گزینهی raw و سپس contentType صحیح انتخاب شدهاند. در ادامه مقدار زیر تنظیم شدهاست:
{ "username": "Vahid", "password": "12345" }
- پس از این تنظیمات اگر بر روی دکمهی send کلیک کنیم، توکنهای دریافتی را در قسمت response میتوان مشاهده کرد.
مرحلهی 3: ذخیره سازی توکنهای دریافتی در متغیرهای سراسری
برای دسترسی به منابع محافظت شدهی سمت سرور، نیاز است access_token را به همراه هر درخواست، به سمت سرور ارسال کرد. بنابراین نیاز است در همینجا این دو توکن را در متغیرهایی برای دسترسی بعدی، ذخیره کنیم:
var jsonData = pm.response.json(); pm.globals.set("access_token", jsonData.access_token); pm.globals.set("refresh_token", jsonData.refresh_token);
مرحلهی 3: ذخیره سازی مراحل انجام شده
برای این منظور، بر روی دکمهی Save کنار Send کلیک کرده، نام Login را وارد و سپس یک Collection جدید را با نام دلخواه JWT Sample ایجاد میکنیم:
مرحلهی 4: دسترسی به منابع محافظت شدهی سمت سرور
برای این منظور بر روی دکمهی + موجود در کنار اولین برگهای که مشغول به تکمیل آن هستیم، کلیک میکنیم تا یک برگهی جدید ایجاد شود. سپس مشخصات آن را به صورت زیر تکمیل خواهیم کرد:
ابتدا آدرس درخواست از نوع Get را به https://localhost:5001/api/MyProtectedApi تنظیم خواهیم کرد.
سپس گزینهی هدرهای این درخواست را انتخاب کرده و key/value جدیدی با مقادیر Authorization و Bearer {{access_token}} ایجاد میکنیم. در اینجا {{access_token}} همان متغیر سراسری است که پس از لاگین، تنظیم میشود. اکنون از این متغیر جهت تنظیم هدر Authorization استفاده کردهایم.
در آخر اگر بر روی دکمهی Send این درخواست کلیک کنیم، response فوق را میتوان مشاهده کرد.
فراخوانی مسیر api/MyProtectedAdminApi نیز دقیقا به همین نحو است.
یک نکته: روش دومی نیز برای تنظیم هدر Authorization در postman وجود دارد. برای این منظور، گزینهی Authorization یک درخواست را انتخاب کنید (تصویر زیر). سپس نوع آنرا به Bearer token تغییر دهید و مقدار آنرا به همان متغیر سراسری {{access_token}} تنظیم کنید. به این صورت هدر مخصوص JWT را به صورت خودکار ایجاد و ارسال میکند و در این حالت دیگر نیازی به تنظیم دستی برگهی هدرها نیست.
مرحلهی 5: ارسال Refresh token و دریافت یک سری توکن جدید
این مرحله، نیاز به ارسال anti-forgery token را هم دارد و گرنه از طرف سرور و برنامه، برگشت خواهد خورد. اگر به کوکیهای تنظیم شدهی توسط برگهی لاگین دقت کنیم:
کوکی با نام XSRF-TOKEN نیز تنظیم شدهاست. بنابراین آنرا توسط متد pm.cookies.get، در قسمت Tests برگهی لاگین خوانده و در یک متغیر سراسری تنظیم میکنیم:
var jsonData = pm.response.json(); pm.globals.set("access_token", jsonData.access_token); pm.globals.set("refresh_token", jsonData.refresh_token); pm.globals.set('XSRF-TOKEN', pm.cookies.get('XSRF-TOKEN'));
ابتدا در قسمت بدنهی درخواست از نوع post به آدرس https://localhost:5001/api/account/RefreshToken، در قسمت raw آن، با انتخاب نوع json، این refresh token را که در قسمت لاگین خوانده و ذخیره کرده بودیم، به سمت سرور ارسال خواهیم کرد:
همچنین دو هدر زیر را نیز باید ارسال کنیم:
یکی هدر مخصوص Authorization است که در مورد آن بحث شد و دیگر هدر X-XSRF-TOKEN که در سمت سرور بجای anti-forgery token پردازش میشود. مقدار آنرا نیز در برگهی login با خواندن کوکی مرتبطی، پیشتر تنظیم کردهایم که در اینجا از متغیر سراسری آن استفاده شدهاست.
اکنون اگر بر روی دکمهی send این برگه کلیک کنید، دو توکن جدید را دریافت خواهیم کرد:
که نیاز است مجددا در برگهی Tests آن، متغیرهای سراسری پیشین را بازنویسی کنند. به همین جهت دقیقا همان 4 سطری که اکنون در برگهی Tests درخواست لاگین وجود دارند، باید در اینجا نیز تکرار شوند تا عملیات refresh token واقعا به تمام برگههای موجود، اعمال شود.
مرحلهی آخر: پیاده سازی logout
در اینجا نیاز است refreshToken را به صورت یک کوئری استرینگ به سمت سرور ارسال کرد که به کمک متغیر {{refresh_token}}، در برگهی params تعریف میشود:
همچنین هدر Authorization را نیز باید درج کرد:
پس از آن اگر درخواست را رسال کنیم، یک true را باید بتوان در response مشاهده کرد:
ذخیره سازی مجموعهی جاری به صورت یک فایل JSON
برای گرفتن خروجی از این مجموعه و به اشتراک گذاشتن آن، اگر اشارهگر ماوس را بر روی نام یک مجموعه حرکت دهیم، یک دکمهی جدید با برچسب ... ظاهر میشود. با کلیک بر روی آن، یکی از گزینههای آن، export نام دارد که جزئیات تمام درخواستهای یک مجموعه را به صورت یک فایل JSON ذخیره میکند. برای نمونه فایل JSON خروجی این قسمت را میتوانید از اینجا دریافت کنید: JWT-Sample.postman_collection.json
var collection = ['a', 1, /3/, {}];
collection[0];
collection.length
var numbers = [1, 2, 3]; _.each(numbers, function (num) { write(num); });
var ary = [1, 5, 10]; var match = ary.find(item => item > 8);
var match = ary.findIndex(item => item > 8);
ary.find('a'); // خروجی ["a", "a", "a"]
var ary = [1, 5, 10, 5, 6]; ary.fill('a', 2, 3)
// خروجی [ 1, 5, "a", 5, 6 ]
[1, 2, 3, 4, 5].copyWithin(0, 3);
// [4, 5, 3, 4, 5]
[1, 2, 3, 4, 5].copyWithin(0, 3, 4); // خروجی // [4, 2, 3, 4, 5]
var ary = new Array(1, 2);
var ary = new Array(1, 2, 3);
var ary = new Array(3);
var Ofary = Array.of(3);
var set = new Set(); set.add(1); set.add(2); set.add(3); console.log(set.size); // logs 3
var set = new Set([1, 2, 3]); console.log(set.size); // logs 3
var set = new Set(); set.has(1); // false set.add(1); set.has(1); // true set.clear(); set.has(1); // false set.add(1); set.add(2); set.size; // 2 set.delete(2); set.size; // 1
var set = new Set(); set.add('Vahid'); set.add('Sirwan'); var i = 0; set.forEach(item => i++); console.log(i);
var set = new Set(); set.add('Vahid'); set.add('Sirwan'); var i = 0; for(let item of set) { i++; } console.log(i);
var set = new Set(); set.add("Sirwan"); set.add(1); set.add("Afifi"); var setIter = set.entries(); console.log(setIter.next().value); // ["Sirwan", "Sirwan"] console.log(setIter.next().value); // [1, 1] console.log(setIter.next().value); // ["Afifi", "Afifi"]
var map = new Map(); map.set('name', 'Sirwan'); map.get('name'); // Sirwan
var map = new Map([['name', 'Sirwan'], ['age', 27]]); map.has('age'); // true map.get('age'); // 27 map.get('name'); // Sirwan
var map = new Map(); map.set(1, true); map.has("1"); // false map.set("1", true); map.has("1"); // true
var map = new Map([['name', 'Sirwan'], ['age', 27]]); var i = 0; map.forEach(function (value, key) { i++; }); console.log(i); // log 2
for (var [key, value] of map) { i++; }
var newArray = new Array(); newArray["name"] = "Sirwan"; newArray["lastName"] = "Afifi";
let user1 = { name: "Vahid" }; let user2 = { name: "Sirwan" }; let result = {}; result[user1] = 10; result[user2] = 20; console.log(result[user1]); // logs 20 console.log(result[user2]); // logs 20
result["[object object]"] = 10; result["[object object]"] = 20; console.log(result["[object object]"]); // logs 20 console.log(result["[object object]"]); // logs 20
- WeakMap و WeakSet فاقد پراپرتیهای size, entries, values و متد foreach هستند.
- WeakMap همچنین فاقد keys است.