How to pass route data from an ActionFilterAttribute to an action method?
I'm routing users to a login-view if the session has expired, using an ActionFilterAttribute
, like shown below.
Now, I want to keep the route data from the original request, so that I can route the user back to that view after logging in.
How can I send the original route data to the Login
action method?
public class BaseController : Controller
{
public int? BranchId {get => HttpContext.Session.GetInt32("BranchId") as int?;}
public string Admin {get => HttpContext.Session.GetString("Admin") as string;}
public BaseController() {}
}
public class AdminOrBranchesAccessAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
base.OnActionExecuting(context);
if ((context.Controller as BaseController).Admin == null &&
(context.Controller as BaseController).BranchId == null)
{
context.Result = new RedirectToRouteResult(new RouteValueDictionary(new
{
controller = "Home",
action = "Login"
}));
}
}
}
[AdminOrBranchesAccess]
public async Task<IActionResult> Details(int? id)
{
// Some stuff going on
return View();
}
c# asp.net-core-mvc
add a comment |
I'm routing users to a login-view if the session has expired, using an ActionFilterAttribute
, like shown below.
Now, I want to keep the route data from the original request, so that I can route the user back to that view after logging in.
How can I send the original route data to the Login
action method?
public class BaseController : Controller
{
public int? BranchId {get => HttpContext.Session.GetInt32("BranchId") as int?;}
public string Admin {get => HttpContext.Session.GetString("Admin") as string;}
public BaseController() {}
}
public class AdminOrBranchesAccessAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
base.OnActionExecuting(context);
if ((context.Controller as BaseController).Admin == null &&
(context.Controller as BaseController).BranchId == null)
{
context.Result = new RedirectToRouteResult(new RouteValueDictionary(new
{
controller = "Home",
action = "Login"
}));
}
}
}
[AdminOrBranchesAccess]
public async Task<IActionResult> Details(int? id)
{
// Some stuff going on
return View();
}
c# asp.net-core-mvc
1
If you're going to use a redirect, then you either have to store that data in session or return it to the client and have the client send it back on the next request. This is an HTTP restriction, not an MVC restriction.
– Kenneth K.
Jan 2 at 21:10
@KennethK. How would I store it in session? Is there some way to do it in one place for the whole application, or do I have to do it in each of my controller methods? I don't have access toHttpContext
in theOnActionExecuting
-class.
– Stian
Jan 2 at 22:04
add a comment |
I'm routing users to a login-view if the session has expired, using an ActionFilterAttribute
, like shown below.
Now, I want to keep the route data from the original request, so that I can route the user back to that view after logging in.
How can I send the original route data to the Login
action method?
public class BaseController : Controller
{
public int? BranchId {get => HttpContext.Session.GetInt32("BranchId") as int?;}
public string Admin {get => HttpContext.Session.GetString("Admin") as string;}
public BaseController() {}
}
public class AdminOrBranchesAccessAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
base.OnActionExecuting(context);
if ((context.Controller as BaseController).Admin == null &&
(context.Controller as BaseController).BranchId == null)
{
context.Result = new RedirectToRouteResult(new RouteValueDictionary(new
{
controller = "Home",
action = "Login"
}));
}
}
}
[AdminOrBranchesAccess]
public async Task<IActionResult> Details(int? id)
{
// Some stuff going on
return View();
}
c# asp.net-core-mvc
I'm routing users to a login-view if the session has expired, using an ActionFilterAttribute
, like shown below.
Now, I want to keep the route data from the original request, so that I can route the user back to that view after logging in.
How can I send the original route data to the Login
action method?
public class BaseController : Controller
{
public int? BranchId {get => HttpContext.Session.GetInt32("BranchId") as int?;}
public string Admin {get => HttpContext.Session.GetString("Admin") as string;}
public BaseController() {}
}
public class AdminOrBranchesAccessAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
base.OnActionExecuting(context);
if ((context.Controller as BaseController).Admin == null &&
(context.Controller as BaseController).BranchId == null)
{
context.Result = new RedirectToRouteResult(new RouteValueDictionary(new
{
controller = "Home",
action = "Login"
}));
}
}
}
[AdminOrBranchesAccess]
public async Task<IActionResult> Details(int? id)
{
// Some stuff going on
return View();
}
c# asp.net-core-mvc
c# asp.net-core-mvc
asked Jan 2 at 21:07
StianStian
364418
364418
1
If you're going to use a redirect, then you either have to store that data in session or return it to the client and have the client send it back on the next request. This is an HTTP restriction, not an MVC restriction.
– Kenneth K.
Jan 2 at 21:10
@KennethK. How would I store it in session? Is there some way to do it in one place for the whole application, or do I have to do it in each of my controller methods? I don't have access toHttpContext
in theOnActionExecuting
-class.
– Stian
Jan 2 at 22:04
add a comment |
1
If you're going to use a redirect, then you either have to store that data in session or return it to the client and have the client send it back on the next request. This is an HTTP restriction, not an MVC restriction.
– Kenneth K.
Jan 2 at 21:10
@KennethK. How would I store it in session? Is there some way to do it in one place for the whole application, or do I have to do it in each of my controller methods? I don't have access toHttpContext
in theOnActionExecuting
-class.
– Stian
Jan 2 at 22:04
1
1
If you're going to use a redirect, then you either have to store that data in session or return it to the client and have the client send it back on the next request. This is an HTTP restriction, not an MVC restriction.
– Kenneth K.
Jan 2 at 21:10
If you're going to use a redirect, then you either have to store that data in session or return it to the client and have the client send it back on the next request. This is an HTTP restriction, not an MVC restriction.
– Kenneth K.
Jan 2 at 21:10
@KennethK. How would I store it in session? Is there some way to do it in one place for the whole application, or do I have to do it in each of my controller methods? I don't have access to
HttpContext
in the OnActionExecuting
-class.– Stian
Jan 2 at 22:04
@KennethK. How would I store it in session? Is there some way to do it in one place for the whole application, or do I have to do it in each of my controller methods? I don't have access to
HttpContext
in the OnActionExecuting
-class.– Stian
Jan 2 at 22:04
add a comment |
1 Answer
1
active
oldest
votes
For rediecting to previous action after login successfully, you need to provide return url for login action and set its value in OnActionExecuting
.
Change
Login
method like below with parameterreturnUrl
[HttpGet]
[AllowAnonymous]
public async Task<IActionResult> Login(string returnUrl = null)
{
// Clear the existing external cookie to ensure a clean login process
await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);
ViewData["ReturnUrl"] = returnUrl;
return View();
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
{
ViewData["ReturnUrl"] = returnUrl;
if (ModelState.IsValid)
{
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, set lockoutOnFailure: true
var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure: true);
if (result.Succeeded)
{
_logger.LogInformation("User logged in.");
return RedirectToLocal(returnUrl);
}
if (result.RequiresTwoFactor)
{
return RedirectToAction(nameof(LoginWith2fa), new { returnUrl, model.RememberMe });
}
if (result.IsLockedOut)
{
_logger.LogWarning("User account locked out.");
return RedirectToAction(nameof(Lockout));
}
else
{
ModelState.AddModelError(string.Empty, "Invalid login attempt.");
return View(model);
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
AdminOrBranchesAccessAttribute
public class AdminOrBranchesAccessAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
base.OnActionExecuting(context);
if ((context.Controller as BaseController).Admin == null &&
(context.Controller as BaseController).BranchId == null)
{
context.Result = new RedirectToRouteResult(new RouteValueDictionary(new
{
controller = "Home",
action = "Login",
returnUrl = context.HttpContext.Request.Path
}));
}
}
}
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54013200%2fhow-to-pass-route-data-from-an-actionfilterattribute-to-an-action-method%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
For rediecting to previous action after login successfully, you need to provide return url for login action and set its value in OnActionExecuting
.
Change
Login
method like below with parameterreturnUrl
[HttpGet]
[AllowAnonymous]
public async Task<IActionResult> Login(string returnUrl = null)
{
// Clear the existing external cookie to ensure a clean login process
await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);
ViewData["ReturnUrl"] = returnUrl;
return View();
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
{
ViewData["ReturnUrl"] = returnUrl;
if (ModelState.IsValid)
{
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, set lockoutOnFailure: true
var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure: true);
if (result.Succeeded)
{
_logger.LogInformation("User logged in.");
return RedirectToLocal(returnUrl);
}
if (result.RequiresTwoFactor)
{
return RedirectToAction(nameof(LoginWith2fa), new { returnUrl, model.RememberMe });
}
if (result.IsLockedOut)
{
_logger.LogWarning("User account locked out.");
return RedirectToAction(nameof(Lockout));
}
else
{
ModelState.AddModelError(string.Empty, "Invalid login attempt.");
return View(model);
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
AdminOrBranchesAccessAttribute
public class AdminOrBranchesAccessAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
base.OnActionExecuting(context);
if ((context.Controller as BaseController).Admin == null &&
(context.Controller as BaseController).BranchId == null)
{
context.Result = new RedirectToRouteResult(new RouteValueDictionary(new
{
controller = "Home",
action = "Login",
returnUrl = context.HttpContext.Request.Path
}));
}
}
}
add a comment |
For rediecting to previous action after login successfully, you need to provide return url for login action and set its value in OnActionExecuting
.
Change
Login
method like below with parameterreturnUrl
[HttpGet]
[AllowAnonymous]
public async Task<IActionResult> Login(string returnUrl = null)
{
// Clear the existing external cookie to ensure a clean login process
await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);
ViewData["ReturnUrl"] = returnUrl;
return View();
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
{
ViewData["ReturnUrl"] = returnUrl;
if (ModelState.IsValid)
{
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, set lockoutOnFailure: true
var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure: true);
if (result.Succeeded)
{
_logger.LogInformation("User logged in.");
return RedirectToLocal(returnUrl);
}
if (result.RequiresTwoFactor)
{
return RedirectToAction(nameof(LoginWith2fa), new { returnUrl, model.RememberMe });
}
if (result.IsLockedOut)
{
_logger.LogWarning("User account locked out.");
return RedirectToAction(nameof(Lockout));
}
else
{
ModelState.AddModelError(string.Empty, "Invalid login attempt.");
return View(model);
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
AdminOrBranchesAccessAttribute
public class AdminOrBranchesAccessAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
base.OnActionExecuting(context);
if ((context.Controller as BaseController).Admin == null &&
(context.Controller as BaseController).BranchId == null)
{
context.Result = new RedirectToRouteResult(new RouteValueDictionary(new
{
controller = "Home",
action = "Login",
returnUrl = context.HttpContext.Request.Path
}));
}
}
}
add a comment |
For rediecting to previous action after login successfully, you need to provide return url for login action and set its value in OnActionExecuting
.
Change
Login
method like below with parameterreturnUrl
[HttpGet]
[AllowAnonymous]
public async Task<IActionResult> Login(string returnUrl = null)
{
// Clear the existing external cookie to ensure a clean login process
await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);
ViewData["ReturnUrl"] = returnUrl;
return View();
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
{
ViewData["ReturnUrl"] = returnUrl;
if (ModelState.IsValid)
{
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, set lockoutOnFailure: true
var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure: true);
if (result.Succeeded)
{
_logger.LogInformation("User logged in.");
return RedirectToLocal(returnUrl);
}
if (result.RequiresTwoFactor)
{
return RedirectToAction(nameof(LoginWith2fa), new { returnUrl, model.RememberMe });
}
if (result.IsLockedOut)
{
_logger.LogWarning("User account locked out.");
return RedirectToAction(nameof(Lockout));
}
else
{
ModelState.AddModelError(string.Empty, "Invalid login attempt.");
return View(model);
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
AdminOrBranchesAccessAttribute
public class AdminOrBranchesAccessAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
base.OnActionExecuting(context);
if ((context.Controller as BaseController).Admin == null &&
(context.Controller as BaseController).BranchId == null)
{
context.Result = new RedirectToRouteResult(new RouteValueDictionary(new
{
controller = "Home",
action = "Login",
returnUrl = context.HttpContext.Request.Path
}));
}
}
}
For rediecting to previous action after login successfully, you need to provide return url for login action and set its value in OnActionExecuting
.
Change
Login
method like below with parameterreturnUrl
[HttpGet]
[AllowAnonymous]
public async Task<IActionResult> Login(string returnUrl = null)
{
// Clear the existing external cookie to ensure a clean login process
await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);
ViewData["ReturnUrl"] = returnUrl;
return View();
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
{
ViewData["ReturnUrl"] = returnUrl;
if (ModelState.IsValid)
{
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, set lockoutOnFailure: true
var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure: true);
if (result.Succeeded)
{
_logger.LogInformation("User logged in.");
return RedirectToLocal(returnUrl);
}
if (result.RequiresTwoFactor)
{
return RedirectToAction(nameof(LoginWith2fa), new { returnUrl, model.RememberMe });
}
if (result.IsLockedOut)
{
_logger.LogWarning("User account locked out.");
return RedirectToAction(nameof(Lockout));
}
else
{
ModelState.AddModelError(string.Empty, "Invalid login attempt.");
return View(model);
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
AdminOrBranchesAccessAttribute
public class AdminOrBranchesAccessAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
base.OnActionExecuting(context);
if ((context.Controller as BaseController).Admin == null &&
(context.Controller as BaseController).BranchId == null)
{
context.Result = new RedirectToRouteResult(new RouteValueDictionary(new
{
controller = "Home",
action = "Login",
returnUrl = context.HttpContext.Request.Path
}));
}
}
}
edited Jan 3 at 5:42
answered Jan 3 at 5:31
Tao ZhouTao Zhou
7,23931333
7,23931333
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54013200%2fhow-to-pass-route-data-from-an-actionfilterattribute-to-an-action-method%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
If you're going to use a redirect, then you either have to store that data in session or return it to the client and have the client send it back on the next request. This is an HTTP restriction, not an MVC restriction.
– Kenneth K.
Jan 2 at 21:10
@KennethK. How would I store it in session? Is there some way to do it in one place for the whole application, or do I have to do it in each of my controller methods? I don't have access to
HttpContext
in theOnActionExecuting
-class.– Stian
Jan 2 at 22:04