ASP.NET Core MVC 共用CheckOut Action实现动态重定向回来源页面
CheckOut方法实现返回原触发页面的方案
问题根因
当前CheckOut方法把重定向地址硬编码为/dogprofile,没有获取提交来源页面的路径信息,因此无论操作从哪个视图触发,最终都会跳转到固定地址。
核心实现逻辑
通过表单传递当前页面的本地路径,Controller接收路径参数后做安全校验,优先重定向回来源页面,校验失败则兜底走原有固定跳转逻辑,完全兼容现有功能。
具体代码修改
视图端调整
在所有触发CheckOut操作的视图表单(包含/DogProfile列表页、/DogProfile/Profile详情页)内部,新增一个隐藏域,自动读取当前页面的路径:
<form asp-controller="DogProfile" asp-action="CheckOut" method="post"> <select name="activity" id="activity"> <option value="walk">Walk</option> <option value="furlough">Furlough</option> <option value="bathe">Bathe</option> </select> <br /> <input type="submit" value="Check Out" /> <input type="hidden" name="dogID" value="@Model.Id" /> <!-- 新增:传递当前页面路径的隐藏域 --> <input type="hidden" name="returnUrl" value="@Context.Request.Path" /> </form>
- 该隐藏域无需手动写死路径值,会自动匹配当前页面的实际路径:在
/DogProfile页面时值为/DogProfile,在/DogProfile/Profile页面时值为/DogProfile/Profile。
Controller端调整
修改CheckOut方法的参数定义,增加动态重定向逻辑,保留原有默认跳转的兼容性:
public IActionResult CheckOut(string activity, int dogID, string returnUrl = "/dogprofile") { var status = context.Dogs.Find(dogID); if (status == null) { return Redirect("/dogprofile"); } status.CheckedOut = true; status.Activity = activity; status.TimeCheckOut = DateTime.Now; context.SaveChanges(); // 校验路径为本地路径,避免开放重定向的安全风险 if (!Url.IsLocalUrl(returnUrl)) { returnUrl = "/dogprofile"; } return Redirect(returnUrl); }
兼容与安全说明
- 给
returnUrl设置默认值/dogprofile,即使有旧的CheckOut触发源没有加隐藏域,也会保持原有的跳转逻辑,不会出现参数缺失报错。 - 新增的
Url.IsLocalUrl校验可以过滤非本地路径的恶意参数,避免被利用做钓鱼跳转。
内容的提问来源于stack exchange,提问作者Allison Howard
相关产品推荐
相关产品推荐

