Preventing redirecting from the start - grails

I'm experience some auto redirecting at the page when it first loaded.
These are my codes:
def editUser = {
if(params.account_expired != null )
{
String updateQuery = "UPDATE user SET expired='"+params.account_expired+"'"
def update = sql.executeUpdate(updateQuery)
redirect (action: listUser)
[update:update]
}
else
{
}
}
so what happen is, when the page got loaded, it auto redirect back to listuser page. This is actually an edituser page and I want it to stay there until the user clicks a button. And then redirect to listuser. Any idea guys?

It's common to use POST method to send update, and GET to show form (as it suggested by W3C, and used in Grails by default). So you can use:
def editUser = {
if (request.method == 'GET') {
render(view: 'editUser')
} else if (request.method == 'POST') {
//.... current code
}
}
by default Grails creates POST form, when you're using <g:form tag, but if you're using plain HTML tags, you should specify POST method as:
<form method="POST">
</form>

That's exactly what your code is supposed to do, because you have this executed:
redirect (action: listUser)
If you want it stay in editUser page, you should remove it. Then
[Query1:Query1]
will render editUser.gsp with this parameter passed.

Related

How to display message before redirecting to another page?

I have a problem... I have registration form and when user has registred it redirect him to Home page..i want to display popup message before redirecting him that he is successfuly registred and then redirect him to Home page.
Controller:
TempData["SuccessMessage"] = "A confirmation email will be sent to the address you've entered shortly";
return RedirectToAction("Index", "Home");
View:
<script>
if (#TempData["SuccessMessage"] != null)
{
alert('#TempData["SuccessMessage"]');
}
</script>
store redirect url Like this way
ViewBag.Redirect = "Your URL ";
And do java script mention below
<script>
if (#TempData["SuccessMessage"] != null)
{
alert('#TempData["SuccessMessage"]');
window.setTimeout(function () {
location.href = #ViewBag.Redirect;
}, 5000);
}
</script>
Add your script in the Layout view page instance of your view page, which allows you to send messages from any Controllers to all views using the same layout.
moreover, using Tempdata not viewbag because Tempdata allows you to keep data between controllers but viewbag will be cleared after redirecting to another controller.
<script>
if (#TempData["SuccessMessage"] != null)
{
alert('#TempData["SuccessMessage"]');
}
</script>

Grails 2.2.0 renders wrong page

I have a grails 2.2.0 application. I have created a global filter and that has some check. if the check fails then it renders a static view file using render view: viewFileName ending the flow else it returns true saying app can continue.
At login action, the action renders a login view calling render view: loginFileName but it displays the viewFileName instead. Note that filter pass has already passed by now and the check in it has passed too.
This issue seems similar to earlier post
Grails "respond" renders the wrong view when launched from .war file
but the difference is that there are two index view files of same name but in different controller but here we have filter rendering a view if some condition passes which gets displayed even if that condition fails.
To makes sure that this is an issue, i removed that render view: viewFileName in filter with render "< div>....< /div >" and then it worked all well i.e. action displayed the right page and not the static page.
I can post more detail if required. I cannot rely on that page that is in string to render as that will not be long term.
Here are the two classes with issue
class MainController {
def login() {
def param = getHeaderParameters()
render view: "login", model: param
}
}
class MainFilters {
private final String mainControllerName = "main"
private final String startPage = "start"
def GrailsConventionGroovyPageLocator groovyPageLocator
def filters = {
all(controller: '*', action: '*') {
before = {
if (AdminUtils.isStart(request)) {
println "rending start page...."
final fileView = "/$mainControllerName/$startPage"
render view: fileView
}
}
}
}
When you render a page and not redirecting it, your action will be called after the before check, if you not return false. For your scenario you don't want your action to be called so you need to return false after that.
def filters = {
all(controller: '*', action: '*') {
before = {
if (AdminUtils.isStart(request)) {
println "rending start page...."
final fileView = "/$mainControllerName/$startPage"
render view: fileView
return false
}
}
}
}

Grails 2.1.1: Redirect to /index.gsp not working with Filter defined

I have a Grails 2.1.1 application which runs fine, at least until I try to define a filter for all Controller to redirect to the index.gsp if user is not set in the session variable...
what ever I try, I'm not able to redirect to "/index", nor render "/index" when starting the server - if I remove the filter and redirect to "/index" from my AuthenticationController on false parameters, all works like charm...
so, here's what I have so far:
class AuthenticationFilters {
all(controller:'*', action'*') {
before = {
def user = (User) session.getValue("user")
if(user == null || !user.loginState) {
redirect(controller: 'authentication', action: 'index')
return false
}
}
}
}
class AuthenticationController {
def authenticationService
def index = {
render(view: '/index')
}
def login(LoginCommand cmd) {
if(cmd.hasErrors()) {
redirect(action: index)
return
}
}
....
}
now, if I comment out the all Filters definition, everything works well. I got the page (index.gsp) shown on start up and if the LoginCommand has errors, I'm redirected to the index.gsp page without any problems.
if I now comment in the all Filters definition, I get a 404.
I tried:
Grails: Redirect to index.gsp that is not in any controller
Upgrade to Grails 2.0: /index.gsp not found
Grails: what are the main issues (and his solutions) when deploying in weblogic?
but I didn't had any luck...
I'm developing on Intellij IDEA 11.1.4 Premium (evaluation)
EDIT: I tried to get the User object from the session property in my AuthenticationFilters class, surrounded by a try/catch block and now facing the problem that obviously the session property is not available? why?
try {
def user = (User) session.getValue("user")
if((user == null || !user.loginState)) {
...
}
} catch(Exception e) {
println("... couldn't get user from session! ${e.getMessage()}")
}
console output:
... couldn't get user from session! No such property: session for class: grailstest001.AuthenticationFilters
any suggestions on this?
So, just to add my experience here to close this question as solved and for further usage for other users:
to check if the user is entering the page for the first time, you could easily do this by checking for the controllerName field. It should be null or "" (empty String) if the user was not referred to the site by any controller.
Also, I'm not using any Database within my application for authentication because all of this issuses are backended by an API. So I created a UserService.groovy class which is acting as a SessionScopedBean and I store all my user related infos within this class.
So, your filter definition could look like:
class MyFilters {
def filters = {
before = {
if(!controllerName || controllerName.equals("")) {
redirect(controller:'home',action:'index')
}
if(!applicationContext.userService?.getUser() || !applicationContext.userService?.getUser.isLoggedIn) {
redirect(controller:'auth',action:'login')
}
}
}
}
Otherwise, if you don't want to redirect the user which 'freshly' entered your page from within your Filters.groovy class, you could use the UrlMappings.groovy class to do so. Just map your / (root) index to the page you want:
class UrlMappings {
static mappings = {
"/"(controller:'mycontroller',action:'myaction') // change it to your liking
"/$controller/$action?/$id?" {
constraints {
// apply constraints here
}
}
"500"(view:'/error')
}
}
I think your filter syntax may be incorrect - try
Class AuthenticationFilters {
def filters = { // <--- added this
all(controller:'*', action'*') {
before = {
def user = (User) session.getValue("user")
if(user == null || !user.loginState) {
redirect(controller: 'authentication', action: 'index')
return false
}
}
}
} // <-- added
}

Why does the previous page link appears in my address bar in MVC3 Razor application?

I am using MVC3/Razor. But I don't understand why the previous page url appears when i redirecToAction.
Scenario: Once the user clicks on Signup from home page like "Account/Signup", the he would get RedirectToAction("AcceptCondition") so once the use accepts the condition and post then the user would get RedirectToAction("Signup") where i will check if he is coming from "AcceptCondition" page then he can proceed otherwise user will go back to "AcceptCondition" page. So when I redirect user from Signup page to AcceptCondition page the url in the address bar appears like "http://localhost:55104/Account/Signup" instead of "http://localhost:55104/Account/AcceptCondition"
I know that i can send user directly to "Account/AcceptCondition" when he click on the signup but I just followed upper scenario.
public ActionResult Signup(string ru)
{
if ((ru == "/Account/AcceptCondition") || (ru == "/Account/Signup"))
{
return View();
}
else
{
return RedirectToAction("AcceptCondition");
}
}
[HttpGet]
public ActionResult AcceptCondition()
{
return View();
}
[HttpPost]
public ActionResult AcceptCondition(AcceptConditionViewModel acceptCondiViewModel)
{
if (acceptCondiViewModel.TermAndCondi == true)
{
return RedirectToAction("Signup",
"Account",
new { ru = "/Account/AcceptCondition" });
}
else
{
return View();
}
}
Signup GET checks refers, if not AcceptCondition, then redirects to AcceptCondition
IF it is AcceptCondition, then render the normal signup view.
AcceptCondition GET renders the AcceptCondition view
AcceptCondition POST does RedirectToAction("SIGNUP")
Signup POST creates the user (Assuming) then goes?
Sounds like the referrer check isn't right so /account/signup is rendered again?
Whats your code look like.
It appears that you are passing a parameter of 'returnUrl' in your first function, but reference it as 'ru' in both the function body and in your RedrectToAction call in the third function. Be sure you are staying consistent with your parameter names as this could be a cause of faulty logic and bad/not working redirects.

ASP.NET MVC Ajax post to Action requiring authentication returns login view when user session has timed out

I am using the Ajax.BeginForm to create a form the will do an ajax postback to a certain controller action and then the response view is inserted into the UpdateTargetId.
using (Ajax.BeginForm("Save", null,
new { userId = Model.UserId },
new AjaxOptions { UpdateTargetId = "UserForm" },
new { name = "SaveForm", id = "SaveForm" }))
{
[HTML SAVE BUTTON]
}
Everything works great except when the Users session has timed out and then they are redirected back to the login page. The login page then gets returned from the Ajax call because of the Authorize attribute and the html gets loaded into the UpdateTargetId and therefore I end up with the login page html within the user profile page (at the Target Id). My controller action looks like this:
[Authorize]
public ActionResult Save(Int32 UserId)
{
//code to save user
return View("UserInfoControl", m);
}
How can I solve this problem?
UPDATE (2011-10-20):
Found this post from Phil Haack about this exact issue - http://haacked.com/archive/2011/10/04/prevent-forms-authentication-login-page-redirect-when-you-donrsquot-want.aspx. I have not gotten a chance to digest or implement his solution yet.
I think that you can handle the authorization issue from inside the action.
First remove [Authorize], the use this code:
public ActionResult Save(Int32 UserId)
{
if (!User.Identity.IsAuthenticated)
{
throw new Exception();
}
//code to save user
return View("UserInfoControl", m);
}
Then you can put a OnFailure condition in your AjaxOptions and redirect your page or something.

Resources