Grails Tomcat blank page - grails

Hi I have deployed my grails webapp and I thought all was fine but it seems any GSP page that has not been requested from within the app just displays a black page on my deployed tomcat 7.
I can log in and use 90% of the functionality but not that page.
http:somewebsite.co.uk/app/invite/index
from within the webapp i can get to
http:somewebsite.co.uk/app/invite/index
but i cannot access this but just entering the URL within the browser.
This does however work in my IDE.
at the top of the controller i have.
static allowedMethods = [index: 'GET']
and i do not need to be logged in to access.
as anyone had and fixed this problem?
I have not preformed numerous test and the problem is something to do with this code:
def index() {
def em = params.email
if (em){
println("params.email : " + em)
if (User.findByEmail(em)){
redirect controller:"public", action:"index"
}
}
[email: em]
}

The error was in the index.gsp page, i use layouts and the name was set to oneBlock, instead of oneblock.

Related

ASP.NET Core 3.1 MVC Routing issue with IIS Default Web Site

New information:
After much messing around with trying to manipulate the URL I almost got it working but not quite. Then I discovered that it works without any coding changes if my home page url is \\localhost\ABIAdmin\Home. But it starts as \\localhost\ABIAdmin, and I have link in my _Layout to bring me there and it also comes up as \\localhost\ABIAdmin (without the \Home). It's easy enough to require our users to provide the full url with home in it, but I need the link to also provide \Home in it. Here's the html for the Home link:
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Dashboard</a>
So now the question is how do I get \Home in the url from the link, and if possible on startup? Can this be addressed through IIS, or through my endpoints?
I have an ASP.NET Core 3.1 MVC application with Razor Pages which works fine when I deploy it to IIS if I do not use the Default Web Site, or if I run the application as an exe. All of my navigation works, and all of my CRUD operations work (I'm using Syncfusion's DataGrid). However, if I deploy to the Default Web Site I run into what seem to be routing issues. Please note the following:
I added a folder under c:\inetpub\wwwroot called ABIAdmin, which contains my core app.
Relevant code from Startup/ConfigureServices: services.AddControllersWithViews();
Relevant code from Startup/Configure:
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseCookiePolicy();
app.UseSession();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
endpoints.MapControllerRoute(
name: "Privacy",
pattern: "{controller=Privacy}/{action=Privacy}/{id?}");
});
I have about 80 controllers not including the Privacy and Home controllers. There is no routing information in any of the controllers.
I tried messing with adding virtual directories but that did not help.
When I navigate to the Campaigns page from the Privacy page it forms a proper URL, e.g., http://localhost:5000/ABIAdmin/Campaigns, where ABIAdmin is the name of the site under the Default Web Site. But if I navigate from the Home page I get a 404 error. The requested URL is formed as http://localhost:5000/Campaigns, but it is missing the "/ABIAdmin", and the physical path is wrong too: C:\inetpub\wwwroot\Campaigns. When I successfully navigate from the Privacy page, the data is retrieved, but if I try to perform an Add/Update/Delete operation it just hangs. I believe this is because whatever URL the grid is forming is wrong. I don't think this is the fault of the Syncfusion grid.
So the question is, why does the Default Web Site behave differently then a standalone web site in this situation? We will be deploying this to multiple customers, and some will want it under the Default Web Site.
Any help would be appreciated. :)
It's looks like I found an answer. I have 3 scenarios to handle, running from VS, running from a standalone website, and running from an application under the Default Web Site. I could not figure out a way to tell in my _Layout.cshtml whether it is running under the Default Web Site so I'm using a configuration parameter to tell me that. I can tell whether I'm running from VS by the name of the application pool (from VS it's "ABIAdminApp AppPool"). I can also tell if I'm coming from the Home page now (that was the missing link), by checking Context.Request.Path. Given that info I can conditionally add the name of my application, ABIAdminApp. Note in the original post I may have referred to this as ABIAdmin. I will consider making the name of the app a configuration parameter as well.
#{
#using ABIAdminApp.Classes;
#using Microsoft.Extensions.Configuration;
#inject IConfiguration Configuration;
string appPoolId = System.Environment.GetEnvironmentVariable("APP_POOL_ID");
string appName = "";
if (appPoolId != "ABIAdminApp AppPool" && Context.Request.Path.ToString() == "" && Extensions.UseDefaultWebsite(Configuration)) { appName = "ABIAdminApp" + "/"; } else { appName = ""; }
string anchor_template = "<a href='" + appName + "${URL}'>${FriendlyName}</a>";
}
So that solves my navigation problems. I also had to make changes for the Syncfusion grid updates. I had to conditionally add the app name and used ViewBag for that purpose with dynamic values for insertUrl, updateUrl, and removeUrl.
So in my Index method of the controller for Campaigns I had this code (preceded by logic to determine whether or not to add the app name):
ViewBag.InsertUrl = AppName + "/Campaigns/Insert";
ViewBag.UpdateUrl = AppName + "/Campaigns/Update";
ViewBag.RemoveUrl = AppName + "/Campaigns/Delete";
And this code in my view, Campaigns.cshtml:
<e-data-manager url="Campaigns/Campaigns" adaptor="UrlAdaptor" insertUrl="#ViewBag.InsertUrl" updateUrl="#ViewBag.UpdateUrl" removeUrl="#ViewBag.RemoveUrl"></e-data-manager>

MVC url routes not working after deployment on IIS

I have a MVC app that works just fine on local, but when deployed on IIS all the routes return 404 not found.
My browser shows me in some cases the layout but doesn't bring the data for that view and instead of that returns 404.
I will show you a method that works fine on local but in IIS fails.
[Route("/Customer/CustomerDetails/{id}")]
public async Task<IActionResult> CustomerDetails(int id)
{
ApiResult<eCOM_Backend.Api.Responses.Customer> apiResult = await _customerApiMethods.CustomerDetailsAsync(id);
eCOM_Backend.Api.Responses.Customer customerFromBackend = null;
if (!apiResult.HasException)
{
customerFromBackend = apiResult.Result;
}
else
{
return RedirectToAction("Error", "Error", new { reason = apiResult.Exception });
}
CustomerViewModel customer = customerFromBackend.ToCustomerViewModel();
return View(customer);
}
When I call this method like: xxx/Customer/CustomerDetails/123 i get page not found.
I have tried lots of solutions(modified the appsettings.json, web.config etc.) but nothing worked so far.
Thanks a lot!
Looks like this is dotnet core. Make sure to provide correct physical path when you publish your app to IIS. Like inetpub\wwwroot\YourAppName. In IIS right click on your web app >Manage Website>Advanced Settings and make sure physical path ends on your app folder not yourApp\someOtherFolder

MVC .NET site inks not pointing correctly to the base URL

I have developed and tested a site on an IIS server at an IP address. Everything was and is working perfectly if I use the IP address in the URL. However for production, the client wanted a friendly domain URL. In other words https://www.IPAddress.com is supposed to point to my default MVC login page at https://www.example.com/department/Account/Login. The client's network team set it all up and most of the links work fine.
However, in some other places the "/department" is not getting appended to the URL, and the link goes to https://www.example.com/Action/Controller (instead of https:www.example.com/department/Action/Controller).
What I discovered so far is that #Html.ActionLinks in Views are pointing correctly.
So this works: #Html.ActionLink("Create a login!", "Register").
It correctly points to the URL https://www.example.com/department/Account/Register.
But this does not (in controller code):
if (await UserManager.IsInRoleAsync(user.Id.ToString(), "Admin"))
{
return RedirectToAction("Dashboard", "Admin"
);
}
if (await UserManager.IsInRoleAsync(user.Id.ToString(), "User"))
{
return RedirectToAction("Dashboard", "User");
}
The code posts incorrectlyto https://www.example.com/Admin/Dashboard, instead of https://www.example.com/department/Admin/Dashboard
Does this have to do with something the network folks have not done. Or is there a place I can set the base URL in my webconfig file?
Thanks in advance,
Sanjeev

Grails/JQuery mobile view not displayed after login

Using Grails 2.4.3 and Spring Security plugin :spring-security-core:2.0-RC4
The default login view auth.gsp is working fine.
Added a user and can login, logout
and view secured pages.
Then I added JQuery mobile files to my layout and view.
I copied auth.gsp to /views/login/auth.gsp pastebin
My /views/layouts/main.gsp layout looks like this pastebin
My login page looks like this:
When I login with invalid credentials I get a blank page.
The source of the page before and after submit is exactly the same. pastebin
If I remove <script src="http://code.jquery.com/mobile/1.4.4/jquery.mobile-1.4.4.min.js"></script>
from main.gsp then I do see the output after submit.
Hope someone knows what I'm doing wrong.
UPDATE
In plugin/springsecurity/LoginController.groovy there is
def authfail() {
// ....
if (springSecurityService.isAjax(request)) {
render([error: msg] as JSON)
}
else {
flash.message = msg
redirect action: 'auth', params: params
}
}
If I change this to:
def authfail() {
// ...
flash.message = msg
redirect action: 'auth', params: params
}
then it is working and I see the login view again.
What still does not work is the redirection after successful login. Stil see a blank page.
Found that the answer on Spring Security Refresh Error in Grails jQuery Mobile app solves mine as well
Need to add data-ajax="false" and then it works.

Redirection in Grails Web-flow

I have question regarding redirection in Grails web-flow.
I am in a view state which will allow users to enter the answers for a question. On 2 wrong attempts I should be able to re-direct the user to view page from different controller. What i mean is
challengeQuestionOne{
onRender() {
//Display question
}
on('next') {BuildQuestion command ->
bindData(flow.recovery,command)
[return the model to flow]
if(command.hasErrors()) {
flow.command = command
return error()
}
if(check for status. If doesnot pass){
flash.message=message(code:'loginForm.account.locked', default: 'Please Contact Admin.')
redirect(controller : "login",action: "login")//how to redirect from here to diff controller
}
if (//compare answer entered) {
}
else{
//set status not active
}
}.to("challengeQuestionTwo")
on(Exception).to("error")
on('cancel').to('finish')
}
I have tried to redirect from onRender . It was redirecting to the page. But how do I display the error msg on the redirected page. How can i forward the error message from one controller to other??
Ivo Houbrechts wrote an excelent tutorial about grails webflow:
Webflow defines its own flash scope. Although it has the same semantics as the standard grails flash scope (the main purpose is to store objects only until after the next request), it is a different scope. This means that objects stored in webflow's flash scope are not visible in standard grails actions.
import org.springframework.web.context.request.RequestContextHolder
....
RequestContextHolder.currentRequestAttributes().flashScope.message = "YourMessage"
You can read more here:
http://livesnippets.cloudfoundry.com/docs/guide/
Flash scope will not work in this case as expected.
Try to use another approach to show error. E.g. you can pass parameters with redirect. Or you can throw some exception and check it on rendered page as follow:
<g:if test="${flowExecutionException}">
<div class="error"><g:message code="loginForm.account.locked"/></div>
</g:if>

Resources