হ্যালো হাসিব! আমরা এক্সেল আপলোড ফিচারের দ্বিতীয় পার্টে চলে এসেছি। এই লেকচারে মূলত UI (User Interface) তৈরি করা হয়েছে, যেখান থেকে ইউজার এক্সেল ফাইল সিলেক্ট করে সার্ভারে সাবমিট করতে পারবে।

এর পাশাপাশি লেকচারার ফাইল আপলোডের একটি খুবই গুরুত্বপূর্ণ কনসেপ্ট enctype নিয়ে আলোচনা করেছেন এবং ডাটাবেস কানেকশনের একটি কমন এরর ফিক্স করেছেন।

চলো পুরো লেকচারটির একটি কুইক সামারি এবং বিস্তারিত আলোচনা শুরু করি।

📝 Lecture Summary at a Glance

  • New Controller: Countries আপলোড করার জন্য আলাদা একটি CountriesController তৈরি করা হয়েছে।
  • The Upload View: ইউজারের ফাইল ইনপুটের জন্য <input type="file"> ব্যবহার করে একটি HTML Form তৈরি করা হয়েছে।
  • Multipart Form Data: ফর্মে ফাইল আপলোড করার জন্য ফর্মের enctype="multipart/form-data" দেওয়া বাধ্যতামূলক। এটি ছাড়া ফাইল সার্ভারে যায় না।
  • Layout Update: নেভিগেশন বারে “Upload Countries” নামে নতুন একটি হাইপারলিংক যুক্ত করা হয়েছে।
  • Database Fix: রানটাইমে “Win32 Exception” (Database Network Error) আসলে বুঝতে হবে LocalDB সার্ভিস স্টার্ট হয়নি, যা Visual Studio থেকে ফিক্স করা হয়েছে।

🧠 Comprehensive Breakdown & Deep Dive

১. Setting up CountriesController [Importance: 8/10]

  • The “Why”: যেহেতু এক্সেল ফাইলের কাজ Countries ডাটাবেস নিয়ে, তাই Clean Architecture-এর রুলস অনুযায়ী এটি PersonsController-এ না লিখে আলাদা CountriesController তৈরি করা হয়েছে।

💻 Code Implementation (CountriesController.cs):

using Microsoft.AspNetCore.Mvc;
 
[Route("[controller]")]
public class CountriesController : Controller
{
    [HttpGet]
    [Route("[action]")]
    public IActionResult UploadFromExcel()
    {
        return View();
    }
}
 

২. The Form and enctype="multipart/form-data" [Importance: 10/10]

  • The “Why”: এটি ইন্টারভিউতে জিজ্ঞেস করার মতো একটি মোস্ট ইম্পরট্যান্ট পয়েন্ট। তুমি যখন সাধারণ ফর্মে (নাম, ইমেইল) সাবমিট করো, তখন সেটি URL Encoded হয়ে যায় (name=Hasib&age=24)। কিন্তু একটি ফাইল তো টেক্সট নয়, এটি বাইনারি ডাটা! URL Encoded টাইপ বাইনারি ডাটা সাপোর্ট করে না।
  • The Fix: ফাইল আপলোডের সময় ব্রাউজারকে বলে দিতে হয় যে ফর্মটি বিভিন্ন খণ্ডে (Multipart) ভাগ করে পাঠাতে হবে, যেখানে টেক্সটের খণ্ড আলাদা এবং ফাইলের খণ্ড আলাদা থাকবে। এজন্যই <form enctype="multipart/form-data"> ব্যবহার করা বাধ্যতামূলক।

💻 Code Implementation (UploadFromExcel.cshtml):

@{
    ViewBag.Title = "Upload Countries";
}
 
<div class="container">
    <h2>Upload Countries</h2>
 
    <form asp-controller="Countries" asp-action="UploadFromExcel" method="post" enctype="multipart/form-data">
        
        <div class="form-group flex">
            <div class="box">
                <label>Choose an Excel File:</label>
            </div>
            
            <div class="box">
                <input type="file" name="excelFile" class="form-input" accept=".xlsx, .xls" />
                
                <div class="text-red">
                    @ViewBag.ErrorMessage
                </div>
            </div>
        </div>
 
        <div class="form-group flex">
            <div class="box"></div>
            <div class="box">
                <button type="submit" class="btn btn-primary">Upload</button>
            </div>
        </div>
 
    </form>
</div>
 

(নোট: আমি accept=".xlsx, .xls" অ্যাড করেছি, যাতে ব্রাউজার শুধু এক্সেল ফাইল সিলেক্ট করতে দেয়। এটি একটি ভালো ইউজার এক্সপেরিয়েন্স)।

৩. Database Network Error (Win32 Exception) [Importance: 7/10]

  • The “Why”: প্রজেক্ট রান করার পর লেকচারার একটি বিশাল এরর পেলেন: “A network-related or instance-specific error occurred…”
  • The Reality (For Linux/Docker): লেকচারার Visual Studio-র LocalDB ইউজ করছেন বলে সার্ভিস রিস্টার্ট দিয়ে ফিক্স করেছেন। হাসিব, তুমি যেহেতু Fedora Linux-এ ডকার দিয়ে SQL Server চালাও, তোমার এমন এরর এলে বুঝতে হবে তোমার ডকার কন্টেইনারটি স্টপ হয়ে আছে।

🛠️ The Linux Fix: টার্মিনালে কমান্ড দেবে:

# রানিং কন্টেইনার চেক করা
docker ps 
 
# যদি SQL কন্টেইনার না থাকে তবে স্টার্ট করা (তোমার কন্টেইনারের নাম অনুযায়ী)
docker start sql_server_container_name
 

🚀 Modern UI & Backend Integration Tips

১. The Correct name Attribute: ফর্মের <input type="file" name="excelFile" /> এ তুমি যে name অ্যাট্রিবিউটটি দেবে, পরবর্তী লেকচারে Controller-এর Action Method-এ প্যারামিটারের নাম ঠিক হুবহু সেটিই হতে হবে (যেমন public IActionResult Upload(IFormFile excelFile)), না হলে ফাইল সার্ভারে null হিসেবে আসবে!

২. Validation Check (Front-end): ইউজার যদি ফাইল সিলেক্ট না করেই “Upload” বাটনে ক্লিক করে, তবে সার্ভারে খামোখা রিকোয়েস্ট পাঠিয়ে লাভ নেই। বাটনটি ডিজেবল করে রাখা বা সিম্পল জাভাস্ক্রিপ্ট ভ্যালিডেশন দেওয়াটা ভালো প্র্যাকটিস।

পরবর্তী লেকচারে Controller-এ এই POST রিকোয়েস্ট রিসিভ করে সার্ভিস লেয়ারের সাথে কানেক্ট করার ইমপ্লিমেন্টেশন দেখানো হবে। তুমি রেডি হলে পরের অংশের ট্রান্সক্রিপ্টটি দিতে পারো!