Redirecting page from Thymeleaf template - thymeleaf

How to redirect the page from Thymeleaf (I have JSP code like below)
out.println("REDIRECT=http://www.example.com/api/response?id="+id)
What is the equivalent in Thymeleaf? I want to do it from the template.

Thymeleaf doesn't provide any mechanism for redirecting to another page from one of its templates -- and I wouldn't recommend doing it anyways (since this is something that should probably be handled at the controller level).
That being said, it's possible to do this using javascript. Something like this:
<script th:inline="javascript">
window.location.href = 'http://www.example.com/api/response?id=' + [[${id}]];
</script>
Or possibly the meta refresh tag.
<meta http-equiv="refresh" th:attr="content=${'5; url=http://example.com/api/response?id=' + id}" />

Related

Inline Redirect in MVC 5

We're in the process of updating an MVC application. Currently, we cannot change any of the backend code and need to do an inline redirect on the razor page. How can I do a redirect to a URL directly in a razor page?
One possibility is to use the Redirect method:
#{
Response.Redirect("http://google.com");
}
or if you wanted to redirect to a controller action in the same application:
#{
Response.Redirect(Url.Action("SomeAction", "SomeController"));
}
This will perform the redirect on the server by returning the 302 status code. If you want to make the redirect on the client you could either use the meta tag in the head section of the DOM:
<meta http-equiv="refresh" content="0;URL=http://google.com">
or plain javascript:
<script>
window.location = 'http://google.com';
</script>

Angular.js in ASP.Net MVC -- need to reload page twice

I minimized the problem to this simple reproduction. Create new Asp.net MVC app, add Angular.js via nugget.
_Layout.cshtml:
<head>
<!-- Other stuff -->
#RenderSection("JavascriptInHead", required: false)
</head>
_Index.cshtml
#section JavascriptInHead {
<script src="~/Scripts/angular.min.js"></script>
}
<div ng-app>
{{2 + 2}}
</div>
So this works (obviously), however when I click, say About or Contact menu to reload another view and then go back to Home, I get
{{2 + 2}}
Then I click page reload two times and I get
4
Please help me understand this..
Angular bootstraps when the document loads. So if you are loading html that contains angular into your page without doing a full page refresh, you'll need to bootstrap angular manually. Try adding this script to your partial page:
angular.element(document).ready(function() {
angular.bootstrap(document);
});
btw, I for one appreciate you posting a concise example rather than 100 lines of code from your actual project. If your actual project has an app name, however, like this...
<div ng-app="myApp">
then the js you put into your partial page should look like this...
angular.element(document).ready(function() {
angular.bootstrap(document, ['myApp']);
});
Documentation for manually bootstrapping Angular can be found here: https://docs.angularjs.org/guide/bootstrap

jQuery Mobile ajax links not working properly in ASP.NET MVC application

I have a master layout looking somehow like this
<html>
<head>
...
</head>
<body>
<section data-role="page" data-theme="d">
<section data-role="content">
#RenderBody()
</section>
...
#Scripts.Render("~/bundles/jquery.mobile")
</section>
</body>
</html>
And I have a couple of controllers and templates pushing some code into content section of master layout.
When i click on a link:
Some order
the ajax loader is shown, the url changes, but all I see is the broken markup of the original page. If I inspect the code I will see that there are two page sections in the DOM (which means that the target page is successfully injected but isn't shown).
If I refresh page I will see the target page.
So what's wrong? Why can't I get the fancy JQM page transitions? thank you.
Add the data-ajax='false' on the links who were responsible for redirect you to another page.
JQuery Mobile uses AJAX navigation unless you tell it otherwise. The ASP.NET redirects have no problem to normal requests, but cause issues with AJAX. So my answer in this case is to turn off AJAX. For that, all you have to do is add the attribute data-ajax='false' to the tag.
In my case, an easy solution could be (as changing each Html.ActionLink/Url.Action is time consuming), adding this at the end of the _Layout.cshtml (just before closing of the 'body' tag).
$(document).on('pageinit', function() {
$('a').each(function() {
$(this).attr("data-ajax", "false");
});
});
That would be fine assuming you don't want jQuery mobile to use any Ajax with links too.
You can go ahead and use Ajax in most circumstances and only turn it off selectively where it can cause a problem.

Redirect from an MVC view

Does anyone know the syntax for a redirect from a view to another view?
I mean, I need to add the redirect code in the actual view, not the controller.
You cannot do this directly in the view with MVC code. The view handles the display of a page only, and is only reached in the code once the final destination of a request has been determined. You can do this however with both JavaScript and HTML:
JavaScript:
window.location.href = "http://example.com";
HTML:
<meta http-equiv="refresh" content="0;URL='http://example.com/'">
This method is discouraged by the W3C and should not be used. I have only included it here for informational purposes.
All that said, you should never have to do this. If you are trying to implement this in your MVC site then you are not respecting the MVC pattern and should rethink your architecture.
To automatically redirect, you can use
Javascript:
window.location.href="otherView";
Meta Refresh
<META HTTP-EQUIV="refresh" CONTENT="N;URL=http://www.foo.com/YourView">
I would do this via javascript
$(function(){
window.location.href = "www.yournewUrl.com";
});
or
$(function(){
window.location.href = "#Html.ActionLink("linkie, "action", "controller")"
});
You can use this
<meta http-equiv="refresh" content="10; ,URL=http://whatev.com/dd.html">
but it is not recommended

ASP.Net MVC Routing issue

I've got an issue with MVC routing(or at least I think it's w/routing :) )...
Just upgraded to MVC RC1, but I'm not sure that it's related as this is my first attempt at setting a MapRoute and corresponding RouteLink.
here's the route:
routes.MapRoute("Test1",
"Forecast/CurrentLineItems/{propertyID}/{forecastYear}/{forecastMonth}",
new { controller = "Forecast", action = "CurrentLineItems", propertyID = "", forecastYear = "", forecastMonth = "" }
);
here's the RouteLink...in the view it's wrapped in a table cell:
Html.RouteLink(Html.Encode(myProperty.Description),"Test1", new { controller = "Forecast", action = "CurrentLineItems", propertyID = myProperty.PropertyID.ToString(), forecastYear = "2008", forecastMonth = "10" })
here's a snippet from the controller:
namespace AnApplication.Controllers
{
[HandleError]
[Authorize]
public class ForecastController : Controller
{
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult CurrentLineItems(string propertyID, string forecastYear, string forecastMonth)
{
//Some code
}
Now for the strange behavior, when I click the link specified by the RouteLink, the app enters the CurrentLineItems method and all the method arguments are correct...
then it enters the CurrentLineItems method again!
with, for instance, these arguments:
propertyID = "scripts"
forecastYear = "jquery-1.2.6.js"
forecastMonth = ""
It then repeats this several times as it seems to run through all the scripts on this view and the Site.Master and then the last one is the .css file for this page!
What is going on!
The Call Stack is of no help as it lists the above-mentioned CurrentLineItems method and then below that is the dreaded [External Code]
When I profile the page/view in FireFox/FireBug all I see are the jQuery calls
Here's the html from the Site.Master re the scripts
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title><%= Html.Encode(ViewData["Title"]) %></title>
<script type="text/javascript" src="../../scripts/jquery-1.2.6.js"></script>
<script type="text/javascript" src="../../scripts/calculations.js"></script>
<script type="text/javascript" src="../../scripts/common.js"></script>
<style media="all" type="text/css">#import "../../Content/all.css";</style>
<!--[if IE]><link rel="stylesheet" type="text/css" href="../../Content/ie.css"media="screen"/><![endif]-->
<!--<link href="../../Content/Site.css" rel="stylesheet" type="text/css" />-->
</head>
here's a snippet from the view re the scripts
<%# Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master"AutoEventWireup="true" CodeBehind="CurrentLineItems.aspx.cs" Inherits="AnApplication.Views.Forecast.CurrentLineItems" %>
<asp:Content ID="lineItemsContent" ContentPlaceHolderID="MainContent" runat="server">
<!--<script type="text/javascript" src="../../scripts/MicrosoftAjax.debug.js"></script>-->
<script type="text/javascript" src="../../scripts/lineItems.js"></script>
<script type="text/javascript" src="../../Scripts/jquery.formatCurrency.js"></script>
<!--<script type="text/javascript" src="../../scripts/jquery-1.2.6.min.js"></script>-->
Note that this ActionLink works fine(It's basically just a menu item used for testing and the three arguments are set in the code inside the controller...):
<%= Html.ActionLink("Line Items", "CurrentLineItems", "Forecast")%>
Any help in solving this issue is greatly appreciated.
Thanks,
Greg
There were in fact two subtle, yet annoying bugs in the recently release ASP.NET MVC Release Candidate. These were the two bugs:
We changed all our URL-rendering methods to render relative URLs instead of absolute URLs. While we feel this might be the right decision in general, we found that it breaks an awful lot of scenarios. AJAX scenarios were especially affected since the URLs for retrieving data asynchronously are often different from the original URL as seen in the browser's address bar.
Html.RouteLink specifically (and not Html.ActionLink) had a bug in it (so it is not in fact a red herring - at least not necessarily). Html.RouteLink would erroneously take the "current" controller and action and pass those values into the routing system. Only Html.ActionLink is supposed to do that. Html.RouteLink is not supposed to do any processing at all. It's supposed to just take the values you give it and pass it along to the ASP.NET Routing system.
Since these two bugs were both pretty bad, we decided to roll back the change that caused #1 and to fix the issue that caused #2 and release an updated ASP.NET MVC Release Candidate Refresh.
You'll see some posts on ScottGu's blog, Phil Haack's blog, and the ASP.NET MVC Forums detailing the refresh.
Thanks,
Eilon
It could be caused by the usage of relative paths to include the scripts.
When you click on the link the URL of the new page will be something like http://[server]/Forecast/CurrentLineItems/xxx/2009/1
Now check the html code in the browser: If the URLs are in the form of '../../scripts/jquery-1.2.6.js', this will cause the browser to load it from http://[server]/Forecast/CurrentLineItems/scripts/jquery-1.2.6.js - and so your controller gets called again.
If that is the case you could either use absolute paths ('/scripts/jquery-1.2.6.js') or use a path relative to the application root ('~/scripts/jquery-1.2.6.js') and resolve it on the server side with Page.ResolveClientUrl().
Maybe there has been a change from Beta to RC1, so that the URLs in the head, even with runat="server", don't get remapped.
RouteLink versus ActionLink is a red herring here. The only thing that matters is the rendered a href="[something]". You would get exactly the same results if you wrote the a href manually instead of generating it via RouteLink.
So, yes, now we're down to routing. Inside your controller action, inspect RouteData in the debugger, and see which route name was matched. Chances are very likely it's the wrong one, and that is causing other things to misbehave. Either change the order of your reps, or add constraints to prevent the wrong one from being matched.
RouteLink works very well to prevent finding the wrong route when you're generating a URL. But when your application is consuming a URL, you still need to have your routes in order in global.asax.

Resources