المشاركات

عرض المشاركات من مايو, 2025

Blazor - إنشاء نموذج ديناميكي باستخدام Loop و Binding

🔹 Blazor - إنشاء نموذج ديناميكي باستخدام Loop و Binding في بعض الأحيان تحتاج إلى إنشاء نموذج يحتوي على عناصر متعددة يتم توليدها ديناميكيًا مثل قائمة مهام أو عناصر جدول يمكن تعديلها. Blazor يسمح لك بتنفيذ ذلك بسهولة باستخدام حلقات @foreach مع EditForm وربط البيانات باستخدام @bind-Value . 🧪 مثال عملي: نموذج لإدخال عناصر متعددة public class TaskItem { public string? Description { get; set; } public bool IsDone { get; set; } } @using System.ComponentModel.DataAnnotations <EditForm Model="@this" OnValidSubmit="Save"> <DataAnnotationsValidator /> @foreach (var task in Tasks) { <div class="mb-2"> <InputText class="form-control d-inline-block w-75" @bind-Value="task.Description" /> <InputCheckbox class="form-check-input ms-2" @bind-Value="task.IsDone" /> </div> } <button class="btn btn-success...

Blazor - التعامل مع InputText و InputSelect و InputDate

🔹 Blazor - التعامل مع InputText و InputSelect و InputDate توفر Blazor مكونات إدخال مدمجة متوافقة مع <EditForm> ، مثل: <InputText> و <InputSelect> و <InputDate> . هذه المكونات تدعم ربط البيانات (Binding)، والتحقق من الصحة (Validation) تلقائيًا. --- 🧪 1. InputText - حقل نصي <InputText @bind-Value="model.Name" class="form-control" /> يُستخدم لإدخال نص مثل الاسم أو البريد الإلكتروني. ويُفضَّل على <input type="text"> لأنه يدعم التحقق من الصحة تلقائيًا. --- 🔢 2. InputNumber - حقل رقمي <InputNumber @bind-Value="model.Age" class="form-control" /> يُستخدم للأرقام الصحيحة أو العشرية. يمكن ربطه بـ int أو decimal أو double . --- 📅 3. InputDate - حقل تاريخ <InputDate @bind-Value="model.BirthDate" class="form-control" /> يُستخدم لاختيار التاريخ من تقويم، ويجب أن تكون الخاصية المرتبطة من نوع DateTime . --- 🔽 4. InputSelect - قائمة منس...

Blazor - التحقق من صحة الحقول وعرض الرسائل

🔹 Blazor - التحقق من صحة الحقول وعرض الرسائل Blazor يوفّر نظام تحقق من صحة (Validation) مدمج، يعتمد على Data Annotations . في هذا الدرس سنتعلم كيفية التحقق من صحة الحقول داخل النموذج، وطريقة عرض رسائل الخطأ بجانب كل حقل بشكل واضح وجذاب. --- ✅ التحقق باستخدام DataAnnotations Blazor يعتمد على السمات (Attributes) داخل الكلاس للتحقق، مثل: public class LoginModel { [Required(ErrorMessage = "اسم المستخدم مطلوب")] public string? Username { get; set; } [Required(ErrorMessage = "كلمة المرور مطلوبة")] [StringLength(20, MinimumLength = 6, ErrorMessage = "يجب أن تكون كلمة المرور بين 6 و 20 حرفًا")] public string? Password { get; set; } } --- 🧪 عرض رسائل الخطأ بجانب الحقول يمكن استخدام <ValidationMessage For=... /> أسفل كل حقل لعرض رسالة الخطأ الخاصة به. <EditForm Model="@loginModel" OnValidSubmit="SubmitForm"> <DataAnnotationsValidator /> <div class="mb-3">...

Blazor - استخدام Forms و EditForm للتعامل مع المدخلات

🔹 Blazor - استخدام Forms و EditForm للتعامل مع المدخلات في Blazor، يمكن التعامل مع النماذج (Forms) بطريقة مرنة وقوية باستخدام المكون <EditForm> . يسمح هذا المكون بربط نموذج ببيانات، وإجراء التحقق من الصحة، وتنفيذ دوال عند الإرسال. --- 🧱 ما هو EditForm؟ هو مكون Blazor يُستخدم لإنشاء نموذج مرتبط بكائن بيانات (Model)، ويوفر التحقق من الصحة (Validation) بشكل تلقائي بناءً على الخصائص المعنونة بـ [DataAnnotations] . --- 🛠️ مثال عملي بسيط على EditForm ✅ 1. إنشاء الكلاس المرتبط بالنموذج: public class ContactFormModel { [Required(ErrorMessage = "الاسم مطلوب")] public string? Name { get; set; } [Required(ErrorMessage = "البريد الإلكتروني مطلوب")] [EmailAddress(ErrorMessage = "صيغة البريد غير صحيحة")] public string? Email { get; set; } } ✅ 2. استخدام EditForm في الصفحة: @using System.ComponentModel.DataAnnotations <EditForm Model="@formModel" OnValidSubmit="HandleSubmit"> <Data...

Blazor - التعامل مع أخطاء التنفيذ (Runtime Errors)

🔹 Blazor - التعامل مع أخطاء التنفيذ (Runtime Errors) في التطبيقات الواقعية، من الطبيعي أن تحدث أخطاء أثناء التشغيل (مثل NullReference أو مشكلة في API). في هذا الدرس سنتعلم كيفية رصد هذه الأخطاء، التعامل معها بشكل سليم، و عرض رسائل مخصصة للمستخدم دون انهيار الصفحة. --- 🧠 ما هو Runtime Error؟ Runtime Errors هي الأخطاء التي تحدث أثناء تشغيل التطبيق وليس أثناء ترجمته (Build). مثل: محاولة الوصول إلى خاصية كائن غير مهيأ، فشل الاتصال بالخادم، أو تقسيم على صفر. --- 🛠️ 1. استخدام try-catch داخل المكون أفضل أسلوب للتعامل مع الأخطاء البسيطة مباشرة داخل الدوال هو استخدام try-catch: <button class="btn btn-danger" @onclick="LoadData">تحميل البيانات</button> @if (!string.IsNullOrEmpty(ErrorMessage)) { <div class="alert alert-danger mt-2">⚠️ @ErrorMessage</div> } @code { private string? ErrorMessage; async Task LoadData() { try { // كود قد يسبب خطأ var result =...

Blazor - إنشاء صفحة خطأ 404 مخصصة

🔹 Blazor - إنشاء صفحة خطأ 404 مخصصة عندما يزور المستخدم رابطًا غير موجود في تطبيق Blazor، يتم عرض رسالة خطأ افتراضية غير جذابة. في هذا الدرس سنتعلم كيف ننشئ صفحة خطأ 404 مخصصة وجذابة، لتعزيز تجربة المستخدم. --- 🧱 أين تُعرض صفحات NotFound؟ التحكم في عرض صفحات 404 يتم من خلال مكون <Router> الموجود في ملف App.razor . بداخله يوجد بلوك <NotFound> وهو المكان الذي يتم فيه عرض محتوى الصفحة عند عدم تطابق أي Route. --- 🛠️ خطوات إنشاء صفحة خطأ 404 مخصصة ✅ 1. تحرير App.razor <Found Context="routeData"> <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" /> </Found> <NotFound> <LayoutView Layout="@typeof(MainLayout)"> <Error404 /> </LayoutView> </NotFound> ✅ 2. إنشاء مكون Error404.razor <div class="text-center mt-5"> <h1 class="display-1 text-danger">404</h...

Blazor - استخدام Layout داخل Layout آخر (Nested Layouts)

🔹 Blazor - استخدام Layout داخل Layout آخر (Nested Layouts) في Blazor يمكنك استخدام أكثر من Layout متداخل، حيث يعتمد أحد الـ Layouts على آخر أكبر منه. هذا مفيد عندما تريد تقسيم الهيكل إلى أجزاء: مثل Layout عام يحتوي على Layout فرعي للأقسام الإدارية أو أجزاء الموقع. --- 🧠 ما هو Nested Layout؟ هو عندما يقوم Layout فرعي باستخدام Layout رئيسي. يعني: بدل ما تكون الصفحة فقط هي من تُستخدم داخل Layout، يمكن أن يكون Layout نفسه داخل Layout آخر! --- 🛠️ خطوات إنشاء Layout داخل Layout ✅ 1. أنشئ Layout عام (خارجي): <div class="p-4 border"> <h2>🌐 إطار خارجي (OuterLayout)</h2> @Body </div> ✅ 2. أنشئ Layout فرعي (داخلي) يستخدم الخارجي: @layout OuterLayout <div class="p-3 bg-light"> <h4>📁 إطار داخلي (InnerLayout)</h4> @Body </div> ✅ 3. صفحة تستخدم الـ InnerLayout فقط: @page "/nested-layout" @layout InnerLayout <p>✅ هذه الصفحة داخل Layout داخلي، والذي بدوره داخل L...

Blazor - تخصيص Layout لأجزاء مختلفة من التطبيق

🔹 Blazor - تخصيص Layout لأجزاء مختلفة من التطبيق أحيانًا نحتاج أكثر من Layout في نفس تطبيق Blazor: واحد للزوار، وآخر للإدارة، وربما ثالث للهواتف المحمولة. في هذا الدرس، ستتعلم كيف تنشئ أكثر من Layout وتربط كل واحد بصفحات مختلفة حسب الحاجة. --- 🎯 متى نستخدم أكثر من Layout؟ صفحات الإدارة تختلف عن صفحات المستخدم العادي. تريد صفحات بدون قائمة جانبية. تحتاج Layout خاص لطباعة أو شاشة تسجيل الدخول. --- 🛠️ خطوات إنشاء أكثر من Layout ✅ 1. أنشئ Layout رئيسي: <div class="p-4"> <h2>🌐 الواجهة العامة</h2> @Body </div> ✅ 2. أنشئ Layout إداري: <div class="admin-container"> <nav class="bg-dark text-white p-2">⚙️ لوحة التحكم</nav> <section class="p-4"> @Body </section> </div> --- 📥 استخدام Layout مخصص في صفحة معينة في أعلى الصفحة، استخدم توجيه @layout لتحديد Layout: @page "/admin-dashboard" @layout AdminLayout ...

Blazor - إنشاء Layout عام للتطبيق

🔹 Blazor - إنشاء Layout عام للتطبيق الـ Layout في Blazor يُستخدم لتعريف الهيكل العام لصفحات التطبيق، مثل: الهيدر، القائمة الجانبية، والفوتر. وبدلًا من تكرار نفس العناصر في كل صفحة، نقوم بتعريفها مرة واحدة داخل Layout واستخدامه في باقي الصفحات. --- 🧱 ما هو Layout في Blazor؟ Layout يشبه الـ _Layout.cshtml في ASP.NET MVC وRazor Pages. يُستخدم لتغليف الصفحات بعناصر تصميم ثابتة. --- 🛠️ خطوات إنشاء Layout مخصص ✅ 1. إنشاء ملف Layout <div class="container-fluid"> <header class="bg-dark text-white p-3"> <h2>🔷 عنوان التطبيق</h2> </header> <div class="row"> <aside class="col-3 bg-light p-3"> <NavLink href="/" class="nav-link" Match="NavLinkMatch.All">🏠 الرئيسية</NavLink> <NavLink href="/counter" class="nav-link">➕ العداد</NavLink> </aside> ...

Blazor - تنفيذ دوال Blazor من JavaScript

🔹 Blazor - تنفيذ دوال Blazor من JavaScript في هذا الدرس سنتعلم كيفية استدعاء دوال C# داخل Blazor **من JavaScript**، وهذا يفيد عندما نريد إشعار Blazor من طرف JavaScript (مثل عند الضغط على زر خارجي، أو اكتمال عملية تحميل). --- 🧠 الفكرة العامة Blazor يتيح لنا تعريف كائن C# يمكن الوصول إليه من JavaScript باستخدام DotNetObjectReference ، ثم يمكننا من خلال JS استدعاء دوال تم وسمها بـ [JSInvokable] . --- 🛠️ خطوات استدعاء دالة Blazor من JavaScript ✅ 1. إنشاء دالة C# قابلة للاستدعاء من JS public class JsInteropHelper { [JSInvokable] public static void ShowAlertFromJs(string message) { Console.WriteLine("📥 تم استدعاء Blazor من JavaScript: " + message); } } ✅ 2. استدعاؤها من JavaScript DotNet.invokeMethodAsync("اسم_المشروع", "ShowAlertFromJs", "رسالة من JavaScript"); استبدل اسم_المشروع بـ اسم مشروع Blazor (الموجود في csproj). --- 📦 مثال عملي - زر JavaScript يستدعي C# ✅ 1. ملف JS: // wwwroot/...

Blazor - تنفيذ دوال JavaScript من Blazor

🔹 Blazor - تنفيذ دوال JavaScript من Blazor في هذا الدرس، سنتعلم كيفية تنفيذ دوال JavaScript من داخل كود Blazor C# باستخدام IJSRuntime . سنتناول حالات عملية، مثل تمرير المعاملات واستقبال القيم، وتنظيم الاستدعاءات في ملفات مستقلة. --- 🧱 الصيغة العامة لاستدعاء JavaScript await JS.InvokeVoidAsync("اسم_الدالة", المعاملات); InvokeVoidAsync : تُستخدم عندما لا تُرجع الدالة قيمة. InvokeAsync<T> : تُستخدم عندما تُرجع الدالة قيمة من نوع T. --- 🛠️ مثال عملي - تنفيذ دالة JavaScript ✅ 1. أنشئ ملف JavaScript: // wwwroot/scripts/myinterop.js function showAlert(message) { alert("📢 " + message); } function addNumbers(a, b) { return a + b; } ✅ 2. أضف الملف إلى _Host.cshtml أو index.html: <script src="scripts/myinterop.js"></script> ✅ 3. استدعِ الدوال من Blazor: @inject IJSRuntime JS <button class="btn btn-info" @onclick="Show">عرض رسالة</button> <button class="btn b...

Blazor - مقدمة في JavaScript Interop

🔹 Blazor - مقدمة في JavaScript Interop Blazor هو إطار عمل يعتمد على C#، لكن في بعض الحالات ستحتاج إلى استخدام وظائف JavaScript داخل تطبيقك – مثل التعامل مع مكتبات خارجية، التفاعل مع DOM، أو استدعاء أكواد جاهزة. هنا يأتي دور JavaScript Interop . --- 🔁 ما هو JavaScript Interop؟ JavaScript Interop (اختصار لـ Interoperability) هو جسر يسمح لتطبيق Blazor باستدعاء دوال JavaScript، وأيضًا يسمح لـ JavaScript باستدعاء دوال C# في Blazor. --- 🛠️ كيف يعمل؟ يتم ذلك باستخدام خدمة IJSRuntime المدمجة في Blazor. ✅ 1. استدعاء دالة JavaScript من C# @inject IJSRuntime JS <button @onclick="SayHello">قل مرحبًا</button> @code { async Task SayHello() { await JS.InvokeVoidAsync("alert", "مرحبًا من Blazor!"); } } InvokeVoidAsync تُستخدم للدوال التي لا تُرجع قيمة. --- ✅ 2. استدعاء دالة JavaScript مخصصة قم بإنشاء ملف JavaScript وإضافة دالة فيه: // wwwroot/scripts/myjs.js function showMessage(message) { alert...

Blazor - استخدام Protected Browser Storage

🔹 7.3 Blazor - استخدام Protected Browser Storage عند استخدام خدمات Singleton أو تخزين الحالة داخل المكونات، يتم فقدان البيانات عند تحديث الصفحة (Refresh). ولحل هذه المشكلة، يمكننا استخدام Protected Browser Storage لحفظ البيانات داخل متصفح المستخدم بشكل آمن. --- 🧠 ما هو ProtectedBrowserStorage؟ هي خدمة توفرها Blazor Server لحفظ البيانات في Session Storage أو Local Storage ، مع تشفير البيانات لضمان الحماية والأمان. --- 🛠️ خطوات استخدام Protected Browser Storage ✅ 1. إضافة التوجيه في رأس المكون @inject ProtectedLocalStorage localStorage ✅ 2. حفظ بيانات await localStorage.SetAsync("userName", "Mahmoud"); ✅ 3. قراءة بيانات var result = await localStorage.GetAsync<string>("userName"); string? name = result.Success ? result.Value : null; --- 🎯 الفرق بين LocalStorage و SessionStorage ProtectedLocalStorage: تبقى البيانات محفوظة حتى بعد إغلاق المتصفح. ProtectedSessionStorage: يتم حذف البيانات بمجرد إغلاق نافذة...

Blazor - استخدام Singleton Services لإدارة الحالة عبر التطبيق

🔹 Blazor - استخدام Singleton Services لإدارة الحالة عبر التطبيق في هذا الدرس، سنشرح كيف يمكننا استخدام خدمة Singleton لمشاركة البيانات (الحالة) بين مكونات متعددة في تطبيق Blazor. هذا الأسلوب مهم جدًا عندما تريد أن تتشارك عدة صفحات أو مكونات نفس المعلومات (مثل سلة التسوق أو بيانات المستخدم). --- 🧠 لماذا نستخدم Singleton؟ للاحتفاظ بالحالة في الذاكرة طوال مدة تشغيل التطبيق. لمشاركة نفس الكائن بين كل المكونات. لجعل التحديثات تنعكس على جميع الأجزاء المرتبطة تلقائيًا. --- 🛠️ خطوات إنشاء خدمة Singleton لإدارة الحالة ✅ 1. إنشاء كلاس AppState public class AppState { public string? UserName { get; set; } public int CartCount { get; set; } public event Action? OnChange; public void NotifyStateChanged() => OnChange?.Invoke(); } ✅ 2. تسجيل الخدمة في Program.cs builder.Services.AddSingleton<AppState>(); ✅ 3. استخدام AppState في أكثر من مكون مكون A: لتحديث البيانات @inject AppState State <input @bind="State.UserName...

Blazor - الطرق البسيطة لإدارة الحالة (في الذاكرة

🔹 Blazor - الطرق البسيطة لإدارة الحالة (في الذاكرة) في تطبيقات Blazor، إدارة الحالة (State Management) تعني الاحتفاظ بالبيانات بين تغيّرات واجهة المستخدم (UI) أو حتى بين الصفحات المختلفة. في هذا الدرس، سنبدأ بأبسط طريقة: **تخزين الحالة في الذاكرة داخل نفس المكون أو عبر خدمة Singleton.** --- 🧠 ما المقصود بالحالة في Blazor؟ الحالة تعني: بيانات نحتاج الاحتفاظ بها أثناء تفاعل المستخدم مع التطبيق، مثل: عدد عناصر في السلة إعدادات المستخدم المؤقتة نتائج بحث --- 🔹 1. تخزين الحالة داخل نفس المكون هذه الطريقة تُستخدم عندما لا تحتاج لمشاركة البيانات مع مكونات أخرى. @page "/counter" <h4>🔢 العداد: @count</h4> <button class="btn btn-primary" @onclick="Increment">زيادة</button> @code { private int count = 0; void Increment() { count++; } } 👆 هذه الحالة ستضيع عند إعادة تحميل الصفحة أو الانتقال إلى صفحة أخرى. --- 🔹 2. استخدام خدمة Singleton لحفظ الحالة إذا أردت الاحتفاظ بالحال...

Blazor - الفرق بين Parameters و RenderFragment

🔹 الفرق بين Parameters و RenderFragment في Blazor في Blazor، توجد طريقتان أساسيتان لتمرير المعلومات من مكوّن أب إلى مكوّن فرعي: Parameters لتمرير البيانات البسيطة، و RenderFragment لتمرير واجهة HTML ديناميكية. --- 🎯 تشبيه بسيط لفهم الفرق تخيل أنك في مطعم وتطلب وجبة: Parameter مثل أن تطلب "وجبة حارة مع جبنة زيادة" – أي بيانات . RenderFragment مثل أن تقول "سأجلب معي طبق خاص وأريد تقديمه في الوجبة" – أي محتوى HTML مخصص . --- 📊 مقارنة بين Parameters و RenderFragment العنصر Parameters RenderFragment الوظيفة تمرير بيانات بسيطة (نص، رقم...) تمرير واجهة HTML أو مكونات قابلة للتخصيص النوع string, int, bool, DateTime RenderFragment أو RenderFragment<T> الاستخدام Message="تم الحفظ" @<p>هذا محتوى مخصص</p> التعريف داخل المكون [Parameter] public string Message { get; set;...

Blazor - إنشاء مكونات ديناميكية (Dynamic Components)

🔹 Blazor - إنشاء مكونات ديناميكية (Dynamic Components) في بعض الحالات، قد تحتاج إلى عرض مكون معين في وقت التشغيل بناءً على شرط أو قيمة متغيرة – هذا ما يُعرف بالمكونات الديناميكية. Blazor يدعم ذلك من خلال العنصر <DynamicComponent> . --- 🧠 ما هو DynamicComponent؟ هو مكون خاص في Blazor يسمح لك بعرض مكون آخر **بشكل ديناميكي**، أي أن اسم المكون يُحدد في وقت التشغيل، ويمكنك تمرير المعاملات إليه أيضًا. <DynamicComponent Type="MyComponentType" Parameters="MyParameters" /> --- 📦 مثال عملي نفترض أن لدينا مكونين مختلفين: <!-- WelcomeComponent.razor --> <p class="text-success">👋 مرحبًا بك في موقعنا!</p> <!-- ErrorComponent.razor --> <p class="text-danger">❌ حدث خطأ ما!</p> والآن نريد عرض أحدهما بناءً على قيمة معينة. --- 🔀 استخدام DynamicComponent لعرض مكون حسب شرط @page "/dynamic-demo" @using Microsoft.AspNetCore.Components <h4>عرض مكون ديناميكي:</h...

Blazor - إعادة استخدام المكونات (Component Reusability)

🔹 Blazor - إعادة استخدام المكونات (Component Reusability) في Blazor، يُعد إعادة استخدام المكونات 🧠 لماذا نعيد استخدام المكونات؟ لتقليل التكرار (DRY - Don't Repeat Yourself). لتسهيل صيانة وتحديث الكود. لتوحيد الشكل والتصرف عبر أجزاء متعددة من التطبيق. --- 🛠️ مثال عملي على مكون قابل لإعادة الاستخدام نفترض أننا نريد مكونًا بسيطًا لعرض رسالة تنبيه مع نوع التنبيه (نجاح، خطأ، تحذير): <!-- AlertBox.razor --> <div class="alert @CssClass" role="alert"> @Message </div> @code { [Parameter] public string Message { get; set; } = string.Empty; [Parameter] public string CssClass { get; set; } = "alert-info"; } --- 📥 استخدام المكون في أكثر من مكان يمكننا الآن استخدام <AlertBox> في أي مكان بالصفحة وتغيير الرسالة أو نوع التنسيق: <AlertBox Message="تم الحفظ بنجاح" CssClass="alert-success" /> <AlertBox Message="حدث خطأ أثناء الحفظ" CssClass="alert-dan...

Blazor - التعامل مع RenderFragment

🔹 Blazor - التعامل مع RenderFragment RenderFragment هو نوع خاص في Blazor يُستخدم لتمرير أجزاء من واجهة المستخدم (UI) كمحتوى ديناميكي إلى مكوّن آخر. يشبه "slot" في Vue.js أو "children" في React. ببساطة، يمكننا اعتباره طريقة لتمرير "HTML مُخصص" من مكوّن أب إلى مكوّن فرعي. 🧠 ما هو RenderFragment؟ هو delegate يُستخدم في Blazor لتمثيل جزء من واجهة المستخدم يمكن تمريره إلى مكون آخر. الـ RenderFragment يمكن أن يكون ثابتًا أو يحتوي على منطق ديناميكي يتم إنشاؤه في وقت التشغيل. RenderFragment content = @<p>هذا محتوى ديناميكي</p>; 🛠️ استخدام RenderFragment كمحتوى في مكون نفترض أنك تريد إنشاء مكون <MyCard> يحتوي على رأس، ومحتوى، وتذييل قابل للتخصيص: <!-- MyCard.razor --> <div class="card mb-3"> <div class="card-header bg-primary text-white"> @Header </div> <div class="card-body"> @ChildContent </div> <div class="car...

.NET API - Roles & Authorization (السماح بناءً على الدور)

2.6 ‎.NET API - Roles & Authorization (السماح بناءً على الدور) بعد تفعيل تسجيل الدخول باستخدام JWT، يُفضل في بعض الأنظمة إضافة ميزة الأدوار (Roles) لتحديد صلاحيات المستخدمين، بحيث يُسمح فقط لمستخدمين بدور معين بالدخول إلى Endpoint معين. 👥 أمثلة على الأدوار الشائعة Admin : يمكنه إدارة كل شيء. User : يمكنه فقط عرض البيانات. Manager : لديه صلاحيات خاصة بالإشراف. 🔐 إضافة الدور إلى التوكن [HttpPost("login")] public IActionResult Login(UserLoginDto login) { if (login.Username == "admin" && login.Password == "123") { var claims = new[] { new Claim(ClaimTypes.Name, login.Username), new Claim(ClaimTypes.Role, "Admin") }; var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("your_super_secret_key_here")); var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); var token = new JwtSecurityToken( expir...

.NET API - حماية الـAPI باستخدام JWT Authentication

2.5 ‎.NET API - حماية الـAPI باستخدام JWT Authentication JWT أو JSON Web Token هو معيار يُستخدم لتأمين الـAPI من خلال إصدار "توكن" يُرفق مع كل طلب، ويُستخدم للتحقق من هوية المستخدم دون الحاجة لتخزين الجلسة على الخادم. 🔐 1. ما هو التوكن؟ التوكن هو سلسلة نصية تُولد عند تسجيل الدخول، وتُحفظ لدى العميل (Client)، وتُرسل مع كل طلب في الـ Header. Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... 📦 2. تثبيت الحزم المطلوبة dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer ⚙️ 3. إعداد المصادقة في Program.cs builder.Services.AddAuthentication("Bearer") .AddJwtBearer("Bearer", options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = false, ValidateAudience = false, ValidateLifetime = true, ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey( Encoding.UTF8.G...

.NET API - توثيق الـAPI باستخدام Swagger

2.4 ‎.NET API - توثيق الـAPI باستخدام Swagger Swagger هو أداة لتوثيق واختبار واجهات الـ Web API، وتُعرف الآن باسم OpenAPI . يتم دمجها بسهولة مع ASP.NET Core Web API لتوليد صفحة توثيق تفاعلية لكل الـEndpoints. ⚙️ 1. تثبيت الحزمة (إذا لم تكن موجودة) عادة ما تكون موجودة تلقائيًا عند إنشاء مشروع Web API جديد، لكن يمكنك تثبيتها يدويًا: dotnet add package Swashbuckle.AspNetCore 🧠 2. تفعيل Swagger في Program.cs builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); var app = builder.Build(); if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } 🌐 3. الدخول إلى واجهة Swagger بعد تشغيل المشروع، افتح الرابط التالي في المتصفح: http://localhost:5000/swagger ستظهر صفحة تحتوي على كل الـControllers وEndpoints، ويمكنك تجربة أي طلب منها مباشرة. 📝 4. إضافة تعليقات XML لتفاصيل التوثيق من داخل خصائص المشروع، فعّل خيار XML documentation file ثم أضف التعليق فوق كل دالة: /// <summary> /// يُرجع جميع المنتجات. /// ...

.NET API - فلترة وترتيب البيانات (Filtering, Sorting, Pagination)

2.3 ‎.NET API - فلترة وترتيب البيانات (Filtering, Sorting, Pagination) عند عرض بيانات كثيرة في Web API، من الأفضل توفير مرونة للمستخدم مثل: 🔍 فلترة (Filter) حسب شروط معينة ⬆️⬇️ ترتيب (Sort) حسب اسم أو تاريخ أو سعر 📄 تقسيم الصفحات (Pagination) لتقليل الحمل وتسريع الأداء 🔍 مثال على الفلترة Filtering [HttpGet] public IActionResult GetAll(string? search) { var query = _context.Products.AsQueryable(); if (!string.IsNullOrWhiteSpace(search)) query = query.Where(p => p.Name.Contains(search)); return Ok(query.ToList()); } مثال على الرابط: GET /api/products?search=laptop ⬆️⬇️ مثال على الترتيب Sorting public IActionResult GetAll(string? sort) { var query = _context.Products.AsQueryable(); if (sort == "name") query = query.OrderBy(p => p.Name); else if (sort == "price_desc") query = query.OrderByDescending(p => p.Price); return Ok(query.ToList()); } مثال: GET /api/products?sort=price...

.NET API - التعامل مع الأخطاء (Exception Handling + Middleware)

2.2 ‎.NET API - التعامل مع الأخطاء (Exception Handling + Middleware) عند بناء Web API احترافي، من المهم جدًا التعامل مع الأخطاء بطريقة منظمة وآمنة، بحيث لا يظهر للمستخدم تفاصيل داخلية، ويتم تسجيل الأخطاء لتتبعها لاحقًا. 🧨 ما أنواع الأخطاء الشائعة؟ ❌ NullReferenceException ❌ SqlException أو أخطاء قواعد البيانات ❌ UnauthorizedAccessException ❌ ArgumentException عند تمرير قيم غير صحيحة 🔧 طرق التعامل مع الأخطاء لدينا طريقتان رئيسيتان: ✅ استخدام try-catch داخل الـ Controller أو Service ✅ بناء Global Exception Handling Middleware 📍 مثال باستخدام try-catch [HttpGet("{id}")] public IActionResult GetById(int id) { try { var product = _context.Products.Find(id); if (product == null) return NotFound("المنتج غير موجود"); return Ok(product); } catch (Exception ex) { _logger.LogError(ex, "خطأ أثناء استرجاع المنتج"); return StatusCode(500, "حدث خطأ داخلي...

.NET API - DTOs وAutoMapper: نقل البيانات بين الطبقات

2.1 ‎.NET API - DTOs وAutoMapper: نقل البيانات بين الطبقات DTO هي اختصار لـ Data Transfer Object ، وهي كائنات تُستخدم لنقل البيانات بين الطبقات داخل التطبيق، خاصة من الطبقة الخلفية (Backend) إلى العميل (Client). أما AutoMapper فهي مكتبة في ‎.NET تُستخدم لتحويل البيانات تلقائيًا بين الكائنات (من Entity إلى DTO والعكس). 🧱 لماذا نستخدم DTOs؟ ✅ فصل كود قاعدة البيانات (Entity) عن كود العرض (Client). ✅ حماية الحقول الحساسة من الظهور في واجهة المستخدم. ✅ تحسين الأداء بنقل الحقول المطلوبة فقط. 📦 مثال: كيان المنتج Product // الكيان المرتبط بقاعدة البيانات public class Product { public int Id { get; set; } public string Name { get; set; } public decimal Price { get; set; } public DateTime CreatedAt { get; set; } } نريد أن نعرض فقط الاسم والسعر: // DTO public class ProductDto { public string Name { get; set; } public decimal Price { get; set; } } ⚙️ تثبيت AutoMapper dotnet add package AutoMapper.Extensions.Microsoft.DependencyInjection ...

.NET API - قراءة الـappsettings.json وربط البيانات

1.8 ‎.NET API - قراءة الـappsettings.json وربط البيانات ملف appsettings.json هو ملف الإعدادات الرئيسي في مشاريع ASP.NET Core، ويُستخدم لتخزين إعدادات التطبيق مثل بيانات الاتصال، مفاتيح API، إعدادات التكوين الخاصة، وغيرها. 🧾 تنسيق ملف appsettings.json { "ConnectionStrings": { "DefaultConnection": "Server=.;Database=MyDb;Trusted_Connection=True;" }, "MyAppSettings": { "SiteTitle": "Drift CMS", "ItemsPerPage": 10 } } 📦 قراءة الإعدادات في C# يمكنك إنشاء كلاس يمثل القسم الذي تريد قراءته: public class MyAppSettings { public string SiteTitle { get; set; } public int ItemsPerPage { get; set; } } ثم تسجله في Program.cs : builder.Services.Configure<MyAppSettings>( builder.Configuration.GetSection("MyAppSettings")); 🧠 استخدام الإعدادات داخل Controller أو Service using Microsoft.Extensions.Options; [ApiController] [Route("api/[controller]")] publi...

.NET API - التعامل مع HTTP Methods: GET, POST, PUT, DELETE

1.7 ‎.NET API - التعامل مع HTTP Methods: GET, POST, PUT, DELETE تُستخدم HTTP Methods في Web API لتحديد نوع العملية المطلوب تنفيذها على البيانات. في ASP.NET Core Web API، يتم ربط كل Method بميزة محددة من خلال Attribute مثل: [HttpGet] أو [HttpPost] . 📥 1. GET - جلب البيانات يستخدم للحصول على البيانات من السيرفر. [HttpGet] public IActionResult GetAll() { return Ok(_context.Products.ToList()); } مثال على الطلب في Postman أو المتصفح: GET http://localhost:5000/api/products 📤 2. POST - إضافة بيانات جديدة يُستخدم لإنشاء سجل جديد في قاعدة البيانات. [HttpPost] public IActionResult Create(Product product) { _context.Products.Add(product); _context.SaveChanges(); return Ok(product); } مثال على بيانات تُرسل في جسم الطلب: { "name": "New Product", "price": 200 } ✏️ 3. PUT - تحديث البيانات يُستخدم لتحديث سجل موجود بالكامل. [HttpPut("{id}")] public IActionResult Update(int id, Product product) { if (id != pro...

.NET API - CRUD باستخدام Entity Framework Core (مع قاعدة بيانات SQLite أو SQL Server)

1.6 ‎.NET API - CRUD باستخدام Entity Framework Core (مع قاعدة بيانات SQLite أو SQL Server) في هذا الدرس سنتعلم كيفية تنفيذ العمليات الأساسية CRUD (إنشاء، قراءة، تحديث، حذف) باستخدام Entity Framework Core وربطها بـ Web API. 📦 ما هو EF Core؟ Entity Framework Core هو ORM (Object-Relational Mapper) يتيح لك التعامل مع قاعدة البيانات ككائنات C# بدون الحاجة لكتابة SQL يدوي. 🔧 1. إعداد المشروع لاستخدام EF Core أولاً، نثبّت الحزم المطلوبة: dotnet add package Microsoft.EntityFrameworkCore dotnet add package Microsoft.EntityFrameworkCore.SqlServer dotnet add package Microsoft.EntityFrameworkCore.Tools إذا كنت تفضل SQLite: dotnet add package Microsoft.EntityFrameworkCore.Sqlite 📄 2. إنشاء الكيان (Model) public class Product { public int Id { get; set; } public string Name { get; set; } public decimal Price { get; set; } } 🧠 3. إنشاء DbContext using Microsoft.EntityFrameworkCore; public class AppDbContext : DbContext { public AppDbContext(DbContextOpt...