In a Grails application I'd like to send a user from page A, then to a form on page B and then back to page A again.
To keep track of which URL to return to I send a "returnPage" parameter to page B containing the URL of page to return to (page A).
Currently I'm using request.getRequestURL() on page A to retrieve the page's URL. However, the URL I get from getRequestURL() does not correspond to the URL the end-user has in his/hers address bar:
request.getRequestURL() == "http://localhost:8080/something/WEB-INF/grails-app/views/layouts/main.gsp"
URL in address bar == "http://localhost:8080/something/some/thing"
How do I obtain the "end-user" URL?
The answer is request.forwardURI (details here).
I built this method to get current url.
static String getCurrentUrl(HttpServletRequest request){
StringBuilder sb = new StringBuilder()
sb << request.getRequestURL().substring(0,request.getRequestURL().indexOf("/", 8))
sb << request.getAttribute("javax.servlet.forward.request_uri")
if(request.getAttribute("javax.servlet.forward.query_string")){
sb << "?"
sb << request.getAttribute("javax.servlet.forward.query_string")
}
return sb.toString();
}
I prefer to use:
createLink(action: "index", controller:"user", absolute: true)
// http://localhost:8080/project/user
when I need to get an absolute url!
It's interesting to get relative path too:
createLink(action: "index", controller:"user")
// /project/user
When creating the link to page B you can use the createLink tag to set the returnPage parameter:
<g:link controller="pageB"
action="someaction"
params='[returnPage:createLink(action:actionName, params:params)]'>
Go to Page B
</g:link>
My solution (Grails 1.3.7) is this one, you can copy and paste it into your controller:
boolean includePort = true;
String scheme = request.getScheme();
String serverName = request.getServerName();
int serverPort = (new org.springframework.security.web.PortResolverImpl()).getServerPort(request)
String contextPath = request.getContextPath();
boolean inHttp = "http".equals(scheme.toLowerCase());
boolean inHttps = "https".equals(scheme.toLowerCase());
if (inHttp && (serverPort == 80)) {
includePort = false;
} else if (inHttps && (serverPort == 443)) {
includePort = false;
}
String redirectUrl = scheme + "://" + serverName + ((includePort) ? (":" + serverPort) : "") + contextPath;
In our application, we cannot just use g.createLink(.. absolute:true) because we have different end-user URLs because of multiple customers.
Related
OK, this sounds dumb even to me, but I am clearly having a "bad brain day" and need help.
On a button click, I want to generate a file based on parameters taken from 2 ViewData fields and a checkbox control, and have the file be downloaded/displayed, just as you get with a fixed link.
Most of it is going fine, the controller method passes back a file like so: Return File(filePath, "text/csv") - but then what? How do I connect that to the button and have the file download/open dialog come up?
I feel I am missing something really simple. Just calling the controller via ajax seems to do nothing... the code is called but I see no results
***** EDIT: ******
The following gets me a file automatically downloaded, but with the name "download" - I want to offer the user the choice to open or download, and to set the filename - how do I do that?
serialize = function (obj) {
var str = [];
for (var p in obj)
if (obj.hasOwnProperty(p)) {
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
}
return str.join("&");
};
var params = {
ID1: '#ViewData("ID1")',
ID2: '#ViewData("ID2")',
flag: getFlag()
};
var actionUrl = ('#Url.Action("ProduceReport", "Report")');
actionUrl += "/?" + serialize(params);
window.open(actionUrl);
* 2nd edit *
Controller code - this produces a file and returns the path. After the call to ProduceReport The file is there on that path, this I have checked. It is used in production to email the file (works fine).
public FileResult ProduceReport(int ID1, int ID2, bool flag = false)
{
var filePath = ExcelReports.ProduceReportExcel(Models.UserInfo.GetCurrentUserID, ID1, ID2, flag);
return File(filePath,"application/vnd.ms-excel");
}
The acceptable compromise that I found, to at least get the file downloaded. I will have to do further research to see if I can print it automatically.
Javascript:
serialize = function (obj) {
var str = [];
for (var p in obj)
if (obj.hasOwnProperty(p)) {
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
}
return str.join("&");
};
var params = {
ID1: '#ViewData("ID1")',
ID2: '#ViewData("ID2")',
flag: getFlag()
};
var actionUrl = ('#Url.Action("ProduceReport", "Report")');
actionUrl += "/?" + serialize(params);
window.location.href = actionUrl;
Controller: Note 3rd parameter on the File() call
public FileResult ProduceReport(int ID1, int ID2, bool flag = false)
{
var filePath = ExcelReports.ProduceReportExcel(Models.UserInfo.GetCurrentUserID, ID1, ID2, flag);
return File(filePath,"application/vnd.ms-excel",System.IO.Path.GetFileName(filePath));
}
I have vb.net website and MVC 4 application. I am sending the query string from MVC application to VB application. The VB.Net application is hosted in IIS server.
Temporarily I am reading the query string on a label. The problem is that during first click the query-string doesn't get read. But during the second click on the same link, the query string gets printed on the label.
MVC code:
public JsonResult OpenK3oneWebLink(string strLinkName)
{
string strWebLink = string.Empty;
string linkName = string.Empty;
try
{
if (pclsConcurrency.UXControllerServiceClient.modifyUserStatus("T", pclsConcurrency.strUsersId) == true)
{
string[] arr = pclsConcurrency.m_strDBName.Split('_');
string DBNameForUrl;
if (arr.Length == 1)
{
DBNameForUrl = arr[0];
}
else
{
DBNameForUrl = arr[1];
}
eif (strLinkName == "daytoday")
{
strWebLink = "http://" + pclsConcurrency.m_strAppServer + "/K3OneWeb_" + DBNameForUrl + "/Environment/Login.aspx?intEntityId=" + pclsConcurrency.intEntityId + "&Users=" + pclsConcurrency.strUsersId;// +"192.168.0.163/K3OneWeb_aish1/Environment/Login.aspx?intEntityId=5&Users=SHG";
}
else if (strLinkName == "Daily")
{
strWebLink = "http://" + pclsConcurrency.m_strAppServer + "/K3OneWeb_" + DBNameForUrl + "/Environment/Login.aspx?intEntityId=" + pclsConcurrency.intEntityId + "&Users=" + pclsConcurrency.strUsersId + "&linkname=Daily";
}
and the vb.net code is
Label1.Text = Request.QueryString("intEntityId")
Label2.Text = Request.QueryString("Users")
Label3.Text = Request.QueryString("linkname")
it is written on page load event but, unable to retrieve it on the first click but get retrieved on the second click on the same link.The VB application is hosted on IIS server and MVC application is running locally.
TIA
Off the bat: I am new to using asp.net mvc 4.
I am have a action that creates a excel file and then converts it to PDF.
From View
#Html.ActionLink("Generate Invoice", "genInvoice", new { id = item.invoiceID }) |
Action:
public ActionResult genInvoice(int id = 0)
{
var invoiceItems = from k in db.InvoiceItems
where k.invoiceID == id
select k;
string invoiceClient = (from kk in db.Invoices
where kk.invoiceID == id
select kk.clientName).Single();
invoiceClient = invoiceClient + "_" + DateTime.Now.ToString("ddd dd MMM yyyy hhTmm");
string websitePath = Request.PhysicalApplicationPath;
string pathName = websitePath + "\\" + invoiceClient ;
generateInvoice(invoiceItems, pathName + ".xlsx", id);
convertToPDF(pathName, invoiceClient);
//Response.AppendHeader("Content-Disposition", "attachment");
var viewModel = new InvoiceItemAdd();
viewModel.Invoices = db.Invoices
.Include(i => i.InvoiceItems)
.OrderBy(i => i.invoiceID);
return View("Index", viewModel);
//return RedirectToAction("Index",viewModel);
}
Now I want to to eventually download the PDF file and then return to the index view.
It goes to the Index view prints the html etc etc but then the window stays as a white screen with the url: /Invoice/genInvoice/1
Any idea how I can go about doing this? (Going back to the Index view after PDF generation, also downloading it)
I am sorry, I fixed the white screen problem. While attempting to do the PDF download
//Response.AppendHeader("Content-Disposition", "inline; filename="+invoiceClient+".pdf");
//Return File(output, "application/pdf");
//Response.Flush();
//Response.End();
Response.End() was not commented out and that stopped it I guess.
Now the problem is how to open the PDF in a separate tab and return to index in the current
with the above code.
EDIT:
Decided the file can just be downloaded.
public FileResult genInvoice(int id = 0)
{
//More code
Response.AppendHeader("Content-Disposition", "attachment; filename="+pathName+".pdf");
return File(websitePath + "\\" + invoiceClient + ".pdf", "application/pdf");
}
I have scraped a webpage but I want the link to have valid link and will jump to that linkpage when clicked.
ex scraped data: day 1 - Go to my Page - status
I want the Go to my page to jump to whatever link is in its href.
ex. actual html I got
<td>Go to my Page</td>
I need it to be like this:
<td>Go to my Page</td>
here's my code for scraping:
public string ScreenScrape()
{
string url = "http://somewebsite.com/tab/form/index.php";
string strResult = "";
WebResponse objResponse;
WebRequest objRequest = System.Net.HttpWebRequest.Create(url);
objResponse = objRequest.GetResponse();
using (StreamReader sr = new StreamReader(objResponse.GetResponseStream()))
{
strResult = sr.ReadToEnd();
// Close and clean up the StreamReader
sr.Close();
}
var webGet = new HtmlAgilityPack.HtmlWeb();
var doc = webGet.Load(url);
foreach (HtmlNode link in doc.DocumentNode.SelectNodes("//a[#href]"))
{
HtmlAttribute att = link.Attributes["href"];
att.Value = "http://somewebsite.com/tab/form/"+att.Value;
}
return strResult;
}
Here's my attempt to change the link and remove the javascript string but could not figure out how to get to the right index . Also, once I am able to change that, how do I replace each href in the strResult(above) to the new href?
foreach (HtmlNode link in doc.DocumentNode.SelectNodes("//a[#href]"))
{
HtmlAttribute att = link.Attributes["href"];
att.Value = "http://somewebsite.com/tab/form/" + ....
}
Can anyone pls help me? thanks
nevermind I got it, but I know the html url parsing is not the best way (if you have suggestion on how to parse it better, pls do so). right now, the only goal is to change the href link so here it goes.
public string ScreenScrape()
{
string url = "http://somewebsite.com/tab/form/index.php";
string strResult = "";
WebResponse objResponse;
WebRequest objRequest = System.Net.HttpWebRequest.Create(url);
objResponse = objRequest.GetResponse();
using (StreamReader sr = new StreamReader(objResponse.GetResponseStream()))
{
strResult = sr.ReadToEnd();
// Close and clean up the StreamReader
sr.Close();
}
var webGet = new HtmlAgilityPack.HtmlWeb();
var doc = webGet.Load(url);
foreach (HtmlNode link in doc.DocumentNode.SelectNodes("//a[#href]"))
{
string removeString ="javascript:jsFormAuth('";
string removeEnd = "');";
HtmlAttribute att = link.Attributes["href"];
String strUrl = HttpContext.Current.Request.Url.AbsoluteUri.Replace(att.XPath, "(");
string sub1 = att.Value.Replace(removeString,"");
string sub2 = sub1.Replace(removeEnd,"");
att.Value = "http://somewebsite.com/tab/form/" + sub2;
}
return doc.DocumentNode.InnerHtml;
}
I have list of URL in txt file I am using it for performance test, since URL were not formed correctly java.IO.exeption were thrown,I would like to know how to check correctness of URL? and whether it is working fine? I have more than 35 K url checking manually will consume lot's of time.
To check whether URL are properly formed try casting the string to an URI object.
eg:
public void validURLs(List<string> urlList)
{
int line = 1;
for(string s : urlList)
{
try
{
URI test = new URI(s);
}
catch(Exception e)
{
System.err.println(s + " is not a valid URL, item " + line);
}
line ++;
}
}