Sending a web page by email programmatically. Image urls are not allowed

I am writing a SharePoint timer job that needs to pull the content of a web page and send that HTML address as an email.

I am using HttpWebRequest and HttpWebResponse objects to pull the content.

The email functionality works great except for one problem.

The web page that serves the content of my email contains images.

When the html of a page is sent as email, the image urls inside the HTML are relative urls, they are not resolved as an absolute url.

How do I resolve urls of images in their absolute paths within the content of a web page?

Is there any direct way to do this? I don't want to run Regex over html code to replace all relative urls with absolute urls.

+1


source to share


4 answers


Found this cool Codeplex tool called HtmlAgilityPack. http://www.codeplex.com/htmlagilitypack

Using this API, we can parse the Html so that we can parse XML documents. We can also query and search for nodes using XPath.



I used the following piece of code to fix image urls

HtmlDocument htmlDoc = new HtmlDocument();
            htmlDoc.LoadHtml(htmlMessage);

//This selects all the Image Nodes
            HtmlNodeCollection hrefNodes = htmlDoc.DocumentNode.SelectNodes("//img");

            foreach (HtmlNode node in hrefNodes)
            {
                string imgUrl = node.Attributes["src"].Value;
                node.Attributes["src"].Value = webAppUrl + imgUrl;
            }

        StringBuilder sb = new StringBuilder();
            StringWriter sw = new StringWriter(sb);

            htmlDoc.OptionOutputAsXml = false;
            htmlDoc.Save(sw);
            htmlMessage = sb.ToString();

      

+2


source


Try adding the element base

to the beginning of the resulting html document. href

You must use the URL of the page you are retrieving as an attribute .



+5


source


I ran into this problem several times and I don't think there is any magic wand method to do it all for you. HTMLAgilityPack does a good job of aggregating the content you want, but you'll have to decrypt it yourself. For instance; getting a list of HtmlNodes containing "// img" can return any of the following:

<img src="http://www.adg2435.com/pictures/pic.jpg"/> //absolute url
<img src="coolpicture.jpg"/> //relative to the page
<img src="pictures/pic.jpg"/>
<img src="./pictures/pic.jpg"/>

      

It is up to you to figure out what types of links will appear on a given web page. You also need to consider things like this: (Exaggerate the image url after the ".jpg" extension)

<img src="/pictures/pic.jpg?45823593&xyz=95325235r0634945823ot49140200"/>

      

So, it is convenient for me to keep a few things at hand at any given time:

  • Source URL for the whole page
  • The domain for a given url (to do things like say "does the given src contain a domain?") Here's how you get the domain of the original link:

    Uri domainUri = new Uri (fullUrl); domainUrl = domainUri.GetLeftPart (UriPartial.Authority);

  • Potentially you need a subdomain (ie "http://www.mysite.com/pictures/")

0


source


I don't want to run Regex over html code to replace all relative urls with absolute urls.

Too bad because this is the only way to get images. Would you rather download all of the images and embed them in email too?

-five


source







All Articles