এখানে মূলত দেখানো হয়েছে কীভাবে Model Binding-এর ডিফল্ট বিহেভিয়ারকে তুমি তোমার প্রয়োজন অনুযায়ী কন্ট্রোল করতে পারো।

📝 Quick Revision Summary

  • Default Behavior: Model Binding প্রথমে Route Data চেক করে, সেখানে ভ্যালু না পেলে Query String থেকে ডেটা নেওয়ার চেষ্টা করে।
  • Overrides: [FromRoute] এবং [FromQuery] Attribute ব্যবহার করে এই ডিফল্ট ফ্লো ব্রেক করা যায়।
  • [FromRoute]: Action Method-কে বাধ্য করে শুধুমাত্র URL Path (Route) থেকে ডেটা রিসিভ করতে। Query String-এ ডেটা থাকলেও তা ইগনোর করে।
  • [FromQuery]: Action Method-কে বাধ্য করে শুধুমাত্র ?key=value (Query String) থেকে ডেটা রিসিভ করতে। Route-এ ডেটা থাকলেও তা রিড করে না।
  • Code Refactoring: ডুপ্লিকেট Validation লজিক রিমুভ করে কোড ক্লিন রাখা উচিত।

🔍 Comprehensive Breakdown

১. Default Model Binding Behavior (Priority: 7/10)

The Why (কেন জানা জরুরি): ওভাররাইড করার আগে সিস্টেম ডিফল্টভাবে কীভাবে কাজ করে তা ক্লিয়ার থাকা দরকার। লেকচারের শুরুতে বলা হয়েছে, যখন Action Method-এ কোনো Parameter দেওয়া থাকে, তখন ASP.NET Core স্বয়ংক্রিয়ভাবে প্রথমে Route Data-তে সেই ভ্যালু খোঁজে। যদি সেখানে ভ্যালু না দেওয়া থাকে (null হয়), তখন সে Query String চেক করে।

২. [FromRoute] Attribute-এর ব্যবহার (Priority: 10/10)

The Why (কেন ব্যবহার করব): যখন তুমি নিশ্চিত করতে চাও যে কোনো স্পেসিফিক Parameter শুধুমাত্র URL Path থেকেই আসবে। উদাহরণস্বরূপ, Chatrabash প্রজেক্টে যদি তুমি নির্দিষ্ট কোনো হোস্টেলের ইনফরমেশন ফেচ করতে চাও, তবে আইডিটা Route থেকে আসাই লজিক্যাল এবং RESTful স্ট্যান্ডার্ড। কেউ যদি Query String দিয়ে আইডি পাস করতে চায়, তুমি তা ইগনোর করতে চাও।

Code Implementation:

// Route: api/hostels/{hostelId}
[HttpGet("api/hostels/{hostelId}")]
public IActionResult GetHostelDetails([FromRoute] int? hostelId)
{
    // যদি রিকোয়েস্ট আসে: api/hostels?hostelId=5
    // তাহলে hostelId null হবে। কারণ [FromRoute] থাকায় সে Query String চেক করবে না।
    
    if (hostelId == null) return BadRequest("Hostel ID must be provided in the route.");
    
    return Ok($"Fetching details for Hostel ID: {hostelId}");
}
 

৩. [FromQuery] Attribute-এর ব্যবহার (Priority: 10/10)

The Why (কেন ব্যবহার করব): Data Filtering, Sorting বা Pagination-এর জন্য Query String ব্যবহার করা হয়। তুমি যদি চাও কোনো Parameter শুধুমাত্র Query String থেকেই তার ভ্যালু নিক (Route-এ একই নামের ভ্যালু থাকলেও তা ইগনোর করুক), তখন এটি ব্যবহার করা হয়। যেমন, Chatrabash-এ এভেইলেবল রুম ফিল্টার করার ক্ষেত্রে এটি পারফেক্ট।

Code Implementation: (Something wrong here)

// Route: api/rooms/{roomId?}
[HttpGet("api/rooms/{roomId?}")]
public IActionResult FilterRooms([FromQuery] int? roomId, [FromQuery] bool isAvailable)
{
    // যদি রিকোয়েস্ট আসে: api/rooms/10?roomId=50&isAvailable=true
    // তাহলে roomId হবে 50। কারণ [FromQuery] থাকার কারণে সে Route-এর '10'-কে পুরোপুরি ইগনোর করেছে।
    
    return Ok($"Filtering Room ID: {roomId}, Available: {isAvailable}");
}
 

৪. Explicit Specification vs Default Priority (Priority: 8/10)

লেকচারের মূল থিম হলো: থিওরেটিক্যালি Route Data-এর Priority বেশি হলেও, তুমি যখন Explicitly [FromQuery] বা [FromRoute] বলে দাও, তখন Model Binding-এর ডিফল্ট Priority পুরোপুরি ইগনোর হয়। তুমি যেই Attribute দেবে, ফ্রেমওয়ার্ক শুধু সেই সোর্স থেকেই ডেটা পিক করবে।

৫. Code Cleanup / Refactoring (Priority: 5/10)

ভিডিওর একদম শেষে ট্রেইনার দেখিয়েছেন যে, আগের লেকচারের কোডে কিছু ডুপ্লিকেট Validation Condition ছিল (যেমন: bookId < 0 এবং bookId > 1000 চেক করার লজিক)। তিনি অপ্রয়োজনীয় কন্ডিশনগুলো রিমুভ করে কোড ক্লিন করেছেন। এটি মূলত Clean Code মেইনটেইন করার একটি সাধারণ রিমাইন্ডার।


💡 Best Practices

  1. Be Explicit: প্যারামিটারের সোর্স সব সময় Explicitly বলে দেওয়া বেস্ট প্র্যাকটিস। এতে অন্য ডেভেলপাররা কোড দেখলেই বুঝতে পারে ডেটা কোথা থেকে এক্সপেক্ট করা হচ্ছে।
  • Example: public IActionResult ProcessOrder([FromBody] OrderDto order, [FromQuery] bool applyDiscount)
  1. Resource ID vs Filters: যেকোনো Resource Identify করার জন্য (যেমন: userId, hostelId) সব সময় [FromRoute] ব্যবহার করবে। আর অপশনাল ফিল্টার বা পেজিনেশনের জন্য (যেমন: pageNumber, searchTerm) [FromQuery] ব্যবহার করবে।

🚀 .NET 10 Updates (Changes from .NET 6)

ভিডিওর কনসেপ্টগুলো MVC Controller-এর উপর ভিত্তি করে। তবে .NET 8, 9 এবং 10-এ (বিশেষ করে Minimal APIs-এ) Model Binding আরও অনেক স্মার্ট এবং Implicit হয়ে গেছে। C# 13 ব্যবহার করে তুমি এখন খুব সহজেই পুরো রিকোয়েস্ট বাইন্ড করতে পারো।

.NET 10-এ Route Template দেখেই ফ্রেমওয়ার্ক অটোমেটিক বুঝে নেয় কোনটা Route থেকে আসবে আর কোনটা Query থেকে।

.NET 10 Minimal API Code Implementation:

var app = WebApplication.CreateBuilder(args).Build();
 
// Route parameter টেমপ্লেটে ডিফাইন করা আছে
app.MapGet("/api/hostels/{hostelId}/rooms", (int hostelId, bool isAvailable) => 
{
    // .NET 10 এতটাই স্মার্ট যে:
    // ১. {hostelId} টেমপ্লেটে থাকায় সে অটোমেটিক একে [FromRoute] হিসেবে ট্রিট করবে।
    // ২. isAvailable টেমপ্লেটে না থাকায় সে অটোমেটিক একে [FromQuery] হিসেবে ট্রিট করবে। 
    // অ্যাট্রিবিউট না দিলেও ডিফল্টভাবেই একদম লজিক্যাল সোর্স থেকে ডেটা ম্যাপ হবে।
    
    return Results.Ok(new { Hostel = hostelId, Available = isAvailable });
});
 
app.Run();
 

এই কনসেপ্টটা ভিজ্যুয়ালি এক্সপ্লোর করার জন্য নিচের সিমুলেটরটি ব্যবহার করতে পারো: