How to load relative source in WebView - c#

I'm using HttpClient to get html string and use WebView's navigateToString method to show this page. I know I can use WebView load this page directly, but I would need to do some processing on that page before it's shown in WebView.
So, I faced a question. The web page quotes some css/js files in header, but I saw that 'href' value is relative path. Then the page will not show correctly in WebView.
[Updated]
For example, I'm using HttpClient to request a URI (http://example.com), then I will get the whole html page string. I will do some operations on this html string. After that, I will use WebView.NavigateToString(htmlpage) method to show this page. But if you check its head tag, there will be some <link> tag, its href value is relative path(/style-a/1.css), not absolute path. Then you will find that the html page doesn't show correctly in WebView.
Could someone give me a solution/code sample?
#Pedro Lamas, rene, Barett, moi_meme, Shachaf.Gortler Please do not put my question on hold. I didn't break any SO rules. My question was very clear. I think you do this, it's because you do not know how to answer my question. That's ok. If you don't know, you could choose not to answer it, but please do not put it on hold.

You can set address of your Link or Scripts tag with ms-appx-web:// and put address after that with additional [ / ] .
for example in this case you can use :
<script src="ms-appx-web:///Assets/FolderName/test.js" type="text/javascript"></script>
and also for link can use :
<link rel="stylesheet" type="text/css" href="ms-appx-web:///style-a/1.css">

Related

Get page name only using Request MVC

I want to add alternate tag for multiple lang. website, previous developer had added the alternate url using the below code:
<link rel="alternate" href="#Request.Url.Scheme://#Request.Url.Authority/us/#Request.RawUrl.Remove(0,1).Replace("/us","")" hreflang="es-us" />
it was done only for one lang. Now I am facing problem to get the page only, rawurl is returning the "/us/folder/pagename" but I want "/folder/pagename". is there any way by which I can achieve this?
It is on html side, i don't want to get it on code level and pass to view. i am asking if there is any way by which i can get in view only.

How can I get a web site's favicon?

Simple enough question: I've created a small app that is basically just a favourites that sits in my system tray so that I can open often-used sites/folders/files from the same place. Getting the default icons from my system for known file types isn't terribly complicated, but I don't know how to get the favicon from a website. (SO has the grey->orange stack icon in the address bar for instance)
Does anyone know how I might go about that?
You'll want to tackle this a few ways:
Look for the favicon.ico at the root of the domain
www.domain.com/favicon.ico
Look for a <link> tag with the rel="shortcut icon" attribute
<link rel="shortcut icon" href="/favicon.ico" />
Look for a <link> tag with the rel="icon" attribute
<link rel="icon" href="/favicon.png" />
The latter two will usually yield a higher quality image.
Just to cover all of the bases, there are device specific icon files that might yield higher quality images since these devices usually have larger icons on the device than a browser would need:
<link rel="apple-touch-icon" href="images/touch.png" />
<link rel="apple-touch-icon-precomposed" href="images/touch.png" />
And to download the icon without caring what the icon is you can use a utility like http://www.google.com/s2/favicons which will do all of the heavy lifting:
var client = new System.Net.WebClient();
client.DownloadFile(
#"http://www.google.com/s2/favicons?domain=stackoverflow.com",
"stackoverflow.com.ico");
Updated 2020
Here are three services you can use in 2020 onwards
<img height="16" width="16" src='https://icons.duckduckgo.com/ip3/www.google.com.ico' />
<img height="16" width="16" src='http://www.google.com/s2/favicons?domain=www.google.com' />
<img height="16" width="16" src='https://api.statvoo.com/favicon/?url=google.com' />
You can use Google S2 Converter.
http://www.google.com/s2/favicons?domain=google.com
Source: http://www.labnol.org/internet/get-favicon-image-of-websites-with-google/4404/
This question is the first google search result I got when I keep searching for website favicon API. So I think it'll be still helpful in the future.
https://icon.horse/icon/[url.hostname] will give you a better site icon.
https://icon.horse/icon/stackoverflow.com
You can do it without programming in 3 steps:
1. Just open the web site, right-click and select "view source" to open the HTML code of that site. Then in the text editor search for "favicon" - it will direct you to something looking like
<link rel="icon" href='/SOMERELATIVEPATH/favicon.ico' type="image/x-icon" />
Take the string in href and append it to the web site's base URL (let's assume it is "http://WEBSITE/"), so it looks like
http://WEBSITE/SOMERELATIVEPATH/favicon.ico
which is the absolute path to the favicon. If you didn't find it this way, it can be as well in the root in which case the URL is http://WEBSITE/favicon.ico.
2. Take the URL you determined and insert it into the href-Parameter of the following code:
<html>
<head>
<title>Capture Favicon</title>
</head>
<body>
<a href='http://WEBSITE/SOMERELATIVEPATH/favicon.ico' alt="Favicon"/>Favicon</a>
</body>
</html>
3. Save this HTML code locally (e.g. on your desktop) as GetFavicon.html and then double-click on it to open it. It will display only a link named Favicon. Right-click on this link and select "Save target as..." to save the Favicon on your local PC - and you're done!
It's a good practice to minimize the number of requests each page needs.
So if you need several icons, yandex can do a sprite of favicons in one query.
Here is an example
http://favicon.yandex.net/favicon/google.com/stackoverflow.com/yandex.net/
The first thing to look for is /favicon.ico in the site root; something like WebClient.DownloadFile() should do fine. However, you can also set the icon in metadata - for SO this is:
<link rel="shortcut icon"
href="http://sstatic.net/stackoverflow/img/favicon.ico">
and note that alternative icons might be available; the "touch" one tends to be bigger and higher res, for example:
<link rel="apple-touch-icon"
href="http://sstatic.net/stackoverflow/img/apple-touch-icon.png">
so you would parse that in either the HTML Agility Pack or XmlDocument (if xhtml) and use WebClient.DownloadFile()
Here's some code I've used to obtain this via the agility pack:
var favicon = "/favicon.ico";
var el=root.SelectSingleNode("/html/head/link[#rel='shortcut icon' and #href]");
if (el != null) favicon = el.Attributes["href"].Value;
Note the icon is theirs, not yours.
In 2020, using duckduckgo.com's service from the CLI
curl -v https://icons.duckduckgo.com/ip2/<website>.ico > favicon.ico
Example
curl -v https://icons.duckduckgo.com/ip2/www.cdc.gov.ico > favicon.ico
You can get the favicon URL from the website's HTML.
Here is the favicon element:
<link rel="icon" type="image/png" href="/someimage.png" />
You should use a regular expression here. If no tag found, look for favicon.ico in the site root directory. If nothing found, the site does not have a favicon.
HttpWebRequest w = (HttpWebRequest)HttpWebRequest.Create("http://stackoverflow.com/favicon.ico");
w.AllowAutoRedirect = true;
HttpWebResponse r = (HttpWebResponse)w.GetResponse();
System.Drawing.Image ico;
using (Stream s = r.GetResponseStream())
{
ico = System.Drawing.Image.FromStream(s);
}
ico.Save("favicon.ico");
Sometimes we can't get the favicon image with the purposed solution as some websites use .png or other image extensions. Here is the working solution.
Open your website with a firefox browser.
Right-click on the website and click the "View page info" option from the list.
It will open up a dialog and click on the "Media" tab.
In that tab you will see all the images including favicon.
Select the favicon.ico image or click through the images to see which image is used as favicon. Some websites use .png images as well.
Then click on the "Save As" button and you should be good to go.
thanks!
This is a late answer, but for completeness: it is difficult to get even close to fetching 90% all favicons.
A while ago I wrote a WordPress plugin which attempts to get closer to 100%.
This is how it works:
It starts by searching existing favicon repositories such as Google favicons and GetFavicons for the favicon.
If none of them returns an icon, the plugin attempts to get the icon itself. This involves traversing several pages on the domain.
The plugin then inspects the physical image file, because on some servers files get returned with the incorrect mime types.
The code is still not perfect because in the details you will find many weird situations: people have wrongly coded paths, e.g. img/favicon.ico where img is not in the root, duplicate headers in HTML output, different server responses from the head and body etc.
The core of the fetching part is here so you can reverse-engineer it, but be aware that validating the response should be done (checking image filetype, mime etc.).
The SHGetFileInfo (Check pinvoke.net for the signature) lets you retrieve a small or large icon, just as if you were dealing with a file/folder/Shell item.
http://realfavicongenerator.net/favicon_checker?site=http://stackoverflow.com gives you favicon analysis stating which favicons are present in what size. You can process the page information to see which is the best quality favicon, and append it's filename to the URL to get it.
You can use Getfv.co :
To retrieve a favicon you can hotlink it at... http://g.etfv.co/[URL]
Example for this page : http://g.etfv.co/https://stackoverflow.com/questions/5119041/how-can-i-get-a-web-sites-favicon
Download content and let's go !
Edit :
Getfv.co and fvicon.com look dead. If you want I found a non free alternative : grabicon.com.
Using jquery
var favicon = $("link[rel='shortcut icon']").attr("href") ||
$("link[rel='icon']").attr("href") || "";

Why is a meta refresh tag and title tag sitting outside of the <head> tag in ASP.NET?

When I render a page in ASP.NET, the following happens
</head>
<NOSCRIPT>
<meta http-equiv="REFRESH" content="0;URL=/Default.aspx?id=84&epslanguage=en-GB&jse=0" />
</NOSCRIPT>
<title>Page title goes here.</title>
<body>
My masterpage looks like this:
<title>Page title goes here.</title>
</head>
<body>
So what I'm asking is, where the heck has this refresh meta tag come from, why has it put it between my head tag and body tag, and why has my page title jumped outside of the head?!
When viewing the page's generated source in firebug, it shows the title tag and this new meta tag within the head tag, but viewing the source in any browser, it looks like the above. When using wget to scrape the page, it also comes out incorrectly as displayed above.
Any ideas why browsers may be interpreting this in different ways, and more importantly where this new meta tag has come from?
Thanks! Karl.
Edit:
Hi!
Thanks for your replies guys, very informative!
I've discovered that the problem is this line of code:
Page.Header.Controls.Add(ctrl);
Putting the mysterious meta tag in using this line puts it outside the head tag. When commenting this out, the title tag drops back into the right place, and all is well!
Any further thoughts?
Thanks!
Karl.
On the matter of why browsers will be interpreting it differently there are two answers. Firstly the firebug output as you say is generated source. That means its gone through a certain amount of processing already and clearly firefox is doing some magic to say "Well, its a meta and a title tag, they should be in the header so I'll put them there."
The other browsers you are comparing their raw source it sounds like which is before the browser has tried to make sense of it. I suspect you'd get the same if you viewed the raw source in firefox (ctrl-u).
I'd have expected all browsers to do much the same thing as you have described firefox as doing but if not then that's not really somethign to be concerned about. When invalid HTML like this is received the browsers have no real rules of what to do. This means that browsers are welcome to do whatever they want from trying to guess what you meant to just ignoring it entirely.
As for what is causing it, the epslanguage query paramter is from episerver - I don't know if that was in the request url or not so it may be that it is just being persisted or it may be episerver trying to redirect to a page with an explicit language instead of just assuming the default. Unfortunately I'm not familiar with episerver so I can't say any more specific to that.
It is of course definitely the case that there is something on your server side that is causing this to happen.
Do you get that for all pages out of interest or just one specific one or just in one specific circumstance?
Quite often it's a case of an element not being properly closed. Most browsers will try to adjust the markup so that it makes sense, but in most cases the markup will be incorrectly parsed.
You should probably share more of your master page (and the web form using it)!
Maybe your HEAD-tag doesn't have runat="server"?

Style Sheet is not working in one web page

Style sheet in master page is not working for one web page of asp.net application but it works for another web page.
If you are referencing a css file from a master page you should ensure it has an absolute path, that way it will work everywhere. For example:
<head runat="server">
<link type="text/css" rel="stylesheet" href="~/_styles/mystylesheet.css" />
</head>
The important thing to note here is that the head tag has the runar="server" attribute and that i am specifying the full virtual path using a tilde ("~").
Are none of its style elements being included? Is it being over ridden( they are Cascading Style Sheets)? Does it have the correct CSS include statement?
Are your pages in different levels of folders ?
For example,
..\main.css
..\folder1\MasterPage.master
..\folder1\css_working.aspx
..\folder1\folder2\css_not_working.aspx
in this scenario you should define your css in masterpage as :
<link rel="stylesheet" type="text/css" href="../main.css" />
And take your pages to same level, like that :
..\main.css
..\folder1\MasterPage.master
..\folder1\css_working.aspx
..\folder2\css_not_working.aspx
If you are using update panels there are some cases where the styling may be lost for AJAX toolkit controls. To fix this you need to put hte full name of hte class items into the stylesheet instead of letting hte toolkit handle this.
Also be sure to use a relative url where possible so that if a file moves it won't loose it's mapping.
Use Firebug or Debug Bar, these tools will show you all the styles being employed on each element, so you can see what stylesheets it is using and which ones it is not.
Also, when you build check for any warnings about stylesheets that it can't reference etc.
it could be a permission issue on the folder... if you have deny users="?" in your web config.. make sure you have an allow users on the folder where you have your style sheets

Element-Enhancing Javascript in ASP.NET Master Pages

I have run in to a bit of a problem and I have done a bit of digging, but struggling to come up with a conclusive answer/fix.
Basically, I have some javascript (created by a 3rd party) that does some whizzbang stuff to page elements to make them look pretty. The code works great on single pages (i.e. no master), however, when I try and apply the effects to a content page within a master, it does not work.
In short I have a master page which contains the main script reference. All pages will use the script, but the parameters passed to it will differ for the content pages.
Master Page Script Reference
<script src="scripts.js" language="javascript" type="text/javascript" />
Single Page
<script>
MakePretty("elementID");
</script>
As you can see, I need the reference in each page (hence it being in the master) but the actual elements I want to "MakePretty" will change dependant on content.
Content Pages
Now, due to the content page not having a <head> element, I have been using the following code to add it to the master pages <head> element:
HtmlGenericControl ctl = new HtmlGenericControl("script");
ctl.Attributes.Add("language", "javascript");
ctl.InnerHtml = #"MakePretty(""elementID"")";
Master.Page.Header.Controls.Add(ctl);
Now, this fails to work. However, if I replace with something simple like alert("HI!"), all works fine. So the code is being added OK, it just doesn't seem to always execute depending on what it is doing..
Now, having done some digging, I have learned that th content page's Load event is raised before the master pages, which may be having an effect, however, I thought the javascript on the page was all loaded/run at once?
Forgive me if this is a stupid question, but I am still relatively new to using javascript, especially in the master pages scenario.
How can I get content pages to call javascript code which is referenced in the Master page?
Thanks for any/all help on this guys, you will really be helping me out with this work problem.
NOTES:
RegisterStartupScript and the like does not seem to work at any level..
The control ID's are being set fine, even in the MasterPage environment and are rendering as expected.
Apologies if any of this is unclear, I am real tired so if need be please comment if a re-word/clarification is required.
Put a ContentPlaceHolder in the head section of the master page, then add a asp:Content control on the content page referring to the placeholder and put your script in that control. You can customize it for each page this way.
Also, the reference by ID may not be working because when you use Master Pages, the control IDs on the page are automatically created based on the container structure. So instead of "elementID" as expected, it may be outputting "ctl00_MainContentPlaceHolder_elementID" View your source or use firebug to inspect your form elements to see what the IDs outputted are.
Isn't it possible to do with clean javascript ?-)
-- just add something similar to this inside the body-tag:
<script type="text/javascript">
window.onload = function(){
MakePretty("elementID");
}
</script>
By the way the script-tag has to have an end-tag:
<script type="text/javascript" src="myScript.js"></script>
Why not use jQuery to find all the controls? Something like this:
$(document).ready(function(){
$("input[type='text'], input[type='radio'], input[type='checkbox'], select, textarea").each(function(){
MakePretty(this);
});
});
This way you'll get all elements on the page, you can wait until the page is ready (so you don't modify the DOM illigally). The jQuery selector can get the elements in a bit more of a specific format if you need (ie, add a root element, like the ID of the body div).
It'd also be best to modify the MakePretty method so it takes the element not the ID as the parameter to reduce processing overhead.
Once you use Master Pages, the ids of controls on the client side aren't what you think they are. You should use Control.ClientID when you generate the script.
When using master pages, you need to be careful with the html attribute ID, since .NET will modify this value as it needs to keep ids unique.
I would assume your javascript is applying css styles via ID, and when you are using master pages the ID is different than what is in your aspx. If you verify your javascript is always being added, your answer needs to take into account the following:
ALWAYS set your master page id in page load (this.ID = "myPrefix";)
Any HTML element in your master page will be prefixed by the master page id (i.e.: on the rendered page will be "myPrefix_myDiv")
Any HTML element in your content place holder id will be prefixed with an additional prefix (i.e. myPrefix_ContentPlaceHolderId1_myDiv)
Please let me know if I can clarify anything. Hope this helps!

Categories