从ASP.NET MVC 5迁移到ASP.NET Core时RedirectToAction问题排查
问题:ASP.NET Core中RedirectToAction传递RouteValues后在ActionFilter中获取为null的问题
我正在从ASP.NET MVC 5迁移到ASP.NET Core,遇到了RedirectToAction的使用问题。我将RouteValues设置为new { Test = "Hello World" },但当请求进入我的ActionFilterAttribute时,ActionExecutingContext.RouteData.Values["Test"]的值为null。请问我遗漏了什么?
相关代码
应用启动配置
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ClarityUserManager userManager, SignInManager<ClarityUser> signInManager) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseStaticFiles(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseSession(); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); }); AppDomain.CurrentDomain.SetData("ContentRootPath", env.ContentRootPath); AppDomain.CurrentDomain.SetData("WebRootPath", env.WebRootPath); }
控制器代码
public class SomeController : Controller { [HttpPost] public ActionResult Something() { return RedirectToAction("Index", "Home", new { Test = "Hello World" }); } }
ActionFilter代码
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)] public class SessionExpireAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { var test = filterContext?.ActionDescriptor?.RouteValues["Test"]; // test is null var test2 = filterContext.RouteData.Values["Test"]; // test2 is also null } }
Home控制器代码
public class HomeController : Controller { public HomeController() { } // // GET: /Home/ [SessionExpire] public ActionResult Index() { // } }
原因分析
你的默认路由模板{controller=Home}/{action=Index}/{id?}中没有定义Test这个路由参数,所以调用RedirectToAction时,Test不会被解析到路由值(RouteData.Values)中,而是会被自动拼接成URL的查询字符串(比如/Home/Index?Test=Hello%20World)。因此在ActionFilter中从RouteData.Values无法获取到该值。
解决方案
方案1:修改路由模板,添加Test参数(将Test作为路由段)
如果需要把Test作为路由的一部分,修改启动配置中的路由模板,增加可选的Test参数:
app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}/{Test?}"); });
修改后,RedirectToAction生成的URL会变成/Home/Index/Hello%20World(或对应格式),此时filterContext.RouteData.Values["Test"]就能获取到值。
方案2:从QueryString中获取参数(更推荐,无需修改路由)
如果不需要将Test作为路由段,直接从请求的查询字符串中获取值即可,这也是更常用的做法:
public override void OnActionExecuting(ActionExecutingContext filterContext) { var test = filterContext.HttpContext.Request.Query["Test"].ToString(); // test 会是 "Hello World" }
内容的提问来源于stack exchange,提问作者Alexandre Severino
相关产品推荐
相关产品推荐

