Thursday, December 15, 2005

"ActiveX Scripting WebPart" for SharePoint technologies

This is the new home of ActiveX Scripting WebPart that was previously located at

Comments and questions are welcome!


Yes, this sounds heretic, and it probably is :-) This is a generic sample (use it at your own risk :-) WebPart for SharePoint technologies (means it works for Microsoft Windows SharePoint Services as well as Microsoft SharePoint Portal Server 2003) that runs an ActiveX Scripting code on the server.
By default, VBScript and JScript (a.k.a JavaScript) are supported on decent Windows installations, but nothing prevents you from using Python, Perl or other languages that have an ActiveX Scripting existence. Here is an example of such a code (in VBScript) that displays the user name and the current date:

Sub Render(writer)
writer.Write "User: " & Context.User.Name & "<br>"
writer.Write "Date: " & Now
End Sub

Binaries and Source code can be downloaded from here

The WebPart can be installed using SharePoint standard deployment tools:

"%CommonProgramFiles%\Microsoft Shared\web server extensions\60\BIN\stsadm"
-force -o addwppack -filename

Or (GAC installation)

"%CommonProgramFiles%\Microsoft Shared\web server extensions\60\BIN\stsadm"
-force -o addwppack -filename
-globalinstall -url

The WebPart caches a compiled version of the scripts. If you want to disable this cache, just add the following to your web.config:
<add key="ScriptCachingMode" value="disabled" />

Using the standard WebPart modification tools provided by the SharePoint WebPart Framework (Design Page, Browse, Modify, ToolPane, ...), you can switch the WebPart from Edit Mode to Run Mode. In Edit mode, you can type the script code directly into the provided TextArea.
This script code can be put in the main procedure (the one that is not inside a declared procedure, sub or function). In this case, it will run probably at Page initialization. For example, the following script code will render the current user's login name *before* the first <html> declaration:

Context.Response.Write Context.User.Name

Or it can be placed inside predefined "Emulated" function. Supported emulated functions prototypes are (the syntax here is in VBScript):

Sub OnInit()
' Code put here will run in the OnInit method
' of the ActiveX Scripting WebPart
End Sub

Sub OnLoad()
' Code put here will run in the OnLoad method
' of the ActiveX Scripting WebPart
End Sub

Sub OnPreRender()
' Code put here will run in the OnPreRender method
' of the ActiveX Scripting WebPart
End Sub

Sub Render(writer)
' Code put here will run in the Render method
' of the ActiveX Scripting WebPart
' The Writer object has only one Write(object obj) method
' see the example at the beginning
End Sub

Sub OnUnload()
' Code put here will run in the OnUnload method
' of the ActiveX Scripting WebPart
End Sub

"Emulated" ASP.Net Object Model:
As already demonstrated before, the script code recognizes one "named object" (in ActiveX Scripting terminology) which is "Context" (sounds familiar?). From this context object, the ActiveX Scripting WebPart provides limited support for an "emulated" ASP.Net HttpContext object model. Please consult ASP.Net documentation for details on the following properties and methods.

+: Class
R: Read Only property
RW: Read Write property
M: Method):

+ Context
+ Cache
M void Insert(string key, object value)
M object Get(string key)
R int Count
M object Remove(string key)

+ Request
R int ContentLength
R string CurrentExecutionFilePath
R bool IsAuthenticated
R bool IsSecureConnection
R string Path
R string PathInfo
R string PhysicalApplicationPath
R string PhysicalPath
R string RawUrl
R string RequestType
R int TotalBytes
R string UserHostAddress
R string UserHostName
M void ValidateInput()
M void SaveAs(string filename, bool includeHeaders)
M void MapPath(string virtualPath, string baseVirtualDir,
bool allowCrossAppMapping)
R string UserAgent
R string HttpMethod
R string ContentType
RW Encoding ContentEncoding
R string ApplicationPath
R string FilePath

+ Response
RW bool SuppressContent
R bool IsClientConnected
RW bool Buffer
RW bool BufferOutput
RW string StatusDescription
RW string Charset
RW string Status
RW string CacheControl
RW string RedirectLocation
RW int Expires
RW DateTime ExpiresAbsolute
RW string ContentType
RW Encoding ContentEncoding
RW int StatusCode
M void AddHeader(string name, string value)
M void AppendHeader(string name, string value)
M void AppendToLog(string param)
M void ApplyAppPathModifier(string virtualPath)
M void BinaryWrite(byte[] buffer)
M void Pics(string value)
M void SetCookie(string name, string value)
M void TransmitFile(string filename)
M void Clear()
M void ClearContent()
M void ClearHeaders()
M void Close()
M void End()
M void Flush()
M void Redirect(string url, bool endResponse)
M void Write(object obj)

+ Server
R string MachineName
R int ScriptTimeout
M void ClearError()
M object CreateObject(string progID)
M object CreateObjectFromClsid(string clsid)
M string HtmlDecode(string s)
M string HtmlEncode(string s)
M string MapPath(string path)
M void Transfer(string path, bool preserveForm)
M string UrlDecode(string s)
M string UrlEncode(string s)
M string UrlPathEncode(string s)

+ Session (no method implemented so far..., coding anyone ?)

+ Trace
R TraceMode TraceMode
R bool IsEnabled
M void Write(string message)
M void Warn(string message)

+ User
R string Name
R string AuthenticationType
R bool IsAuthenticated
M bool IsInRole(string role)

Monday, May 23, 2005

.NET Html Agility Pack: How to use malformed HTML just like it was well-formed XML...

!! Update 06/08/18 !! The home of Html Agility Pack has changed again (hopefully for the last time...). The project is now located at CodePlex, available here:

Comments and questions are welcome!

Here is an agile HTML parser that builds a read/write DOM and supports plain XPATH or XSLT. It is an assembly that allows you to parse "out of the web" HTML files. The parser is very tolerant with "real world" malformed HTML. The object model is very similar to what proposes System.Xml, but for HTML documents (or streams).

Sample applications:

  • Page fixing or generation. You can fix a page the way you want, modify the DOM, add nodes, copy nodes, you name it.
  • Web scanners. You can easily get to img/src or a/hrefs with a bunch XPATH queries.
  • Web scrapers. You can easily scrap any existing web page into an RSS feed for example, with just an XSLT file serving as the binding. An example of this is provided.

There is no dependency on anything else than .Net's XPATH implementation. There is no dependency on Internet Explorer's dll or tidy or anything like that. There is also no adherence to XHTML or XML, although you can actually produce XML using the tool.

For example, here is how you would fix all hrefs in an HTML file:

HtmlDocument doc = new HtmlDocument();
foreach(HtmlNode link in doc.DocumentElement.SelectNodes("//a[@href"])
HtmlAttribute att = link["href"];
att.Value = FixLink(att);

You can still download the .NET Framework 1.1 version here, and for the .NET Framework 2.0 version, please go to CodePlex (link above)

Note: This page was previously located at