Redirect,RedirectToAction和Return View 的区别

博客主要介绍了Redirect、RedirectToAction和Return View的区别。Redirect让浏览器重定向,与服务器两次交互,新请求取不到第一次的ViewBag信息;Return View由服务器渲染cshtml内容,一次交互,可获取ViewBag信息。RedirectToAction是客户端重定向,无法读取ViewBag内容。还说明了各自适用场景。

Redirect和Return View 的区别


1、 Redirect是让浏览器重定向到新的地址;Return View是让服务器把指定的cshtml的内容运行渲染后给到浏览器。
2、 Redirect浏览器和服务器之间发生了两次交互;Return View浏览器和服务器之间发生了1次交互。
3、 Redirect由于是两次请求,所以第一次设置的ViewBag等这些信息,在第二次是取不到;而View则是在同一个请求中,所以ViewBag信息可以取到。
4、如果用Redirect,则由于是新的对Controller/Action的请求,所以对应的Action会被执行到。如果用View,则是直接拿某个View去显示,对应的Action是不执行的。


什么情况用View?
服务器端产生数据,想让一个View去显示的;


什么情况用Redirect?
让浏览器去访问另外一个页面的时候。


RedirectToAction和Return View的区别

RedirectToAction()是让客户端重定向,是一个新的Http请求,所以无法读取ViewBag中的内容;
Return View()是一次服务器一次处理中的转移。


Redirect和RedirectToAction的区别

RedirectToAction是从一个Action调到另一个Action,在后台做跳转。
Response.Redirect是给返回前台返回应答,前台根据应答的url进行跳转。
一个是后台,一个是前台。


这是视图// Views/Team/Delete.cshtml - 删除确认页面 @model UserManagementSystem.Web.Models.ViewModels.TeamDeleteViewModel @{ ViewData["Title"] = $"删除队别 - {Model.Name}"; } <div class="container-fluid"> <div class="d-flex justify-content-between align-items-center mb-4"> <h2>@ViewData["Title"]</h2> <a asp-action="Index" class="btn btn-secondary"> <i class="bi bi-arrow-left"></i> 返回列表 </a> </div> @if (TempData["ErrorMessage"] != null) { <div class="alert alert-danger alert-dismissible fade show" role="alert"> @TempData["ErrorMessage"] <button type="button" class="btn-close" data-bs-dismiss="alert"></button> </div> } <div class="row"> <div class="col-md-8"> <div class="card border-danger"> <div class="card-header bg-danger text-white"> <h5 class="mb-0">删除确认</h5> </div> <div class="card-body"> <div class="alert alert-warning"> <h5><i class="bi bi-exclamation-triangle"></i> 警告:此操作不可撤销!</h5> <p>您即将永久删除以下队别信息,删除后将无法恢复。</p> </div> <h6>要删除的队别信息:</h6> <dl class="row"> <dt class="col-sm-3">@Html.DisplayNameFor(model => model.Name)</dt> <dd class="col-sm-9">@Html.DisplayFor(model => model.Name)</dd> <dt class="col-sm-3">@Html.DisplayNameFor(model => model.GroupName)</dt> <dd class="col-sm-9">@Html.DisplayFor(model => model.GroupName)</dd> <dt class="col-sm-3">@Html.DisplayNameFor(model => model.CmbName)</dt> <dd class="col-sm-9">@Html.DisplayFor(model => model.CmbName)</dd> <dt class="col-sm-3">@Html.DisplayNameFor(model => model.SortOrder)</dt> <dd class="col-sm-9">@Html.DisplayFor(model => model.SortOrder)</dd> </dl> <p class="text-danger"> <strong>重要提示:</strong> 删除此队别不会影响用户数据,因为队别目前不直接关联用户。 </p> </div> </div> </div> <div class="col-md-4"> <div class="card mb-4"> <div class="card-header bg-danger text-white"> <h5 class="mb-0">确认删除</h5> </div> <div class="card-body"> <p>请确认您要删除这个队别吗?</p> <form asp-action="Delete" method="post"> @Html.AntiForgeryToken() <input type="hidden" name="id" value="@Model.Id" /> <div class="d-grid gap-2"> <button type="submit" class="btn btn-lg btn-danger"> <i class="bi bi-trash-fill"></i> 确认删除 </button> <a asp-action="Details" asp-route-id="@Model.Id" class="btn btn-lg btn-secondary"> <i class="bi bi-x-circle"></i> 取消删除 </a> </div> </form> </div> </div> <div class="card"> <div class="card-header bg-secondary text-white"> <h5 class="mb-0">安全提示</h5> </div> <div class="card-body"> <ul class="list-unstyled"> <li class="mb-2"><i class="bi bi-shield-lock-fill text-success"></i> 删除操作需要二次确认</li> <li class="mb-2"><i class="bi bi-shield-lock-fill text-success"></i> 系统会记录操作日志</li> <li class="mb-2"><i class="bi bi-shield-lock-fill text-success"></i> 建议先备份重要数据</li> <li class="mb-2"><i class="bi bi-shield-lock-fill text-success"></i> 删除后可通过重新创建恢复</li> </ul> </div> </div> </div> </div> </div> 这是控制器// Controllers/TeamController.cs using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using System.Threading.Tasks; using UserManagementSystem.Web.Data; using UserManagementSystem.Web.Models; using UserManagementSystem.Web.Models.ViewModels; namespace UserManagementSystem.Web.Controllers { public class TeamController : Controller { private readonly ApplicationDbContext _context; public TeamController(ApplicationDbContext context) { _context = context; } [HttpGet] public async Task<IActionResult> Index(TeamListRequestModel request) { // 确保页码至少为1 request.PageNumber = Math.Max(1, request.PageNumber); var query = _context.Teams .Include(t => t.Group).ThenInclude(g => g.Cmb) .AsQueryable(); // 应用过滤条件 if (!string.IsNullOrEmpty(request.SearchTerm)) { query = query.Where(t => t.Name.Contains(request.SearchTerm)); } if (request.SelectedGroupId.HasValue) { query = query.Where(t => t.GroupId == request.SelectedGroupId.Value); } if (request.SelectedCmbId.HasValue) { query = query.Where(t => t.Group != null && t.Group.CmbId == request.SelectedCmbId.Value); } const int pageSize = 10; var totalItems = await query.CountAsync(); var totalPages = (int)Math.Ceiling(totalItems / (double)pageSize); var teams = await query .OrderBy(t => t.SortOrder) .ThenBy(t => t.Id) .Skip((request.PageNumber - 1) * pageSize) .Take(pageSize) .Select(t => new TeamListItemViewModel { Id = t.Id, Name = t.Name, GroupName = t.Group != null ? t.Group.Name : "未分配", CmbName = t.Group != null && t.Group.Cmb != null ? t.Group.Cmb.Name : "未知", SortOrder = t.SortOrder, GroupId = t.GroupId??0 }) .ToListAsync(); // ✅ 新增:传递所有组别(包含所属行政村名称)到视图 ViewBag.AllGroups = await _context.Groups .Include(g => g.Cmb) .Select(g => new GroupSelectViewModel { Id = g.Id, Name = g.Name, CmbName = g.Cmb != null ? g.Cmb.Name : "未知" // 或使用 ?. ?? 更简洁 }) .ToListAsync(); // ✅ 新增:传递所有行政村到视图 ViewBag.AllCmbs = await _context.Cmbs .Select(c => new { c.Id, c.Name }) .ToListAsync(); var viewModel = new TeamListViewModel { Teams = teams, PageNumber = request.PageNumber, TotalPages = totalPages, TotalItems = totalItems, SearchTerm = request.SearchTerm, SelectedGroupId = request.SelectedGroupId, SelectedCmbId = request.SelectedCmbId }; return View(viewModel); } [HttpGet("Details/{id}")] public async Task<IActionResult> Details(int id) { var team = await _context.Teams .Include(t => t.Group) .ThenInclude(g => g.Cmb) .FirstOrDefaultAsync(t => t.Id == id); if (team == null) { return NotFound(); } var viewModel = new TeamDetailViewModel { Id = team.Id, Name = team.Name, GroupName = team.Group?.Name ?? string.Empty, CmbName = team.Group?.Cmb?.Name ?? string.Empty, SortOrder = team.SortOrder }; return View(viewModel); } [HttpGet("Create")] public async Task<IActionResult> Create() { // ✅ 创建时也需要下拉框数据 ViewBag.AllGroups = await _context.Groups .Include(g => g.Cmb) .Select(g => new GroupSelectViewModel { Id = g.Id, Name = g.Name, CmbName = g.Cmb.Name }) .ToListAsync(); return View(new TeamEditViewModel()); } [HttpPost("Create")] [ValidateAntiForgeryToken] public async Task<IActionResult> Create(TeamEditViewModel model) { if (ModelState.IsValid) { var team = new Team { Name = model.Name, GroupId = model.GroupId, SortOrder = model.SortOrder }; _context.Teams.Add(team); await _context.SaveChangesAsync(); return RedirectToAction(nameof(Index)); } // 如果验证失败,重新加载下拉框数据 ViewBag.AllGroups = await _context.Groups .Include(g => g.Cmb) .Select(g => new GroupSelectViewModel { Id = g.Id, Name = g.Name, CmbName = g.Cmb.Name }) .ToListAsync(); return View(model); } [HttpGet("Edit/{id}")] public async Task<IActionResult> Edit(int id) { var team = await _context.Teams.FindAsync(id); if (team == null) { return NotFound(); } var model = new TeamEditViewModel { Id = team.Id, Name = team.Name, GroupId = team.GroupId ?? 0, SortOrder = team.SortOrder }; // ✅ 编辑时也需要下拉框数据 ViewBag.AllGroups = await _context.Groups .Include(g => g.Cmb) .Select(g => new GroupSelectViewModel { Id = g.Id, Name = g.Name, CmbName = g.Cmb.Name }) .ToListAsync(); return View(model); } [HttpPost("Edit/{id}")] [ValidateAntiForgeryToken] public async Task<IActionResult> Edit(int id, TeamEditViewModel model) { if (id != model.Id) { return NotFound(); } if (ModelState.IsValid) { var team = await _context.Teams.FindAsync(id); if (team == null) { return NotFound(); } team.Name = model.Name; team.GroupId = model.GroupId; team.SortOrder = model.SortOrder; try { _context.Update(team); await _context.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) { if (!TeamExists(team.Id)) { return NotFound(); } else { throw; } } return RedirectToAction(nameof(Index)); } // 验证失败时重新加载下拉框 ViewBag.AllGroups = await _context.Groups .Include(g => g.Cmb) .Select(g => new GroupSelectViewModel { Id = g.Id, Name = g.Name, CmbName = g.Cmb.Name }) .ToListAsync(); return View(model); } [HttpGet("Delete/{id}")] public async Task<IActionResult> Delete(int id) { var team = await _context.Teams .Include(t => t.Group) .ThenInclude(g => g.Cmb) .FirstOrDefaultAsync(t => t.Id == id); if (team == null) { return NotFound(); } var model = new TeamDeleteViewModel { Id = team.Id, Name = team.Name, GroupName = team.Group?.Name ?? string.Empty, CmbName = team.Group?.Cmb?.Name ?? string.Empty, SortOrder = team.SortOrder }; return View(model); } // POST: Team/Delete/5 [HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> Delete(int id) { var team = await _context.Teams.FindAsync(id); if (team == null) { TempData["ErrorMessage"] = "团队不存在或已被删除。"; return RedirectToAction(nameof(Index)); } _context.Teams.Remove(team); await _context.SaveChangesAsync(); TempData["SuccessMessage"] = $"团队 '{team.Name}' 已成功删除。"; return RedirectToAction(nameof(Index)); } private bool TeamExists(int id) { return _context.Teams.Any(e => e.Id == id); } } }
10-08
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值