بهبود model binding در asp.net core
Learn Blazor WebAssembly and Web API on .NET 6 by building a shopping cart application using C#. This course also provides a guide on how to integrate a payment gateway into your Blazor WebAssembly component, so that a user is able to pay for products through your application using a debit or credit card or PayPal account.
⭐️ Course Contents ⭐️
⌨️ (0:00:00) Introduction
⌨️ (0:00:51) Create the Database using EF Core Code First Database Migrations
⌨️ (0:26:05) Retrieve Product Data from Database (Web API component)
⌨️ (0:30:17) Create Classes for Data Transfer Objects (DTOs)
⌨️ (0:36:22) Create ProductRepository Class (Repository Design Pattern)
⌨️ (0:43:05) Create ProductController Class
⌨️ (0:51:08) Create DtoConversion Class (DTO Conversion Extension methods)
⌨️ (0:57:45) Display Product Data to User (Blazor WebAssembly Component)
⌨️ (1:39:59) Display Data for Specific Product to User (Web API and Blazor)
⌨️ (2:06:07) Add Product to Shopping Cart (Web API and Blazor)
⌨️ (2:52:40) Remove Product from Shopping Cart (Web API and Blazor)
⌨️ (3:14:03) Update the Quantity of Products in the Shopping Cart (Web API, Blazor, Blazor JavaScript Interoperability)
⌨️ (3:44:01) Update the Header Menu in Response to a Change to the State of the Shopping Cart (Creating Custom Events in Blazor)
⌨️ (4:04:48) Integration of PayPal Payment Gateway into Blazor Component
⌨️ (4:36:03) Dynamically Populate the Side-Bar Menu (Web API and Blazor)
⌨️ (5:05:44) Optimise Code for Performance (Web API and Blazor)
⌨️ (5:08:26) Use Include Extension Method in LINQ Query (Web API)
⌨️ (5:14:00) User Local Storage Functionality (Blazor)
⌨️ (5:35:42) Outro
If Not a And b Then ... Else ... EndIf
if(!(a) && b) { ... } else { }
معرفی واژهی کلیدی جدید not در C# 9.0
در ابتدا اینترفیس نمونهای را به همراه دو کلاس مشتق شدهی از آن درنظر بگیرید:
public interface ICommand { } public class Command1 : ICommand { } public class Command2 : ICommand { }
ICommand command = new Command1(); if (!(command is Command2)) { }
if (command is not Command2) { }
معرفی واژههای کلیدی جدید and و or در C# 9.0
واژههای کلیدی جدید and و or نیز درک و نوشتن عبارات pattern matching را بسیار ساده میکنند. برای نمونه قطعه کد متداول زیر را درنظر بگیرید:
if ((command is ICommand) && !(command is Command2)) { }
if (command is ICommand and not Command2) { }
و یا حتی در اینجا در صورت نیاز میتوان از واژهی کلیدی جدید or نیز استفاده کرد:
if (command is Command1 or Command2) { }
امکان اعمال واژههای کلیدی جدید and، or و not به سایر نوعها نیز وجود دارند
تا اینجا مثالهایی را که بررسی کردیم، در مورد بررسی نوع اشیاء بود. اما میتوان این واژههای کلیدی جدید در C# 9.0 را به هر نوع ممکنی نیز اعمال کرد. برای نمونه، مثال سادهی زیر را که در مورد بررسی اعداد است، درنظر بگیرید:
var number = new Random().Next(1, 10); if (number > 2 && number < 8) { }
if (number is > 2 and < 8) { }
یک مثال دیگر: متد زیر را در نظربگیرید که با استفاده از && و || متداول #C نوشته شدهاست:
public static bool IsLetterOrSeparator(char c) => (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '.' || c == ',';
public static bool IsLetterOrSeparator(char c) => c is (>= 'a' and <= 'z') or (>= 'A' and <= 'Z') or '.' or ',';
امکان اعمال واژههای کلیدی جدید and، or و not به switchها نیز وجود دارد
برای نمونه قطعه کد if/else دار متداول زیر را درنظر بگیرید که قابلیت تبدیل به یک سوئیچ را نیز دارد:
var number = new Random().Next(1, 10); if (number <= 0) { Console.WriteLine("Less than or equal to 0"); } else if (number > 0 && number <= 10) { Console.WriteLine("More than 0 but less than or equal to 10"); } else { Console.WriteLine("More than 10"); }
// C#9.0 switch (number) { case <= 0: Console.WriteLine("Less than or equal to 0"); break; case > 0 and <= 10: Console.WriteLine("More than 0 but less than or equal to 10"); break; default: Console.WriteLine("More than 10"); break; }
// C#7.0 switch (number) { case int value when value <= 0: Console.WriteLine("Less than or equal to 0"); break; case int value when value > 0 && value <= 10: Console.WriteLine("More than 0 but less than or equal to 10"); break; default: Console.WriteLine("More than 10"); break; }
و یا حتی میتوان سوئیچ C# 9.0 را توسط switch expression بهبود یافتهی C# 8.0 نیز به شکل زیر بازنویسی کرد:
var message = number switch { <= 0 => "Less than or equal to 0", > 0 and <= 10 => "More than 0 but less than or equal to 10", _ => "More than 10" };
انواع pattern matchingهای اضافه شدهی به C# 9.0
در این مطلب سعی شد مفاهیم pattern matching اضافه شدهی به C# 9.0، ذیل عنوان واژههای کلیدی جدید آن بحث شوند؛ اما هر کدام دارای نامهای خاصی هم هستند:
الف) relational patterns: امکان استفادهی از <, >, <= and >= را در الگوها میسر میکنند. مانند نمونههای سوئیچی که نوشته شد.
ب) logical patterns: امکان استفادهی از واژههای کلیدی and، or و not را در الگوها ممکن میکنند.
ج) not pattern: امکان استفادهی از واژهی کلیدی not را در عبارات if میسر میکند.
د) Simple type pattern: در مثالهای زیر، پس از انطباق با یک الگو، کاری با متغیر یا شیء مرتبط نداریم. در نگارشهای قبلی برای صرفنظر کردن از آن، ذکر _ ضروری بود؛ اما در C#9.0 میتوان آنرا نیز ذکر نکرد:
private static int GetDiscount(Product p) => p switch { Food => 0, // Food _ => 0 before C# 9 Book b => 75, // Book b _ => 75 before C# 9 _ => 25 };
.NET Conf: Focus on Windows is a free, one-day livestream event that features speakers from the community and Microsoft teams working on Windows desktop apps and making them fantastic on the latest .NET 5. Learn why and how to upgrade WPF and Windows Forms apps to .NET 5, see Visual Studio tooling improvements, learn how to leverage cloud services from your client apps, and a whole lot more. You'll also see what the future of native device development with .NET will look like in .NET 6.
<style> div.container :first-child { color: red; } </style> <div class="container"> <h1>Text 1</h1> <span>Text 2</span> <p>Text 3</p> <div>Text 4</div> <div>Text 5</div> <div> <h1>Text 6</h1> <span>Text 7</span> <p>Text 8</p> <p> <span>Text 9</span> </p> <div>Text 10</div> <p>Text 11</p> </div> <h1>Text 12</h1> <div>Text 13</div> <span>Text 14</span> <div>Text 15</div> </div>
|
|
|
|
| Selector | نسخه CSS |
3.1 | 9.6 | 7.0 | 3.0 | 4.0 | :first-child | 2 |
52- :last-child
<style> div.container :last-child { color: red; } </style> <div class="container"> <h1>Text 1</h1> <span>Text 2</span> <p>Text 3</p> <div>Text 4</div> <div>Text 5</div> <div> <h1>Text 6</h1> <span>Text 7</span> <p>Text 8</p> <p> <span>Text 9</span> </p> <div>Text 10</div> <p>Text 11</p> </div> <h1>Text 12</h1> <div>Text 13</div> <span>Text 14</span> <div>Text 15</div> </div>
|
|
|
|
| Selector | نسخه CSS |
3.2 | 9.6 | 9.0 | 3.5 | 4.0 | :last-child | 3 |
53- :only-child
<style> div.container :only-child { color: red; } </style> <div class="container"> <h1>Text 1</h1> <span>Text 2</span> <p>Text 3</p> <div>Text 4</div> <div>Text 5</div> <div> <h1>Text 6</h1> <span>Text 7</span> <p>Text 8</p> <p> <span>Text 9</span> </p> <div>Text 10</div> <p>Text 11</p> </div> <h1>Text 12</h1> <div>Text 13</div> <span>Text 14</span> <div>Text 15</div> </div>
|
|
|
|
| Selector | نسخه CSS |
3.2 | 9.6 | 9.0 | 3.5 | 4.0 | :only-child | 3 |
54- :nth-child(n)
<style> div.container :nth-child(2) { color: red; } </style> <div class="container"> <h1>Text 1</h1> <span>Text 2</span> <p>Text 3</p> <div>Text 4</div> <div>Text 5</div> <div> <h1>Text 6</h1> <span>Text 7</span> <p>Text 8</p> <p> <span>Text 9</span> </p> <div>Text 10</div> <p>Text 11</p> </div> <h1>Text 12</h1> <div>Text 13</div> <span>Text 14</span> <div>Text 15</div> </div>
|
|
|
|
| Selector | نسخه CSS |
3.2 | 9.6 | 9.0 | 3.5 | 4.0 | :nth-child(n) | 3 |
55- :nth-last-child(n)
<style> div.container :nth-last-child(2) { color: red; } </style> <div class="container"> <h1>Text 1</h1> <span>Text 2</span> <p>Text 3</p> <div>Text 4</div> <div>Text 5</div> <div> <h1>Text 6</h1> <span>Text 7</span> <p>Text 8</p> <p> <span>Text 9</span> </p> <div>Text 10</div> <p>Text 11</p> </div> <h1>Text 12</h1> <div>Text 13</div> <span>Text 14</span> <div>Text 15</div> </div>
|
|
|
|
| Selector | نسخه CSS |
3.2 | 9.6 | 9.0 | 3.5 | 4.0 | :nth-last-child(n) | 3 |
56- :first-of-type
<style> div.container :first-of-type { color: red; } </style> <div class="container"> <h1>Text 1</h1> <span>Text 2</span> <p>Text 3</p> <div>Text 4</div> <div>Text 5</div> <div> <h1>Text 6</h1> <span>Text 7</span> <p>Text 8</p> <p> <span>Text 9</span> </p> <div>Text 10</div> <p>Text 11</p> </div> <h1>Text 12</h1> <div>Text 13</div> <span>Text 14</span> <div>Text 15</div> </div>
|
|
|
|
| Selector | نسخه CSS |
3.2 | 9.6 | 9.0 | 3.5 | 4.0 | :first-of-type | 3 |
57- :last-of-type
<style> div.container :last-of-type { color: red; } </style> <div class="container"> <h1>Text 1</h1> <span>Text 2</span> <p>Text 3</p> <div>Text 4</div> <div>Text 5</div> <div> <h1>Text 6</h1> <span>Text 7</span> <p>Text 8</p> <p> <span>Text 9</span> </p> <div>Text 10</div> <p>Text 11</p> </div> <h1>Text 12</h1> <div>Text 13</div> <span>Text 14</span> <div>Text 15</div> </div>
|
|
|
|
| Selector | نسخه CSS |
3.2 | 9.6 | 9.0 | 3.5 | 4.0 | :last-of-type | 3 |
58- :only-of-type
<style> div.container :only-of-type { color: red; } </style> <div class="container"> <h1>Text 1</h1> <span>Text 2</span> <p>Text 3</p> <div>Text 4</div> <div>Text 5</div> <div> <h1>Text 6</h1> <span>Text 7</span> <p>Text 8</p> <p> <span>Text 9</span> </p> <div>Text 10</div> <p>Text 11</p> </div> <h1>Text 12</h1> <div>Text 13</div> <span>Text 14</span> <div>Text 15</div> </div>
|
|
|
|
| Selector | نسخه CSS |
3.2 | 9.6 | 9.0 | 3.5 | 4.0 | :only-of-type | 3 |
59- :nth-of-type(n)
<style> div.container :nth-of-type(2) { color: red; } </style> <div class="container"> <h1>Text 1</h1> <span>Text 2</span> <p>Text 3</p> <div>Text 4</div> <div>Text 5</div> <div> <h1>Text 6</h1> <span>Text 7</span> <p>Text 8</p> <p> <span>Text 9</span> </p> <div>Text 10</div> <p>Text 11</p> </div> <h1>Text 12</h1> <div>Text 13</div> <span>Text 14</span> <div>Text 15</div> </div>
|
|
|
|
| Selector | نسخه CSS |
3.2 | 9.6 | 9.0 | 3.5 | 4.0 | :nth-of-type(n) | 3 |
60- nth-last-of-type(n)
<style> div.container :nth-last-of-type(2) { color: red; } </style> <div class="container"> <h1>Text 1</h1> <span>Text 2</span> <p>Text 3</p> <div>Text 4</div> <div>Text 5</div> <div> <h1>Text 6</h1> <span>Text 7</span> <p>Text 8</p> <p> <span>Text 9</span> </p> <div>Text 10</div> <p>Text 11</p> </div> <h1>Text 12</h1> <div>Text 13</div> <span>Text 14</span> <div>Text 15</div> </div>
|
|
|
|
| Selector | نسخه CSS |
3.2 | 9.6 | 9.0 | 3.5 | 4.0 | :nth-last-of-type(n) | 3 |
Try .NET is an interactive documentation generator for .NET Core.
Use Try .NET to create executable C# snippets for your websites or, interactive markdown files that users can run on their machine.
Try .NET execute C# code in client side using Blazor and Web Assembly.
Tuple در دات نت 4
نوع جدیدی در دات نت 4 به نام Tuple اضافه شده است که در این مطلب به بررسی آن خواهیم پرداخت.
در ریاضیات، Tuple به معنای لیست مرتبی از اعضاء با تعداد مشخص است. Tuple در زبانهای برنامه نویسی Dynamic مانند اف شارپ، Perl ، LISP و بسیاری موارد دیگر مطلب جدیدی نیست. در زبانهای dynamic برنامه نویسها میتوانند متغیرها را بدون معرفی نوع آنها تعریف کنند. اما در زبانهای Static مانند سی شارپ، برنامه نویسها موظفند نوع متغیرها را پیش از کامپایل آنها معرفی کنند که هر چند کار کد نویسی را اندکی بیشتر میکند اما به این صورت شاهد خطاهای کمتری نیز خواهیم بود (البته سی شارپ 4 این مورد را با معرفی واژهی کلیدی dynamic تغییر داده است).
برای مثال در اف شارپ داریم:
let data = (“John Doe”, 42)
که سبب ایجاد یک tuple که المان اول آن یک رشته و المان دوم آن یک عدد صحیح است میشود. اگر data را بخواهیم نمایش دهیم خروجی آن به صورت زیر خواهد بود:
printf “%A” data
// Output: (“John Doe”,42)
در دات نت 4 فضای نام جدیدی به نام System.Tuple معرفی شده است که در حقیقت ارائه دهندهی نوعی جنریک میباشد که توانایی در برگیری انواع مختلفی را دارا است :
public class Tuple<T1>
up to:
public class Tuple<T1, T2, T3, T4, T5, T6, T7, TRest>
همانند آرایهها، اندازهی Tuples نیز پس از تعریف قابل تغییر نیستند (immutable). اما تفاوت مهم آن با یک آرایه در این است که اعضای آن میتوانند نوعهای کاملا متفاوتی داشته باشند. همچنین تفاوت مهم آن با یک ArrayList یا آرایهای از نوع Object، مشخص بودن نوع هر یک از اعضاء آن است که type safety بیشتری را به همراه خواهد داشت و کامپایلر میتواند در حین کامپایل دقیقا مشخص نماید که اطلاعات دریافتی از نوع صحیحی هستند یا خیر.
یک مثال کامل از Tuples را در کلاس زیر ملاحظه خواهید نمود:
using System;
using System.Linq;
using System.Collections.Generic;
namespace TupleTest
{
class TupleCS4
{
#region Methods (4)
// Public Methods (4)
public static Tuple<string, string> GetFNameLName(string name)
{
if (string.IsNullOrWhiteSpace(name))
throw new NullReferenceException("name is empty.");
var nameParts = name.Split(',');
if (nameParts.Length != 2)
throw new FormatException("name must contain ','");
return Tuple.Create(nameParts[0], nameParts[1]);
}
public static void PrintSelectedTuple()
{
var list = new List<Tuple<string, int>>
{
new Tuple<string, int>("A", 1),
new Tuple<string, int>("B", 2),
new Tuple<string, int>("C", 3)
};
var item = list.Where(x => x.Item2 == 2).SingleOrDefault();
if (item != null)
Console.WriteLine("Selected Item1: {0}, Item2: {1}",
item.Item1, item.Item2);
}
public static void PrintTuples()
{
var tuple1 = new Tuple<int>(12);
Console.WriteLine("tuple1 contains: item1:{0}", tuple1.Item1);
var tuple2 = Tuple.Create("Item1", 12);
Console.WriteLine("tuple2 contains: item1:{0}, item2:{1}",
tuple2.Item1, tuple2.Item2);
var tuple3 = Tuple.Create(new DateTime(2010, 5, 6), "Item2", 20);
Console.WriteLine("tuple3 contains: item1:{0}, item2:{1}, item3:{2}",
tuple3.Item1, tuple3.Item2, tuple3.Item3);
}
public static void Tuple8()
{
var tup =
new Tuple<int, int, int, int, int, int, int, Tuple<int, int>>
(1, 2, 3, 4, 5, 6, 7, new Tuple<int, int>(8, 9));
Console.WriteLine("tup.Rest Item1: {0}, Item2: {1}",
tup.Rest.Item1,tup.Rest.Item2);
}
#endregion Methods
}
}
using System;
namespace TupleTest
{
class Program
{
static void Main()
{
var data = TupleCS4.GetFNameLName("Vahid, Nasiri");
Console.WriteLine("Data Item1:{0} & Item2:{1}",
data.Item1, data.Item2);
TupleCS4.PrintTuples();
TupleCS4.PrintSelectedTuple();
TupleCS4.Tuple8();
Console.WriteLine("Press a key...");
Console.ReadKey();
}
}
}
توضیحات :
- روشهای متفاوت ایجاد Tuples را در متد PrintTuples میتوانید ملاحظه نمائید. همچنین نحوهی دسترسی به مقادیر هر کدام از اعضاء نیز مشخص شده است.
- کاربرد مهم Tuples در متد GetFNameLName نمایش داده شده است؛ زمانیکه نیاز است تا چندین خروجی از یک تابع داشته باشیم. به این صورت دیگر نیازی به تعریف آرگومانهایی به همراه واژه کلیدی out نخواهد بود یا دیگر نیازی نیست تا یک شیء جدید را ایجاد کرده و خروجی را به آن نسبت دهیم. به همان سادگی زبانهای dynamic در اینجا نیز میتوان یک tuple را ایجاد و استفاده کرد.
- بدیهی است از Tuples در یک لیست جنریک و یا حالات دیگر نیز میتوان استفاده کرد. مثالی از این دست را در متد PrintSelectedTuple ملاحظه خواهید نمود. ابتدا یک لیست جنریک از Tuple ایی با دو عضو تشکیل شده است. سپس با استفاده از امکانات LINQ ، عضوی که آیتم دوم آن مساوی 2 است یافت شده و سپس المانهای آن نمایش داده میشود.
- نکتهی دیگری را که حین کار با Tuples میتوان در نظر داشت این است که اعضای آن حداکثر شامل 8 عضو میتوانند باشند که عضو آخر باید یک Tuple تعریف گردد و بدیهی است این Tuple نیز میتواند شامل 8 عضو دیگر باشد و الی آخر که نمونهای از آن را در متد Tuple8 میتوان مشاهده کرد.