হ্যালো হাসিব! আজকের লেকচারটি হলো “ViewData in Layout Views”। এই লেকচারে আমরা দেখব কীভাবে একটি View থেকে Layout View-তে ডেটা (যেমন পেজের Title) ট্রান্সফার করা যায়। এটি MVC-তে অত্যন্ত দরকারি একটি কনসেপ্ট।

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

📝 শর্ট সামারি (Quick Revision)

  • Execution Sequence: Controller -> View -> Layout View। এই সিকোয়েন্সের কারণেই Controller বা View থেকে Layout-এ ডেটা পাস করা সম্ভব হয়।
  • ViewData Object: এটি একটি Dictionary Type অবজেক্ট, যা Key-Value pair হিসেবে ডেটা স্টোর করে।
  • Setting Data (in View): প্রতিটি View ফাইলে পেজের নাম সেট করতে হয়: ViewData["Title"] = "Home";
  • Getting Data (in Layout): Layout ফাইলে সেই নাম ডায়নামিকালি রেন্ডার করতে হয়: <title>@ViewData["Title"]</title>
  • Scope: ViewData ব্যবহার করে শুধু String নয়, যেকোনো Object বা Data (যেমন Model Object, Number) View থেকে Layout-এ পাঠানো যায়।
  • ViewImports Rule: _ViewImports.cshtml শুধুমাত্র Namespaces ইমপোর্ট করার জন্য ব্যবহৃত হয়, এখানে ডেটা শেয়ারিং করা উচিত নয়।

🚀 বিস্তারিত আলোচনা (Comprehensive Breakdown)

১. MVC-তে Code Execution Sequence (Priority: 9/10)

কী (What): Controller-এ return View() কল করার পর ফ্রেমওয়ার্ক ঠিক কোন সিরিয়ালে ফাইলগুলো এক্সিকিউট করে, তা বোঝা খুব জরুরি। Flow:

  1. Global ViewImports & ViewStart: Views ফোল্ডারের রুট ডিরেক্টরিতে থাকা ফাইলগুলো।
  2. Local ViewImports & ViewStart: Controller-specific ফোল্ডারে (যেমন: Views/Home/) থাকা ফাইলগুলো (যদি থাকে)।
  3. Actual View: যে View-টি রিকোয়েস্ট করা হয়েছে (যেমন: Index.cshtml)।
  4. Layout View: সবার শেষে _Layout.cshtml এক্সিকিউট হয়।

কেন (Why): যেহেতু Actual View এক্সিকিউট হওয়ার পর Layout View এক্সিকিউট হয়, তাই View-এর ভেতরে তৈরি করা বা অ্যাসাইন করা যেকোনো ডেটা খুব সহজেই Layout View-তে এক্সেস করা যায়। ডেটা সবসময় Downstream-এ ফ্লো করে।

২. ViewData ব্যবহার করে Data Transfer (Priority: 10/10)

কী (What): ViewData হলো ASP.NET Core-এর একটি Built-in Dictionary object। এটি মূলত Controller থেকে View অথবা View থেকে Layout-এ ডেটা ট্রান্সফার করতে ব্যবহৃত হয়। কেন (Why): আমাদের লেআউটের <head> ট্যাগের ভেতরে একটি <title> ট্যাগ থাকে। আমরা চাই যখন ইউজার Home পেজে যাবে, তখন ব্রাউজারের ট্যাবে “Home” লেখা উঠুক, আবার যখন Contact পেজে যাবে, তখন “Contact” লেখা উঠুক। যেহেতু Layout ফাইল একটাই, তাই এই Title-টি ডাইনামিক হতে হবে।

৩. Code Implementation: View থেকে Layout এ Title পাস করা (Priority: 10/10)

ধাপ ১: View-এর ভেতরে ViewData সেট করা প্রতিটি নির্দিষ্ট View-তে (যেমন Index.cshtml, About.cshtml) Razor Code Block-এর ভেতরে আমাদের Key-Value অ্যাসাইন করতে হবে।

<!-- Views/Home/Index.cshtml -->
@{
    // "Title" হলো Key, এবং "Home" হলো Value
    ViewData["Title"] = "Home";
}
 
<h1>Welcome to Home Page</h1>
 

ধাপ ২: Layout View-তে সেই Data রেন্ডার করা এবার _Layout.cshtml ফাইলের <title> ট্যাগের ভেতরে সেই Key-টি কল করতে হবে।

<!-- Views/Shared/_Layout.cshtml -->
<!DOCTYPE html>
<html>
<head>
    <!-- View থেকে আসা Title এখানে রেন্ডার হবে -->
    <title>@ViewData["Title"]</title>
</head>
<body>
    <div class="page-content">
        @RenderBody()
    </div>
</body>
</html>
 

এভাবে প্রতিটি View-এর শুরুতে ViewData["Title"] = "Contact";, ViewData["Title"] = "Products"; ইত্যাদি সেট করে দিলে, Layout স্বয়ংক্রিয়ভাবে সেই পেজের জন্য সঠিক Title রেন্ডার করবে।

৪. Inspect Element এবং Output Verification (Priority: 6/10)

কী (What): কোড রান করার পর ব্রাউজারে গিয়ে Network Tab বা Elements Tab-এ (শর্টকাট: Ctrl + Shift + I) দেখতে পাবে যে, <title> ট্যাগের ভেতরে ভ্যালুটি সঠিকভাবে বসে গেছে। ভিডিওতে ইনস্ট্রাক্টর Layout View-তে Breakpoint বসানোর চেষ্টা করেছিলেন, কিন্তু Razor view-এর HTML এলিমেন্টের লাইনে (যেমন <title>) সরাসরি Breakpoint হিট করে না, যদি না সেখানে কমপ্লেক্স কোনো C# লজিক থাকে।

৫. ViewImports এবং ViewStart এর সীমাবদ্ধতা (Priority: 5/10)

কী (What): যদিও _ViewImports এবং _ViewStart ফাইলগুলো সবার আগে এক্সিকিউট হয়, কিন্তু এই ফাইলগুলোর মাধ্যমে ViewData ব্যবহার করে ডেটা পাস করা ঠিক নয়। কেন (Why): _ViewImports এর একমাত্র উদ্দেশ্য হলো Namespaces (@using) ইমপোর্ট করা। আর _ViewStart এর কাজ হলো গ্লোবাল Layout সেট করা। এগুলোর সাথে ডেটা শেয়ারিংয়ের কোনো সম্পর্ক নেই।


💡 .NET 10 Smarter Approach & Enhancements

ভিডিওতে দেখানো পদ্ধতিটি ১০০% সঠিক এবং এখনও বহুল ব্যবহৃত। তবে আধুনিক .NET 10 প্রজেক্টে আমরা <title> রেন্ডার করার সময় একটি Fallback বা Default Value প্র্যাকটিস করি।

ধরো, কোনো একটি View-তে তুমি ভুল করে ViewData["Title"] সেট করতে ভুলে গেলে। তখন ব্রাউজারের ট্যাবে কিছুই দেখাবে না বা ফাঁকা থাকবে। এটি এড়ানোর জন্য নিচের স্মার্ট পদ্ধতিটি ব্যবহার করা হয়:

<!-- Views/Shared/_Layout.cshtml (Smarter Approach) -->
<head>
    <!-- যদি ViewData["Title"] নাল থাকে, তবে "My Application" দেখাবে -->
    <title>@ViewData["Title"] - My Application</title>
</head>
 

অথবা আরও সেইফ অ্যাপ্রোচ:

<head>
    <title>@(ViewData["Title"] ?? "Welcome") - Demo App</title>
</head>
 

🏆 Best Practices (MVC Layout & ViewData)

  1. Consistent Key Naming: ViewData-এর Key এর নাম সবসময় একটি নির্দিষ্ট কনভেনশনে হওয়া উচিত (যেমন: "Title", "MetaDescription"), যাতে পুরো টিমের বুঝতে সুবিধা হয়।
  2. Avoid Complex Objects in ViewData: ViewData দিয়ে String, Number বা ছোটখাটো মেটাডেটা (যেমন Title) পাস করা ঠিক আছে। কিন্তু কোনো বড় Database Entity বা Model Object পাস করার জন্য ViewData ব্যবহার করা Bad Practice। তার জন্য Strongly Typed Views (@model) ব্যবহার করতে হবে।
  3. ViewBag vs ViewData: অনেকেই ViewData["Title"] এর বদলে ViewBag.Title ব্যবহার করতে পছন্দ করেন। দুটি আসলে একই ডেটা সোর্স ব্যবহার করে। ViewBag হলো ViewData এর একটি dynamic wrapper। তবে Layout-এর Title এর জন্য ViewData["Title"] ব্যবহার করাই স্ট্যান্ডার্ড টেমপ্লেট কনভেনশন।