হ্যালো হাসিব! এই লেকচারে আমরা Create Form-এর ড্রপডাউন লিস্টের (Select) অপশনগুলো তৈরি করা আরও সহজ করেছি। এর আগে আমরা ভিউয়ের ভেতরে foreach লুপ চালিয়ে <option> ট্যাগগুলো তৈরি করেছিলাম। এবার আমরা সেই কাজটা Controller-এ করে SelectListItem এর সাহায্যে ভিউতে asp-items Tag Helper ব্যবহার করেছি। এছাড়া সবগুলোর <label>-এও asp-for ব্যবহার করা হয়েছে।

চলো লেকচারটির একটি কুইক সামারি দেখে নিই।

📌 Quick Summary for Revision

  • SelectListItem Class: ড্রপডাউনের অপশন তৈরি করার জন্য ASP.NET Core-এর একটি বিল্ট-ইন ক্লাস। এর প্রধান দুটি প্রপার্টি হলো Text (যা ইউজারের সামনে দেখাবে) এবং Value (যা সাবমিট হবে)।
  • Controller Logic: LINQ-এর .Select() মেথড ব্যবহার করে CountryResponse এর লিস্টকে SelectListItem এর লিস্টে কনভার্ট করা।
  • Tag Helper asp-items: ভিউতে <select> ট্যাগের ভেতরে asp-items="@ViewBag.Countries" ব্যবহার করা, যাতে foreach লুপ ছাড়াই অপশনগুলো জেনারেট হয়ে যায়।
  • Label Tag Helper: ম্যানুয়াল for অ্যাট্রিবিউটের বদলে <label asp-for="PropertyName"> ব্যবহার করা। এতে কম্পাইল-টাইম ভেরিফিকেশন পাওয়া যায় এবং বানান ভুলের সম্ভাবনা থাকে না।

🚀 Comprehensive Breakdown & The “Why”

নিচে লেকচারের প্রতিটি কনসেপ্ট বিস্তারিত এবং কারণসহ এক্সপ্লেইন করা হলো:

১. Controller-এ SelectListItem জেনারেট করা [Priority: 10/10]

The “Why”: ভিউয়ের কাজ হলো শুধু ডাটা দেখানো, ডাটা প্রসেস করা নয়। ভিউয়ের ভেতরে foreach লুপ লেখা খুব একটা ক্লিন প্র্যাকটিস নয়। ASP.NET Core-এ ড্রপডাউন ডাটা প্রসেস করার স্ট্যান্ডার্ড নিয়ম হলো Controller থেকে SelectListItem এর একটি কালেকশন তৈরি করে পাঠানো।

Implementation (PersonsController.cs):

using Microsoft.AspNetCore.Mvc.Rendering; // SelectListItem-এর জন্য এই নেমস্পেস লাগবে
 
[Route("persons/create")]
[HttpGet]
public IActionResult Create()
{
    // ১. Service থেকে সব Country আনা
    List<CountryResponse> countries = _countriesService.GetAllCountries();
 
    // ২. CountryResponse-কে SelectListItem-এ কনভার্ট করা
    ViewBag.Countries = countries.Select(temp => new SelectListItem()
    {
        Text = temp.CountryName,           // ইউজার এটা দেখবে (যেমন: USA)
        Value = temp.CountryID.ToString()  // সার্ভারে এটা সাবমিট হবে (Guid কে String করা হয়েছে)
    });
 
    return View();
}
 

নোট: একই কাজ POST Create মেথডেও করতে হবে (ভ্যালিডেশন ফেইল হলে রিলোড করার জন্য)।

২. View-তে asp-items ব্যবহার করা [Priority: 10/10]

The “Why”: Controller থেকে যখন SelectListItem এর লিস্ট পাঠানো হয়, তখন asp-items Tag Helper নিজে থেকেই সেটাকে রিড করে প্রতিটি আইটেমের জন্য একটি করে <option value="Value">Text</option> ট্যাগ বানিয়ে দেয়। এতে ভিউয়ের কোড অনেক ছোট এবং ক্লিন হয়।

Implementation (Create.cshtml):

<select asp-for="CountryID" class="form-input">
    <option value="">Please Select</option>
    @foreach(var item in ViewBag.Countries)
    {
        <option value="@item.CountryID">@item.CountryName</option>
    }
</select>
 
<select asp-for="CountryID" asp-items="@ViewBag.Countries" class="form-input">
    <option value="">Please Select</option>
</select>
 

৩. Label-এর জন্য asp-for [Priority: 8/10]

The “Why”: লেবেলের ক্ষেত্রে আগে আমরা <label for="PersonName"> লিখতাম। এখানে PersonName হলো একটি হার্ডকোড স্ট্রিং। যদি মডেলে প্রপার্টির নাম চেঞ্জ হয়ে FullName হয়, তবে এখানে চেঞ্জ না করলে লেবেলে ক্লিক করলে ইনপুট ফিল্ড আর ফোকাস হবে না (Broken UX)। asp-for="PersonName" ব্যবহার করলে এই ভুল হওয়ার কোনো সুযোগ থাকে না, কারণ বিল্ড করার সময়ই ভিজ্যুয়াল স্টুডিও এরর দেখিয়ে দেবে।

Implementation:

<label for="PersonName">Person Name</label>
 
<label asp-for="PersonName">Person Name</label>
 

তবে, asp-for ব্যবহার করলে লেবেলের ভেতরের টেক্সট (“Person Name”) ম্যানুয়ালি না লিখলেও হয়। ফ্রেমওয়ার্ক মডেলের প্রপার্টির নাম দেখেই টেক্সট বসিয়ে দেয়। কাস্টম টেক্সট চাইলে তখন মডেলে [Display(Name="Person Name")] অ্যানোটেশন ব্যবহার করা বেস্ট প্র্যাকটিস।


🆕 .NET 10 & Modern Approaches (SelectList Class)

লেকচারে LINQ .Select() ব্যবহার করে ম্যানুয়ালি SelectListItem তৈরি করা হয়েছে। এটি ভালো, তবে ASP.NET Core-এ এর চেয়েও শর্টকাট একটি ক্লাস আছে যার নাম SelectList। এটি একটি লাইনে পুরো কনভার্শনের কাজ করে দেয়!

Modern Alternative in Controller:

// LINQ দিয়ে লুপ না চালিয়ে সরাসরি SelectList অবজেক্ট তৈরি করা যায়
List<CountryResponse> countries = _countriesService.GetAllCountries();
 
// প্যারামিটার: 1. ডাটা সোর্স, 2. Value প্রপার্টির নাম, 3. Text প্রপার্টির নাম
ViewBag.Countries = new SelectList(countries, nameof(CountryResponse.CountryID), nameof(CountryResponse.CountryName));
 

ভিউয়ের কোড একদম সেম থাকবে (asp-items="@ViewBag.Countries")।


⌨️ IDE Shortcuts

  • Code Navigation:
  • মেথড বা ক্লাসের সোর্স কোডে যেতে: নামের উপর F12 চাপুন।
  • (উদাহরণস্বরূপ: SelectListItem ক্লাসটি কীভাবে কাজ করে তা দেখতে SelectListItem এর উপর ক্লিক করে F12 চাপতে পারো)।

💡 Best Practices (Dropdowns & Labels)

১. ViewModel over ViewBag: এই লেকচারেও ড্রপডাউনের ডাটার জন্য ViewBag ব্যবহার করা হয়েছে। আবারও বলছি, রিয়েল লাইফ প্রজেক্টে ViewBag-এর বদলে ViewModel ব্যবহার করে ড্রপডাউনের লিস্ট পাঠানো উচিত। (যেমন: model.CountriesList)। ২. Default Option Validation: <option value="">Please Select</option> রাখাটা খুবই ভালো প্র্যাকটিস। যদি ইউজার কিছু সিলেক্ট না করেই ফর্ম সাবমিট করে, তাহলে সার্ভারে null বা ফাঁকা ভ্যালু যাবে এবং মডেল ভ্যালিডেশন (যদি [Required] থাকে) তাকে এরর দেখাবে।

আমরা ফর্ম তৈরি করা এবং Tag Helper-এর ব্যবহার শিখে নিলাম। লেকচারের শেষে বলা হয়েছে, এরপরের লেকচারটি হবে Client-Side Validation নিয়ে (যেখানে পেজ রিলোড ছাড়াই JavaScript এর মাধ্যমে ফর্ম ভ্যালিডেট করা হবে)।

এই ড্রপডাউন বা লেবেলের টপিক নিয়ে তোমার কি কোনো কনফিউশন আছে?