|
|
aspNetMHT
|
 |
Subscribe to category: aspNetMHT
by Dave
11. December 2012 07:25
What’s new in aspNetMHT v2
aspNetMHT v2 has been in development for almost 2 years. During that time frame we've had multiple customer requests. Many of these new features are directly related to those requests. If you ever see a MHT need, that aspNetMHT does not fulfill, we would love to hear about it. Be sure to send all feature suggestions to support@advancedintellect.com
New Events aspNetMHT exposes some new events for more granular control. The most useful will probably be the BeforeParseMHTPart event. This event is raised before the MHTPart is parsed, allowing the developer to control different aspects of the part.
New, easier to use Methods Some new static methods have been exposed, allowing you to create MHT documents in a single line of code.
Attachment Support aspNetMHT now supports the capability to add attachments to the MHT document. This is especially useful in those instances where you need to add PDFs to your MHT documents.
New Extractor Support aspNetMHT now provides the capability to extract a MHT document into it’s individual parts. This allows you to take an existing MHT document, and convert it back into all it’s individual pieces, and still have all the links work correctly.
Better CSS Support There have been numerous enhancements in this area. Some where minor, but some were quite major. They include, better support for the data: format. Better handling of style tags. Better processing of @import statements. Especially nested @import statements.
More Utility Methods More utility methods have been added to the MHTPart object. These methods allow you to check for specific types, for example: .IsJavascript(), or .IsImage(), where these methods will tell you if the object is a javascript part or an image part. Additional methods are also exposed for easily determining content types.
Compression Support aspNetMHT now has the capability to decode GZip compressed data coming over Http.
Better Local Filesystem Support aspNetMHT can better parse local Html sources. Especially better support for UNC (\\server name\\share name) referenced content such as images.
Better Image Detection Support aspNetMHT now has better image detection support, to better recognize images that may be mis-labeled by the server.
Better Encoding Support aspNetMHT provides the developer with more Html encoding options, for more granular control.
by Dave
4. March 2011 10:45
I recently had an email request, asking if aspNetMHT could be used to switch out images.
In this particular instance, the customer wanted to convert a Url to a MHT document. However, the images were larger than desired. So, the requestor asked if aspNetMHT would allow images to be swapped out.
The following code example demonstrates this capability. In this example, we are going to examine the content-location value of each MHTPart. For simplicity sake, we are simply going to find all .png images, and swap them out with an image named "sample.png". In a production scenario, we would make some logic based decisions when swapping out the images.
Here is the code.
C#
static void Example()
{
string url = "http://www.google.com";
MHT m = new MHT();
//enable logging for any troubleshooting
m.Logger= new MHTLog("c:\\temp\\mht.log");
m.Logger.Enabled =true;
m.Logger.Overwrite=true;
m.Ignore404=true;
m.UserAgent = "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)";
m.LoadUrl(url);
m.Parse();
ReplaceImages( m );
m.SaveToFile("c:\\temp\\");
}
static void ReplaceImages(MHT m)
{
MHTPartCollection parts = m.RetrieveAllParts();
foreach( MHTPart part in parts )
{
if( part.ContentLocation != null )
{
string cl = part.ContentLocation.Value;
if( cl != null )
{
cl = cl.ToLower();
//as a simple test, replace all .png images
if( cl.EndsWith(".png") )
{
//read in the replacement image
FileStream fs = File.OpenRead("c:\\temp\\sample.png");
byte[] data = new byte[ fs.Length ];
fs.Read( data, 0, data.Length );
fs.Close();
part.Data = data;
}
}
}
}
}
VB.NET
Shared Sub Example()
Dim url As String = "http://www.google.com"
Dim m As New MHT()
'enable logging for any troubleshooting
m.Logger = New MHTLog("c:\temp\mht.log")
m.Logger.Enabled = True
m.Logger.Overwrite = True
m.Ignore404 = True
m.UserAgent = "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)"
m.LoadUrl(url)
m.Parse()
ReplaceImages(m)
m.SaveToFile("c:\temp\")
End Sub 'Example
Shared Sub ReplaceImages(m As MHT)
Dim parts As MHTPartCollection = m.RetrieveAllParts()
Dim part As MHTPart
For Each part In parts
If Not (part.ContentLocation Is Nothing) Then
Dim cl As String = part.ContentLocation.Value
If Not (cl Is Nothing) Then
cl = cl.ToLower()
'as a simple test, replace all .png images
If cl.EndsWith(".png") Then
'read in the replacement image
Dim fs As FileStream = File.OpenRead("c:\temp\sample.png")
Dim data(fs.Length) As Byte
fs.Read(data, 0, data.Length)
fs.Close()
part.Data = data
End If
End If
End If
Next part
End Sub 'ReplaceImages
As always, if anyone has any questions, let me know.
Thanks! Dave Wanta
by Dave
3. March 2011 09:53
I received an email from Jeff W. the other day, and he had an interesting requirement.
He wanted to save the current contents of the ASP.NET page, to a MHT document.
This is a little different than the normal situation, because normally aspNetMHT is pointed at a Url, and the remote Url is downloaded, and converted to the MHT document.
In this particular scenario, Jeff wanted to save the contents of the ASP.NET page being rendered, from inside of the page. It turns out this is possible by accessing the Render event. If you override the render with the code below, you can save the current contents, and convert them to a MHT documents.
As always, if anyone has any questions, feel free to contact me through the Contact Us page.
C#
protected override void Render(HtmlTextWriter writer)
{
System.IO.StringWriter sw = new System.IO.StringWriter();
HtmlTextWriter localWriter = new HtmlTextWriter(sw);
base.Render(localWriter);
//get the contets of the page
string html = sw.ToString();
//check to see if the page was posted
if( Page.IsPostBack )
{
//save it to a MHT file
MHT m = new MHT();
//this is the url of this page. It's used so aspNetMHT can resolve any images.
string url = "http://localhost/mhttest/CaptureSubmission.aspx";
m.LoadString( html, url );
m.Parse();
//save the MHT to the filesystem
string path = "c:\\temp\\" + DateTime.Now.ToFileTime() + "_sample.mht";
m.SaveToFile( path );
}
//continue sending the html to the browser
writer.Write(html);
}
VB.NET
Protected Overrides Sub Render(writer As HtmlTextWriter)
Dim sw As New System.IO.StringWriter()
Dim localWriter As New HtmlTextWriter(sw)
MyBase.Render(localWriter)
'get the contets of the page
Dim html As String = sw.ToString()
'check to see if the page was posted
If Page.IsPostBack Then
'save it to a MHT file
Dim m As New MHT()
'this is the url of this page. It's used so aspNetMHT can resolve any images.
Dim url As String = "http://localhost/mhttest/CaptureSubmission.aspx"
m.LoadString(html, url)
m.Parse()
'save the MHT to the filesystem
Dim path As String = "c:\temp\" + DateTime.Now.ToFileTime() + "_sample.mht"
m.SaveToFile(path)
End If
'continue sending the html to the browser
writer.Write(html)
End Sub 'Render
by Dave
3. March 2011 06:58
I recently had a potential aspNetMHT customer email me with the following error.
BC30002: Type 'aspNetMHT.MHT' is not defined
Their entire code page looked like:
<%@ Page Language="vb" AutoEventWireup="true" %> <script runat=server> Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Dim url As String = "http://www.google.com" 'create a MHT object referencing google.com Dim m As New aspNetMHT.MHT(url) 'parses the url into it's MHT parts m.Parse() 'create a zipped MHT file of google.com Dim filename As String = "google.zip" 'save it the filesystem. You will need write permissions to do this m.SaveToFile(Server.MapPath(filename), True) Response.Write(String.Format("Dowload the MHT file <a href='{0}'>here</a>", filename)) End Sub </script>
For anyone else out there, the resolution is as follows:
a)Be sure you import/upload the aspNetMHT.dll into your /bin directory b)Add the following commands at the top of the .aspx page <%@ Assembly Name="aspNetMHT"%> <%@ Import Namespace="aspNetMHT" %>
This will set a reference to the aspNetMHT.dll assembly (notice the .dll extension is missing from the @Assembly directive), and it imports the aspNetMHT namespace.
by Dave
3. March 2011 06:25
This article will talk about posting HTML form data to a second page, so aspNetMHT can properly render that second page.
Lets say there are 2 web pages on a remote server, PageA and PageB. PageA posts Http Form data to PageB. We want to somehow convert PageB to a MHT document. The problem is, that if we navigate directly to PageB, it does not render the expected result.
How do we correctly convert PageB to a MHT document with posted data from PageA?
We need to do this in 2 steps.
1) Determine the HTML form elements that will be posted. 2) Load them in to the MHTForm object, and submit them.
Determine the HTML Form Elements We first need to physically view the source of the rendered PageA. We need to look at all of the HTML input form elements that would normally be submitted on PageA. Some of these may look like:
<form method="post" action="PageB.aspx" > <input type="hidden" name="__VIEWSTATE" value="dDwtMT....UcE2M2Z/lA" /> What color do you like? <input name="txtColor" type="text" /> What size shirt? <input name="txtSize" type="text" /> <input type="submit" value="go" name="submit"> </form>
When this form is submitted to the server, it will send along the values of txtColor and txtSize, along with the other HTML input objects. For our purposes we will specify a color of "Red" and a size of "Large".
What we want to do, is load these HTML objects into the MHTForm, so aspNetMHT can submit them to PageB for us.
Loading the HTML Form objects into the MHTForm Object To load the HTML form elements, the easiest way, is to simply have aspNetMHT fetch PageA and automatically find them. Once they are loaded, we can set our own values.
For example: MHT m = new MHT(); m.Form.LoadForm( "http://localhost/PageA.aspx"); m.Form.AddFormValue("txtColor","Red"); m.Form.AddFormValue("txtSize","Large"); m.Form.Submit(true); m.SaveToFile("c:\\temp\\");
Below are complete working examples of this functionality.
C#
MHT m = new MHT();
m.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)";
//enable logging for any troubleshooting
m.Logger = new MHTLog( "c:\\temp\\mht.log" );
m.Logger.Overwrite = true;
m.Logger.Enabled = true;
//load the form
m.Form = new MHTForm();
m.Form.LoadForm( "http://localhost/PageA.aspx");
m.Form.AddFormValue("txtColor","Red");
m.Form.AddFormValue("txtSize","Large");
//submit the form, and save the resulting MHT file
m.Form.Submit(true);
m.SaveToFile("c:\\temp\\");
VB.NET
Dim m As New MHT()
m.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)"
'enable logging for any troubleshooting
m.Logger = New MHTLog("c:\temp\mht.log")
m.Logger.Overwrite = True
m.Logger.Enabled = True
'load the form
m.Form = New MHTForm()
m.Form.LoadForm("http://localhost/PageA.aspx")
m.Form.AddFormValue("txtColor", "Red")
m.Form.AddFormValue("txtSize", "Large")
'submit the form, and save the resulting MHT file
m.Form.Submit(True)
m.SaveToFile("c:\temp\")
As always, if anyone has any questions, feel free to contact me using the Contact Us page.
Dave Wanta
by Dave
3. March 2011 02:39
Recently I had a customer email me, that they were getting the following exception being thrown from aspNetMHT. It was:
System.IO.IOException: Unable to read data from the transport connection: The connection was closed. at System.Net.ConnectStream.Read(Byte[] buffer, Int32 offset, Int32 size)
This exception was happening when aspNetMHT was making a remote request to the webserver.
Basically, the remote webserver closing the connection.
To prevent this from happening, the following properties needed to be set:
m.HttpProtocolVersion = HttpVersion.Version10 m.HttpKeepAlive = false
Where "m" is the local MHT object.
Here is a more complete, but short, code example:
C#
//any url we want to fetch, for example, google.com
string url ="http://www.google.com";
MHT m = new MHT();
//ignore any broken links
m.Ignore404 = true;
m.HttpProtocolVersion = HttpVersion.Version10;
m.HttpKeepAlive = false;
m.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)";
//enable logging for any troubleshooting purposes
m.Logger = new MHTLog("c:\\temp\\mht.log");
m.Logger.Overwrite = true;
m.Logger.Enabled = true;
m.LoadUrl(url);
m.Parse();
m.SaveToFile("c:\\temp\\");
VB.NET
'any url we want to fetch, for example, google.com
Dim url As String = "http://www.google.com"
Dim m As New MHT()
'ignore any broken links
m.Ignore404 = True
m.HttpProtocolVersion = HttpVersion.Version10
m.HttpKeepAlive = False
m.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)"
'enable logging for any troubleshooting purposes
m.Logger = New MHTLog("c:\temp\mht.log")
m.Logger.Overwrite = True
m.Logger.Enabled = True
m.LoadUrl(url)
m.Parse()
m.SaveToFile("c:\temp\")
As always, if anyone has any questions, feel free to contact me at the Contact Us page. Dave Wanta
by Dave
9. November 2010 01:46
** NOTE: ALL OF OUR PRODUCTS RUN ON ALL VERSIONS OF .NET. **
The instructions below are for people using VS2010 and beyond.
--------------------------
As more and more people are upgrading to VS2010, and beyond, I am getting more of the following emails:
aspNetEmail (or any of our other products) doesn't work in later versions of Visual Studio. I usually get one of the following errors:
"aspNetEmail is not declared, it may be inaccessible due to its protection level."
Or
"The referenced assembly "…" could not be resolved because it has a dependency upon System.Web (or some other internal .NET namespace). Please remove references to assemblies not in the targeted framework or consider retargeting your project"
Usually these exceptions occur when the developer is building a client side application.
Starting in VS2010, VS tries to be too smart for it's own good. When you build a client application (console.exe, winform, etc…) VS limits the number of namespaces you need access too, because it thinks you shouldn't need them.
To change this behavior, what you need to do, is change the target framework from a subset of namespaces, to all of them.
To change this, in VS.NET Solution Explorer, Right-Click on your project, an select Properties. On the Application tab, set the Target Framework to be ".NET Framework XX". By default it is set to ".NET Framework XX Client Profile". Press Ctrl-S for save, and you are done.
Below are 2 pictures that display changing the target framework.
As always, if anyone has any questions, feel free to contact me.
Thanks! Dave Wanta

C# Screenshot:

VB.NET Screenshot (this option is found under the Compile tab. Then, click the "Advanced Compile Option" button.

Testimonial
 |
That [aspNetEmail] worked like a charm. :-)
"
|
 |
| Read more testimonials |
|