Asp.Net MVC Core:如何从Request.Referrer返回视图及模型验证过滤器问题
在ASP.NET Core MVC中从Request.Referrer返回视图并完善模型验证过滤器
我来帮你梳理一下这两个问题的解决方案,都是日常开发里很实用的场景:
一、如何从Request.Referrer返回视图/页面
首先要明确:Request.Referrer对应的是HTTP请求头里的Referer(注意拼写少个r,这是HTTP标准写法),它记录了用户当前请求的来源URL。如果想回到这个来源页面,通常有两种处理方式:
1. 直接重定向到Referrer URL
如果只是想让浏览器跳回来源页面,用RedirectResult就可以,记得先判断Referrer是否为空(避免空值异常):
public IActionResult YourAction() { var referrerUrl = Request.Headers.Referer.ToString(); if (!string.IsNullOrEmpty(referrerUrl)) { return Redirect(referrerUrl); } // 没有Referrer时的兜底逻辑,比如跳转到首页 return RedirectToAction("Index", "Home"); }
2. 在过滤器中结合模型验证返回
这就关联到你第二个问题的模型验证过滤器了,下面详细说明具体实现。
二、完善你的ViewModelValidationActionFilterAttribute
你的过滤器已经实现了基础的模型验证逻辑,现在补全ViewResult的部分,同时结合回到Referrer的需求——这里要注意:如果直接重定向到Referrer,ModelState的错误会丢失,因为重定向是全新的请求,所以需要用TempData来暂存错误信息,之后在目标页面读取展示。
完整的过滤器代码如下:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)] public sealed class ViewModelValidationActionFilterAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext context) { // 模型验证通过就直接跳过后续逻辑 if (context.ModelState.IsValid) return; // 转换为Controller类型,方便操作ViewData和TempData var controller = context.Controller as Controller; if (controller == null) { // 非Controller场景直接返回BadRequest context.Result = new BadRequestObjectResult(context.ModelState); return; } // 获取来源URL var referrerUrl = context.HttpContext.Request.Headers.Referer.ToString(); if (!string.IsNullOrEmpty(referrerUrl)) { // 将模型错误存入TempData,重定向后可以读取展示 controller.TempData["ModelValidationErrors"] = context.ModelState; // 重定向到来源页面 context.Result = new RedirectResult(referrerUrl); } else { // 没有来源URL时,返回当前Action对应的视图,保留模型错误 var actionDescriptor = context.ActionDescriptor as ControllerActionDescriptor; var targetViewName = actionDescriptor?.ActionName; context.Result = new ViewResult { ViewName = targetViewName, ViewData = controller.ViewData, TempData = controller.TempData }; } } }
补充:在页面展示TempData中的错误
因为重定向后ModelState不会自动携带,所以需要在目标页面(比如来源页面的视图)里读取TempData的错误并展示:
@{ if (TempData["ModelValidationErrors"] is ModelStateDictionary modelErrors) { foreach (var error in modelErrors.Values.SelectMany(v => v.Errors)) { <div class="alert alert-danger">@error.ErrorMessage</div> } } }
额外注意事项
- 有些浏览器或请求场景不会携带
Referer头(比如直接输入URL、隐私模式下的请求),所以一定要写兜底逻辑,避免出现异常。 - 如果你的表单就在当前Action对应的视图里,其实不需要重定向,直接返回当前视图即可,这时候
ViewData里的ModelState会自动保留,页面可以用@Html.ValidationSummary()或@Html.ValidationMessageFor()直接显示错误。
内容的提问来源于stack exchange,提问作者Autyan
相关产品推荐
相关产品推荐

