从Controller到Razor View传递LINQ查询结果的公告板开发问题
Let's break this down into clear, actionable steps to build the functionality you need—no username dropdown, auto-populating the correct admin ID via username matching, and passing data from your Controller to the Razor View smoothly.
1. Grab the Current Logged-In User's Username
First, pull the username of the logged-in admin from the authentication context. In your Controller, this is straightforward:
string currentUserName = User.Identity.Name;
This gives us the username we’ll use to match against your admin records, even if their admin ID doesn’t align with their regular user ID.
2. Fetch the Admin ID with a LINQ Query
Assuming you have an Admin table/entity with fields AdminId (the ID you need for bulletins) and UserName (matches the logged-in user’s username), use this LINQ query to get the correct admin record:
// Replace with your actual DbContext and entity names var matchingAdmin = dbContext.Admins .FirstOrDefault(admin => admin.UserName.Equals(currentUserName, StringComparison.OrdinalIgnoreCase)); // Add error handling for edge cases if (matchingAdmin == null) { ModelState.AddModelError("", "No admin record found linked to your account."); return View(); }
This query finds the admin associated with the logged-in username, solving your ID mismatch issue.
3. Attach the Admin ID to the New Bulletin
When the user submits their bulletin content, assign the fetched AdminId to the new entry before saving it to the database:
[HttpPost] public ActionResult PostBulletin(BulletinFormViewModel model) { if (ModelState.IsValid) { string currentUserName = User.Identity.Name; var matchingAdmin = dbContext.Admins .FirstOrDefault(admin => admin.UserName == currentUserName); if (matchingAdmin == null) { ModelState.AddModelError("", "Admin record not found."); return View(model); } var newBulletin = new Bulletin { Content = model.Content, AdminId = matchingAdmin.AdminId, // Use the matched admin ID CreatedDate = DateTime.Now // Add any other required fields (like status, etc.) }; dbContext.Bulletins.Add(newBulletin); dbContext.SaveChanges(); // Redirect to the bulletin board view after successful post return RedirectToAction("BulletinBoard"); } // Return to the form if validation fails return View(model); }
4. Pass Bulletin Data to the Razor View
To display all bulletins (including the new one), fetch the full list (with admin details if you want to show them) and pass it to the View. Using a ViewModel is the cleanest, most maintainable approach:
Step 4.1: Create a Display ViewModel
public class BulletinDisplayViewModel { public int BulletinId { get; set; } public string Content { get; set; } public DateTime CreatedDate { get; set; } public string AdminUserName { get; set; } // Show the admin's name if needed }
Step 4.2: Fetch and Map Data in the Controller
public ActionResult BulletinBoard() { var bulletinsWithAdminInfo = dbContext.Bulletins .Join(dbContext.Admins, bulletin => bulletin.AdminId, admin => admin.AdminId, (bulletin, admin) => new BulletinDisplayViewModel { BulletinId = bulletin.BulletinId, Content = bulletin.Content, CreatedDate = bulletin.CreatedDate, AdminUserName = admin.UserName }) .OrderByDescending(b => b.CreatedDate) // Show newest bulletins first .ToList(); // Pass the list to the View return View(bulletinsWithAdminInfo); }
Step 4.3: Render Bulletins in the Razor View
In your BulletinBoard.cshtml View, loop through the ViewModel list to display each bulletin:
@model List<BulletinDisplayViewModel> <h1>Bulletin Board</h1> <!-- Bulletin Submission Form (if on the same page) --> @using (Html.BeginForm("PostBulletin", "Bulletin", FormMethod.Post)) { <div class="form-group"> @Html.LabelFor(m => m.First().Content) @Html.TextAreaFor(m => m.First().Content, new { @class = "form-control", rows = 5 }) @Html.ValidationMessageFor(m => m.First().Content) </div> <button type="submit" class="btn btn-primary">Post Bulletin</button> } <!-- List of Bulletins --> <div class="mt-4"> @foreach (var bulletin in Model) { <div class="card mb-3"> <div class="card-body"> <p class="card-text">@bulletin.Content</p> <p class="card-text"> <small class="text-muted">Posted by @bulletin.AdminUserName on @bulletin.CreatedDate.ToString("MM/dd/yyyy HH:mm")</small> </p> </div> </div> } </div>
Quick Tips
- Error Handling: Never skip checking for null admin records—this prevents runtime crashes if a logged-in user doesn’t have a matching admin entry.
- Case Insensitivity: Using
StringComparison.OrdinalIgnoreCaseensures username matches work even if cases don’t align (e.g., "JohnDoe" vs "johndoe"). - ViewModel Best Practice: Separating display logic from database entities keeps your code flexible and easy to update later.
内容的提问来源于stack exchange,提问作者Chloe Finn

