ASP.NET 2.0 Resources

Powered by Blogger

Analyzing and Interpreting AdSense results with Google Analytics

This post is description of other AdSense Analytics options offered by Google Analytics tracking service together with AdSense click tracking script i have developed. You can read more about this script and how it operates in previous post Tracking AdSense clicks with Google Analytics. You will need this tracking script installed and Google Analytics set up if you want to use these reporting options.

I will show you how to analyze which Ads your visitors like the most, what type of traffic converts to most clicks, where are the visitors clicking your Ads from, what Search Engine queries convert to most AdSense clicks on your pages and even a lot more. And the best part is that's all for free, the only thing you need is this free AdSense tracking script and free Google Analytics account.

Google Analytics basics

I will just repeat a little bit from how the tracking script integrates with Google Analytics. Tracking script simulates virtual directory hierarchy to Google Analytics so you can use it's reporting capabilities effectively. This hierarchy always starts with /asclick directory, is then followed by Ad group type or custom type(channel) name and the final thierd level of this hierarchy is AsSense Ad URL address or AdLinks Keyword (only available on IE). So simple AdSense click hit would be /asclick/NavigBanner/www.DirectRelief.org for NavigBanner Ad type and DirectRelief Ad.

There are some tasks common for all reports so i will mention them only once here at the very beginning. These common tasks are Comparing time ranges and Viewing overtime data trends

Comparing time ranges

Comparing time ranges is one of the neet features offered by Google Analytics user interface for many types of reports. It does precisely what it says, it compares data for two specified time ranges.

When clicking icon highlighted on the picture, the second date picker control appears so you can select second time range to compare the data to.

Comparing two time ranges with Google Analytics

Viewing overtime data trends

This feature allows you to view selected data over time. It's activated by clicking the highlighted icon and selecting "Data Over Time" option. The graphs are displayed in new window.

View overtime data trends

Ad clicks tracking

This is the most basic report and is also provided by integrated AdSense reporting. If you want to know absolute number of AdSense ad clicks, use Goal Tracking report (Content Optimization / Goals & Funnel Process / Goal Tracking). There you can see number of clicks graph over selected period and also total and average number of clicks.

If you're rather interested in click through rate (CTR) just use the next report Goal Conversion (Content Optimization / Goals & Funnel Process / Goal Conversion). Just note that this is different CTR as oposed to AdSense reports (it should be higher). Google Analytics shows you visitors CTR as oposed to page views CTR showed by AdSense reports.

Adsense for Google Analytics tracking user clicks

Ads performance tracking

Knowing how different Ad types perform is key condition for successfull AdSense sites. It's possible to track different channels with AdSense integrated reporting, but with AdSense tracking script and Google Analytics it's easier and more powerfull.

Just navigate to Content Drilldown report (Content Optimization / Content Performance / Content Drilldown). And navigate further to asclick subtree by clicking on it's icon. Now you can see different ad types in the table and also their number of visits (unique vistitor clicks) and page views (ad clicks).

Adsense for Google Analytics tracking clicked Ad types

You can see on this sample picture that i have used custom channel tracking and reporting. If you navigate even further and click on concrete ad type, you can even see how different banners or AdLinks keywords perform and what are your visitors most interested in!

Adsense for Google Analytics tracking clicked Ad texts

There are no real data on those pictures. These were taken as I was testing tracking script. But with real world data even more may be concluded...

  • If you look at Pageviews and Visits numbers in the sample, they are the same. But in real world use, they will probably be different. Pageviews can be interpretted as absolute number of Ad clicks, but the number in Visits column would not count repeated clicks by single visitor.
  • Avg Time is also very interesting. This is the average time the user stayed on the page (the page he was sent when clicking at the Ad) in case he then returned back to your page. You can see what Ads your users don't like and are comming back to your pages fast.
  • % Exit show you how many users did not come back to your pages at all and stayed on Ad page (we are of course talking about one user visit).

It's also possible to get an overview what ads are clicked the most without navitation Content Drilldown structure. We will use Goal Verification report for that (Content Optimization / Goals & Funnel Process / Goal Verification). The sample report is visible on the following picture. There is clearly visible what Ad URL's and Ad types are clicked most.

Adsense for Google Analytics tracking clicked Ad texts

Web pages performance tracking

It could also be very interesting to know what web pages generate most of the AdSense clicks. This type of report is also possible to do in AdSense integrated reporting, but it requires a lot of manual work creating url channels for different web pages. Google Analytics offers much simpler way to do this.

We will use integrated goal tracking for this report. Specifically Defined Funnel Navigation and Reverse Goal Path reports (Content Optimization / Goals & Funnel Process / Defined Funnel Navigation). As we have not defined any funnel navigation path you can see the AdSense clicks directly in the first report. Note that only 5 most effective pages are displayed on screen. If you want to see all pages use text export by clicking the T button on top.

Adsense for Google Analytics tracking most clicked pages

You can also use Reverse Goal Path report. There you can see what navigation paths lead to most AdSense clicks.

Adsense for Google Analytics tracking most clicked navigation paths

Traffic type performance

Do you ever wanted to know if visitors with highest conversion came from Search Engine of some refering site? It's also possible with Google Analytics. There are two subtypes of this report. The first type teels you what medium has the highest click through rate (CTR) and the second one is about absolute number of AdSense clicks.

We will use Medium Conversion report and goal tracking for the first type (Marketing Optimization / Marketing Campaign Results / Medium Conversion).

AdSense Google Analytics traffic type performance

The different values of Medium / Source column mean...

  • organic indicates visitors referred by an unpaid search engine listing.
  • referral indicates visitors referred by links which were not tagged with any campaign variables.
  • (not set) indicates visitors referred by links which were tagged with campaign variables but for which the medium variable was not set.
  • (none indicates visitors who visited the site by typing the URL directly into their browser.

The most interesting column for us is G1/Visit. It shows how many users comming to our pages through specific medium actually clicked on AdSense Ad. You can further navigate the hierarchy to see for example which search engine has higher conversion rate for you.

There is also very similar report for refering sites. It's Referring Source report (Marketing Optimization / Visitor Segment Performance / Referring Source).

We will learn about the second type of report in Advanced Cross segment reporting chapter.

Search Engine specific performance tracking

Have you ever wondered what queries that brought visitors to your web pages from search engine convert to most AdSense clicks? It's also possible with AdSense tracking script and Google Analytics. We will use Overall Keyword Conversion report (Marketing Optimization / Search Engine Marketing / Overall Keyword Conversion).

I have no sample picture for this type of report yet, so i will only explain this one. It's very similar to previous type of report. The only difference is there are no traffic types but search queries in the left most table column.

User segment performance tracking

Are you interested in what country came the most clicking visitors from? What language do they speak? This can also be answered by Google Analytics.

Just navigate to Geo Location and Language reports respectively (Marketing Optimization / Visitor Segment Performance / Geo Location).

AdSense Google Analytics Geo Location report

There is an old known report prepared for you. You can further navigate the Geo hierarchy to see more specific information. The language report is very similar to this one.

Advanced Cross segment reporting

There are a lot of nuggets hidden in this Google Analytics advanced feature. You can cross segment /asclick directory (or any other) from Content Drilldown report (Content Optimization / Content Performance / Content Drilldown) to many other values.

You can for example cross reference to the folowing values to get absolute visits for Adsene click goal...

  • Platform - to show clicking users platforms
  • Connection speed - for different connection options
  • Keyword - for search engine keywords
  • Visitor Type - very neat feature showing how many returning visitors click on the ads

The most powerfull feature of these reports is, that they are not restricted to simple AsSence click goal. You can cross segment individual Ad units and event individual Ad URL's!

Conclusions

Those were the options Google Analytics offers to you for AdSense click reporting. Do you have your own favorite report? Just feel free to leave me a comment.

Read more > Posted on: 3/26/2006 02:58:00 PM

Tracking AdSense clicks with Google Analytics

UPDATED: there is updated version available - AdSense tracking script v2

There are quite a few adsense click tracking systems/scripts around, but i was not satistied with any of them. Partly because they were not able to track what ad units were clicked (not even mentioning specific Ads and AdLinks keywords). But also mainly because their lack of advanced reporting capabilities. I'm using Google Analytics on my sites and i really like that user interface and reports, so i was looking for a way to integrate AdSense tracking with them.

The AdSense tracking script presented here is a result of my research. You can download free astracker.js script just now. Please first read the instuctions how to install this script and how to connect is to Google Analytics.

If you are rather interested in How to interpret AdSense clicks results with Google Analytics, please also read my post Analyzing and Interpreting AdSense results with Google Analytics

Features

  • Supports also Firefox browser
  • Tracking of clicked ad types - Type of ad unit is tracked with click. You can also setup custom type for each ad unit on page.
  • Tracking clicked URLs and Keywords - URLs or AdLinks keywords are tracked together with click.
  • Support for custom ad channels - You can easily setup custom channel (type) for each ad unit.

Known limitations

These are the limitation i have faced when using this script. If you know about any other, please leave me a comment and i will add it.

  • Tested and tweaked for Internet Explorer / Mozilla (Firefox) only
  • The clicks are tracked only after page is fully loaded - Click tracking is initialized when page onload event occurs, so before page is fully loaded no clicks can be tracked with this javascript.
  • Clicks resulting from AsLinks search results ads are not tracked - This happens on google seach server, so it's simply not possible to track those clicks.
  • Keyboard "clicks" are (usually) not tracked - When tabbing and pressing enter on AdSense ad, this click won't be tracked unless mouse pointer if also in AdSense IFrame.
  • Possible false keyboard clicks - This is the oposite of above. When the mouse pointer is on AdSense IFrame and the user uses TAB key to focus some of AdSense IFrames, false click could be reported.
  • False click reports when using two mice - Yes, this could really happen :)) When one mouse poiter is in AdSense IFrame and document unload event occurs (for example when some (non adsene) link is clicked by second mouse), false click could be reported.

Requirements

  • Presented AdSense tracking script adtracker.js
  • Working AdSense account
  • Google Analytics account (or profile)
  • Access to tracked web page source code and some web space to store javascript tracking code to (it's small around 3.5k)
  • Small knowledge of HTML to implement tracking script

How does it work?

Setup is quite simple. Small javascript file is added to your web page and that's it. This script listens for ad clicks and reports them to Google Analytics (analytics code has to be already installed in the web pages). Google Analytics interface is than used to interpret tracking results.

Compliance with Google AdSense TOS

This tracking script uses passive click monitoring and in no way alters code generated by Google AdSense. It does not interfere with Ad clicks directly, but simply listens for browser mouse and keyboard events and reports through Google Analytics tracking engine. I have reviewed AdSense TOS and did not find any issue what so ever. But if you want to be sure, go ask Google AdSense support for permittion first. Just don't expect simple Yes/No answer from them :)

Tracking Accurancy

The passive listening method used by this tracking script does not allow for 100% accurate click reporting. When compared to AdSense, my results are usually about 10-15% lower in Google Analytics goals. The limitations i know about are already mentioned in some of previous paragraphs. I would be really interested in how this script performs for you (especialy for higher traffic volumes).

Google Analytics integration

Integration with Google Analytics is achieved by manually calling urchingTracker when user clicks on AdSense Ad. Tracking script simulates virtual directory hierarchy to Google Analytics so you can use it's reporting capabilities effectively. This hierarchy always starts with /asclick directory (unless you modified this value), is followed by Ad group type or custom type(channel) name. The final thierd level of this hierarchy is AsSense ad URL address or AdLinks Keyword (note that this is not available for clicks from Firefox browser).

The example tracked URL will look like:
/asclick/336x280_as/www.DirectRelief.org
or /asclick/NavigBanner/www.DirectRelief.org (if you use custom adgroup names).

Setup procedure

The setup procedure constists of two parts. First you have to setup your web page to track AdSense clicks and report them to Google Analytics. Second part is about tweaking Google Analytics settings a bit to ease interpreting click retults.

And please be prepared to wait at least 24 hours before some AdSense tracking hits appear in your Google Analytics interface.

Web Page

  1. Download astracker.zip file containing all required files.
  2. Unzip and upload tracking javascript astracker.js somewhere to the web ideally directly to your web server.
  3. Add reference to this javascript to your web page directly below Google Analytics code (see the following example).
    <script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
    </script>
    <script type="text/javascript">
        _uacct = "UA-xxxxxx-y";
        urchinTracker();
    </script>
    </script src="/javascript/astracker.js" type="text/javascript">
    </script>
  4. Optionally tweak the page to support custom channel reporting - see Advanced Settings for further info.

Google Analytics

This procedure is not required, but it eases access to some type of reports so it's highly recomended. I will assume you followed this procedure in the examples how to interpret tracking results.

  1. Log on to your Google Analytics account and open settings for desired web page by clicking Edit link.
    Adsense for Google Analytics setup
  2. You should see "Conversion Goals and Funnel" pane with four goals (G1-G4). Click on the right Edit link for first goal (G1).
    Adsense for Google Analytics setup goals
  3. Set Goal URL to "/asclick" (without quotes), Goal name to "Adsense click" (without quotes) or whatever you like and finally set this goal as active (by checking Yes option for Active Goal)
    Adsense for Google Analytics setup goal details
  4. We won't setup any Funnel Navigation so you can now scroll down to Additional settings and just make sure Case sensitive option is NOT set and Match Type is set to Head Match
  5. Now scroll down click Save Changes button and we are set. From now on adsense clicks on your web page will be considered goal hits in Google Analytics.
    Adsense for Google Analytics setup goal Additional settings

Advanced settings

This AdSense tracking script supports custom channel tracking by wrapping adsense code in HTML element with specially predefined id. If you wrap your AdSense code to HTML element with id prefixed as asc_ (AdSense Contianer), the tracker will use the remaining portion of id and report is as Ad type. So for example if you wrap AdSense HTML code in div element with id asc_NavigBanner, the tracker will use "NavigBanner" instead of default "234x60_as" when tracking clicks for this Ad group.

<div id="asc_NavigBanner">
    <script type="text/javascript"><!--
    google_ad_client = "pub-xxxxxxx";
    google_ad_width = 160;
    google_ad_height = 600;
    google_ad_format = "160x600_as";
    google_ad_type = "text_image";
    google_ad_channel ="";
    google_color_border = "E8E7D0";
    google_color_bg = "FFFFFF"
    google_color_link = "E58712";
    google_color_url = "993333";
    google_color_text = "303030";
    //--></script>
    <script type="text/javascript"
      src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
    </script>
</div>

Final URL in Google Analytics will than apear as for example /asclick/NavigBanner/www.DirectRelief.org

Using Google Analytics Reports

Google Analytics is far more powerfull when compared to AdSense reporting capabilities. But some of the reports are also possible to produce with AdSense reporting and in such cases you should always use those reports as they are 100% accurate. Also there is no actual ad revenue and eCPM tracking in Google Analytics reports so you will still have to use AdSense center for this.

How many users clicked on AdSense ads?

If you want to know absolute number of AdSense ad clicks, use Goal Tracking report (Content Optimization / Goals & Funnel Process / Goal Tracking). There you can see number of clicks graph over selected period and also total and average number of clicks.

If you're rather interested in click through rate (CTR) just use the next report Goal Conversion (Content Optimization / Goals & Funnel Process / Goal Conversion). Just note that this is different CTR as oposed to AdSense reports (it should be higher). Google Analytics shows you visitors CTR as oposed to page views CTR showed by AdSense reports.

Adsense for Google Analytics tracking user clicks

How do I know what ad types users click the most?

As usually Google Analytics has a report prepared for you. Just navigate to Content Drilldown report (Content Optimization / Content Performance / Content Drilldown). And navigate further to asclick subtree by clicking on it's icon. Now you can see different ad types in the table and also their number of visits (unique vistitor clicks) and page views (ad clicks).

Adsense for Google Analytics tracking clicked Ad types

You can see on this sample picture that i have used custom channel tracking and reporting. If you navigate even further and click on concrete ad type, you can even see how different banners or AdLinks keywords perform and what are your visitors most interested in!

Adsense for Google Analytics tracking clicked Ad texts

There are no real data on those pictures. These were taken as I was testing tracking script. But with real world data even more may be concluded...

  • If you look at Pageviews and Visits numbers in the sample, they are the same. But in real world use, they will probably be different. Pageviews can be interpretted as absolute number of Ad clicks, but the number in Visits column would not count repeated clicks by single visitor.
  • Avg Time is also very interesting. This is the average time the user stayed on the page (the page he was sent when clicking at the Ad) in case he then returned back to your page. You can see what Ads your users don't like and are comming back to your pages fast.
  • % Exit show you how many users did not come back to your pages at all and stayed on Ad page (we are of course talking about one user visit).

It's also possible to get an overview what ads are clicked the most without navitation Content Drilldown structure. We will use Goal Verification report for that (Content Optimization / Goals & Funnel Process / Goal Verification). The sample report is visible on the following picture. There is clearly visible what Ad URL's and Ad types are clicked most.

Adsense for Google Analytics tracking clicked Ad texts

How do I know what pages generate most clicks?

This one is also quite simple. We will use integrated goal tracking for this report. Specifically Defined Funnel Navigation and Reverse Goal Path reports (Content Optimization / Goals & Funnel Process / Defined Funnel Navigation). As we have not defined any funnel navigation path you can see the AdSense clicks directly in the first report. Note that only 5 most effective pages are displayed on screen. If you want to see all pages use text export by clicking the T button on top.

Adsense for Google Analytics tracking most clicked pages

You can also use Reverse Goal Path report. There you can see what navigation paths lead to most AdSense clicks.

Adsense for Google Analytics tracking most clicked navigation paths

Google Analytics Notes

Presented were only the most basic Google Analytics reports. There is far more power hidden inside Google Analytics reporting but i want to keep this post as short as possible. So if you are interested in other reporting posibilities, please also read my other post: Analyzing and Interpreting AdSense results with Google Analytics

Read more > Posted on: 3/26/2006 12:07:00 PM

ASP.NET 2.0: Custom paging and sorting with ObjectDataSource

Today i came across some very interesting arcticles by Scott Mitchell Custom Paging in ASP.NET 2.0 with SQL Server 2005 and Sorting Custom Paged Results. I was looking for such complex info for a long time and those arcticles finally supplied all infromation together at one place. As a bonus you get some basic speed comparisons of different paging and sorting methods.

If you want custom paged and sortable ObjectDataSource you will have define some object properties (see the following ObjectDataSource declaration sample)...

<asp:ObjectDataSource 
    ID="FundListDataSource" 
    runat="server" 
    EnablePaging="True" 
    TypeName="Core.BLL.FundController" 
    SelectCountMethod="GetFundCount"     
    SelectMethod="GetFunds" 
    StartRowIndexParameterName="startrow" 
    MaximumRowsParameterName="maxrows"     
    SortParameterName="sortExpression" 
/>

ID, TypeName, runat and SelectMethod are probably familiar to you. So lets look at the others...

EnablePaging

This property turns on/off paging support for this data source. If you enable paging for ObjectDataSource control you also have to define SelectCountMethod, StartRowIndexParameterName and MaximumRowsParameterName properties.

SelectCountMethod

This property contains method name (must be static, parameterless method of TypeName type) used for geting total count of paged items.

StartRowIndexParameterName

This is the name of parameter for SelectMethod specifying starting page index.

MaximumRowsParameterName

Similar to StartRowIndexParameterName this parameter specifies how many rows to return.

SortParameterName

When using custom sorting for ObjectDataSource, this property contains name of the parameter that specifies row sorting.

This is my Bussiness Layer GetFuns method. It return list of all funds and has three parameters. First is starting data row, second is how many rows to return and the last one is our sorting expression. This method first tries to translate sortExpression from Bussiness Layer notation to Data layer notation (more about it later) and after that retrieves data from underlying Data layer.

public static List<FundInfo> GetFunds(int startrow, 
    int maxrows, string sortExpression)
{
    string translatedSortExpression = null;
    List<FundInfo> funds = null;

    if (!String.IsNullOrEmpty(sortExpression)) { 
        translatedSortExpression = 
            CBO<FundInfo>.TranslateSortParams(sortExpression);
    }

    using (IDataReader dr = 
        DataProviderFactory.CoreProvider.GetFunds(
                                startrow, 
                                maxrows, 
                                translatedSortExpression))
    {
        funds = CBO<FundInfo>.FillList(dr);
    }
    return funds;
}

Translating sortExpression to Data layer notation is quite tricky. Previously mentioned GetFunds method is used to populate web application GridView defined for example as...

<asp:GridView ID="GridView1" runat="server" 
    AllowPaging="True" AutoGenerateColumns="False"
    DataSourceID="FundListDataSource" AllowSorting="True">
    <Columns>
        <asp:BoundField DataField="ID" 
            HeaderText="ID" SortExpression="ID" />
        <asp:BoundField DataField="Name" 
            HeaderText="Name" SortExpression="Name" />
        <asp:BoundField DataField="ISIN" 
            HeaderText="ISIN" SortExpression="ISIN" />
    </Columns>
</asp:GridView>

The sort expressions comming from this Gridview are ID, Name and ISIN but Data Layer works internally with column names FND_ID, FND_NAME and FND_ISIN. Translation from one notation to another is handled by CBO's class static method TranslateSortParams. It uses reflection on FundInfo class properties which are decorated with DatabaseField atributes to translate from one notation to another.

As noted in original arcicles, for large result sets this custom paging is roughly two order of magnitudes faster than the default paging. It's implementation is not so straight forward as default paging and sorting but for large result sets together with correct database indexes it works like a charm. Definitely have a look at those arcticles too!

Read more > Posted on: 3/23/2006 02:38:00 PM

ASP.NET 2.0: Custom Resource Provider Using Sql Database

The world of Web applications is quite different from Windows forms. The solutions that perform great for Windows applications are sometimes quite pain when developing solution designed for the web. ASP.NET 2.0 introduces new feature called declarative localization expressions. It allows you to easily localize web pages and by default it uses .resx files stored in App_LocalResources and App_GlobalResources folders in your web application. Visual studio 2005 supports easy resource creation for each web page by "Generate local resources..." menu entry. Localization to different language/culture is so simple as copying and renaming this automatically generated file and adding desired locale code to it's file name.

But there are also some drawbacks when using this in ASP.NET 2.0 web applications...

  • The resource files (satelite assemblies) are locked all the time, the application is running (it's not easy to update there localized resources).
  • It's difficult (if not impossible) to manage these resources directly from your own web application (for example let the user create new localization or edit existing ones on ther own).

But wait, we are in ASP.NET 2.0. Many thing can be extended and so this Resource provider can be. All you need is simply create your own ResourceProviderFactory based on ResourceProviderFactory class and modify web.config file. Now imagine, you could have your resources stored in Sql (or any other) database.

public sealed class SqlResourceProviderFactory : ResourceProviderFactory
{
    public override IResourceProvider 
        CreateGlobalResourceProvider(string classKey) {
        return new SqlResourceProvider(null, classKey);
    }
    public override IResourceProvider
        CreateLocalResourceProvider(string virtualPath) {
        return new SqlResourceProvider(virtualPath, null);
    }
}

And coresponding declaration in web.config file...

<system.web>
    <globalization 
        resourceProviderFactoryType="Core.Localization.SqlResourceProviderFactory"/>
    ...

This is all you need (except of course writing your own localization resource provider) to swap ASP.NET 2.0 core resource management functionality and suply your own implementation. The ResourceProviderFactory contains two methods...

  • CreateGlobalResourceProvider - used for creating provider for global resources (accessed by GetGlobalResourceObject method or those declaratively used as <%$ Resources:Class, ResourceID %>)
  • CreateLocalResourceProvider - used for local resources (accessed by GetLocalResourceObject method or those declaratively used as meta:resourcekey="Button1")

The IResourceProvider interface that is return by these two methods contains definition for following method and property.

object GetObject(string resourceKey, CultureInfo culture)
IResourceReader ResourceReader

The GetObject method is used to get resource by resourceKey string and specific culture, where ResourceReader property returns all resources for specified virtualPath and current culture. I will not discuss any other details, instead i'm providing links to some custom database ResourceProviders implemented by other users...

Read more > Posted on: 3/22/2006 01:12:00 PM

Troubles using Autodesk DFW viewer ActiveX 3D API

In past few days I was looking for a solution how to display and control 3D DWF files using Autodesk DWF viewer 6.5. I have faced so many problems and also found some solutins that I've decided to share with You. But first some background about DWF viewer for those who haven't seen it before.

Autodesk® DWF™ Viewer allows you to easily view and print 2D and 3D designs in the DWF format, the ideal way to accurately share design information with team members. DWF viewer is available for free download from Autodesk website. It allows you to...

  • Access data integral to engineering and architectural design review including drawing scale, precise design coordinates, sheet set details, and object and markup properties.
  • Easily view and navigate drawings, maps, and 3D models without the software that created them.
  • View and print engineering and architectural files accurately with the same rendering engine as AutoCAD® software.
Many Autodesk products support saving to DWF format: AutoCAD® 2006, Autodesk® Architectural Desktop 2006, Autodesk® Building Systems 2006, Autodesk® Civil 3D® 2006, Autodesk Inventor® 9 and 10, Autodesk® Land Desktop 2006, Autodesk® Mechanical Desktop® 2006, Autodesk® Revit® Building 8, Autodesk® Revit® Structure, Autodesk® VIZ 2006, Autodesk® 3ds Max® 8.

DWF viewer is also available as ActiveX plugin for Microsoft Internet Explorer. The plugin supports API interface, so you can control opened DWF file programmatically. This API documentation is far from complete, but lets start from the beginning. Integrating DWF viewer with your website is quite easy...

<object id="ADViewer" classid="clsid:A662DA7E-CCB7-4743-B71A-D817F6D575DF"
 codebase="http://www.autodesk.com/global/dwfviewer/installer/DwfViewerSetup.cab"
 border="1" width="640" height="480">
    <param name="src" value="Engine.dwf">
    <param name="ToolbarVisible" value="False">
    <param name="UserInterfaceEnabled" value="False">
</object>

There are a few parameters that are worth mentioning. I was integrating DWF viewer with the following assumptions:

  • Hide all user control interfaces (the viewer will be controled from outside using javascript)
  • Establish two way communication channel between viewer and web application
So what those parameters mean. ToolbarVisible set to False hides user toolbar (on top of viewer), UserInterfaceEnabled parameter controls right mouse click context menu and src attribute points out to DWF file being visualized.

Autodesk DWF Viewer 6.5 contains new feature bottom navigation bar. This bar visibility cannot be controlled with object tag parameter, but luckily there is other way. This navbar can be disabled just after DWF document is loaded in viewer with following javascript code.

<script type="text/javascript" for="ADViewer"
 event="OnEndLoadItem(bstrItemName,vData,vResult)">
    if (bstrItemName == "DOCUMENT")
    {
        ADViewer.ExecuteCommandEx("NAVBAR", false);
    }
</script>

The code listens for DOCUMENT OnLoad event for ADViewer object and sends NAVBAR disable command to it. This is not documented in official API and may change in feature releases of Autodesk DWF viewer. So are the following commands that we will use. The whole 3D API is not yet officially supported.

<script type="text/javascript">
function fitToWindow() {
    ADViewer.ExecuteCommand("FITTOWINDOW");     
}
    
function setView() {
    ADViewer.ExecuteCommand("STANDARD_VIEW_FRONTTOPLEFT");         
}
            
function selectPart()    
{    
    ADViewer.ExecuteCommandEx("INVERTSELECTION", 0);
    ADViewer.ExecuteCommandEx("HIDE", 0);
    fitToWindow();
}
    
function showAll()    
{    
    ADViewer.ExecuteCommandEx("SHOWALL", 0);
    setView();
    fitToWindow();
}        
</script>

fitToWindow function is quite easy, it fits current object to occupate whole window. The setView functions sets standard camera view (Front Top Left) and showAll function shows all objects.

The last function selectPart is where i failed to find a solution. This function should select object by it's id or anything, hide all other objects and fit the selected object to whole window. I was able to programmatically hide other object when the object was already selected with mouse, I was able to fit the selected part to whole window. But there is no way to select single object (part) from javascript. There was rudimentary 3D API support in older Autodesk DWF viewer 6.0, but it has changed and I didn't find any usable API function in viewer 6.5.

I have spent almost all day diging into all ActiveX interfaces, searching over the internet with no luck. I didn't find solution for such simple task as selecting part from my javascript code (neither in official API /which does not exist for 3D files/ nor on the internet). There is a lot of discussin about lacking 3D support on Autodesk support forums, but without solutions. They always suggest to wait for feature version that might have 3D API support, but those discussions are dated from the year of 2003.

Read more > Posted on: 3/10/2006 08:56:00 AM

Microsoft Anti-Cross Site Scripting Library V1.0

Microsoft Anti-Cross Site Scripting Library V1.0 has been released.

Cross Site Scripting problem is that many Web pages display input that is not validated. If input is not validated, malicious script can be embedded within the input. If a server-side script then displays this non-validated input, the script runs on the browser as though the trusted site generated it.

The new .NET library from Microsoft is supported on Windows 2000, Windows XP, and Windows 2003, and can be used with .NET 1.0, .NET 1.1, and .NET 2.0. The library exposes these two methods: HtmlEncode and UrlEncode (taking a single string paramter). These are the same methods as found in the System.Web.HttpUtility namespace in the .NET Framework today. The new library takes the approach with a method called "white-listing" or implementing the "principle of inclusions". This means it looks for what's good and considers everything else as bad and replaces those characters with their escape character equivalents.

Read more > Posted on: 3/02/2006 10:44:00 AM

Generating PDF documents with .NET

I was looking for a way to generate PDF documents in ASP.NET pages on the fly. When searching the net i came across a cool guide How to select PDF component for .NET. It covers many commercial and also some open source PDF generators. There are very nice comparison tables available. There is mentioned one open source project iTextSharp. When searching further i have also discovered an open source XHTML to PDF converter PDFizer.

iTextSharp

iText# (iTextSharp) is a port of the iText open source java library written entirely in C# for the .NET platform. iText# is a library that allows you to generate PDF files on the fly. To use iTextSharp, you create a Document object, and then create a PdfWriter that listens to the Document and directs its output to a stream which could be a FileStream or some other type of stream entirely. You then use methods of the Document to add content. When you close the document, the writer takes everything you've dumped into the document and outputs it as a PDF file.

iTextSharp can handle quite a bit of advanced PDF formatting including embedded TrueType fonts, tables, links, outlines, graphics, and more. However, the documentation is limited to a set of online tutorials, and support is via the SourceForge discussion board for the project only.

PDFizer

A XHTML to PDF converter: with this library, you can transform simple XHTML pages to nice and printable PDF files. This project is based on the excellent webzine article "Pdfizer, a dumb HTML to PDF converter, in C#" written by Jonathan de Halleux.

Read more > Posted on: 3/01/2006 08:05:00 PM

C# 2.0 Features: Static Classes

C# 2.0 contains one very nice feature called static classes. Maybe you already encountered situation where creating instance of some class was useless because it contained only static methods. In C# 1.1 you would have to create sealed class with private contructor to disable creation of instances and deriving your class.

public class MyUtilities {
    private MyUtilities() {}
    
    public static string HelloWorld() {
        return "Hello world";
    }
}

In C# you can declare class as static.

public static class MyUtilities
{  
   public static string HelloWorld() {
           return "Hello world";
   }
}

The C# 2.0 compiler will not allow you to add a non-static member to a static class, and will not allow you to create instances of the static class as if it were an abstract class. In addition, you cannot derive from a static class. It's as if the compiler adds both abstract and sealed to the static class definition. Note that you can define static classes but not static structures, and you can add a static constructor.

Read more > Posted on: 3/01/2006 07:30:00 PM

Created dolly