Chrome Problems


Fig 1 IE with Silverlight ve:Map component

With the introduction of Chrome, Google has thrown down the gauntlet to challenge IE and Firefox. Out of curiosity I thought it would be interesting to download the current Chrome Beta and see what it could do with some of the interfaces I’ve worked on. Someone had recently quipped, “isn’t all of Google Beta?” I guess the same could be said of Amazon AWS, but then again in the “apples to apples” vein, I decided to compare IE8 Beta and Chrome Beta. The above screen shot shows an example of the new Silverlight ve:Map component in an ASP Ajax running on II6. The browser is IE8 beta in Vista, and surprise, not, it all works as expected.


Fig 2 Chrome with Silverlight ve:Map component

Also not surprisingly, the same Silverlight ve:Map component in an ASP Ajax site fares poorly in Chrome. In fact the component appears not at all, while curiously the menu asp:MenuItems act oddly. Instead of the expected drop down I get a refresh to a new horizontal row?


Fig 3 IE with Silverlight ve:Map component

Moving on to a Google Map Component embedded in the same ASP page, IE8 beta displays the map component including the newer G_SATELLITE_3D_MAP map type. ASP drop down menu and tooltips all work.


Fig 4 Chrome with Silverlight ve:Map component

Since this is a Google Map Component I would be disappointed if it did not work in Chrome, and it does. Except, I noticed the G_SATELLITE_3D_MAP control type is missing? I guess Chrome Beta has not caught up with Google Map Beta. Again the ASP Menu is not functional.


Fig 5 IE Google Map Control with Earth Mode – G_SATELLITE_3D_MAP

Back to IE to test the 3D Earth mode of my Google Map Component.As seen above it all works fine.


Fig 6 IE Silverlight Deep Earth

Now to check the new Silverlight DeepEarth component in IE. DeepEarth is a nice little MultiScaleTile source library for smoothly spinning around the VE tile engines. It works as amazingly smooth as ever.


Fig 7 Google Chrome Deep Earth

However, in Chrome, no luck, just a big white area. I suppose that Silverlight was not a high priority with Chrome.


Fig 8 IE SVG hurricane West Atlantic weather clip

Switching to some older SVG interfaces, I took a look at the Hurricane clips in the West Atlantic. It looks pretty good, Hanna is deteriorating to a storm and Ike is still out east of the Bahamas.


Fig 9 Chrome SVG hurricane West Atlantic weather clip

On Chrome it is not so nice. The static menu side of the svg frames shows up but the image and animation stack is just gray. Clicking on menu items verifies that events are not working. Of course this SVG is functional only in the Adobe SVG viewer, but evidently Chrome has some svg problems.


Fig 10 IE ASP .NET 3.5

Moving back to IE8, I browsed through a recent ASP .NET 3.5 site I built for an Energy monitoring service. This is a fairly complete demonstration of ListView and Linq SQL and it of course works in IE8 beta.


Fig 11 Chrome ASP .NET 3.5

Surprisingly, Chrome does a great job on the ASP .NET 3.5. Almost all the features work as expected with the exception of the same old Menu problems.


Fig 12 IE SVG OWS interface

Finally I went back down memory lane for an older OWS interface built with the SVG, using the Adobe Viewer variety. There are some glitches in IE8 beta. Although I can still see WMS and WFS layers and zoom around a bit , some annoying errors do pop up here and there. Adobe SVG viewer is actually orphaned, ever since Adobe picked up Macromedia and Flash, so it will doubtless receed into the distant past as the new browser generations arrives. Unfortunately, there is little Microsoft activity in SVG, in spite of competition from the other browsers, Safari, Firefox, and Opera. It will likely remain a 2nd class citizen in IE terms as SIlverlight’s intent is to replace Flash, which itself is a proprietary competitor to SVG.


Fig 13 Chrome SVG OWS interface

Chrome and Adobe SVG are not great friends. Rumor has it that Chrome intends to fully support SVG, so if I ever get around to it, I could rewrite these interfaces for Firefox, Opera, Chrome 2.0.

Summary:
Chrome is beta and brand new. Although it has a lot of nice features and a quick clean tabbed interface, I don’t see anything but problems for map interfaces. Hopefully the Google Map problems will be ironed out shortly. There is even hope for SVG at some later date. I imagine even Silverlight will be supported grudgingly since I doubt that Google has the clout to dictate useage on the internet.

TatukGIS – Generic ESRI with a Bit Extra


Fig1 basic TatukGIS Internet Server view element and legend/layer element

TatukGIS is a commercial product that is basically a generic brand for building GIS interfaces including web interfaces. It is developed in Gdynia Poland:


The core product is a Developer Kernel, DK, which provides basic building blocks for GIS applications in a variety of Microsoft flavors including:

  • DK-ActiveX – An ActiveX® (OCX) control supporting Visual Basic, VB.NET, C#, Visual C++
  • DK.NET – A manageable .NET WinForms component supporting C# and VB.NET
  • DK-CF – A manageable .NET Compact Framework 2.0/3.5 component – Pocket PC 2002 and 2003, Windows Mobile 5 and 6, Windows CE.NET 4.2, Windows CE 5 and 6
  • DK-VCL – A native Borland®/CodeGear® Delphi™/C++ Builder™

These core components have been leveraged for some additional products to make life a good deal easier for web and PDA developers. A TatukGIS Internet Server single server deployment license starts at $590 for the Lite Edition or $2000 per deployment server for the full edition in a web environment. I guess this is a good deal compared to ESRI/Oracle licenses, but not especially appealing to the open source integrators among us. There is support for the whole gamut of CAD, GIS, and raster formats as well as project file support for ESRI and MapInfo. This is a very complete toolkit.

The TatukGIS Internet Server license supports database access to all the usual DBs: "MSSQL Server, MySQL, Interbase, DB2, Oracle, Firebird, Advantage, PostgreSQL… " However, support for spatial formats are currently only available for Oracle Spatial/Locator and ArcSDE. Support for PostGIS and MS SQL Server spatial extensions are slated for release with TatukGIS IS 9.0.

I wanted to experiment a bit with the Internet Server, so I downloaded a trial version(free)..

Documentation was somewhat sparse, but this was a trial download. I found the most help looking in the sample subdirectories. Unfortunately these were all VB and it took a bit of experimental playing to translate into C#. The DK trial download did include a pdf document that was also somewhat helpful. Perhaps a real development license and/or server deployment license would provide better C# .NET documentation. I gather the historical precedence of VB is still evident in the current doc files.

The ESRI influence is obvious. From layer control to project serialization, it seems to follow the ESRI look and feel. This can be a plus or a minus. Although very familiar to a large audience of users, I am afraid the ESRI influence is not aesthetically pleasing or very smooth. I was able to improve over the typically clunky ArcIMS type zoom and wait interface by switching to the included Flash wrapper (simply a matter of setting Flash="true").

The ubiquitous flash plugin lets the user experience a somewhat slippy map interface familiar to users of Virtual Earth and Google Maps. We are still not talking a DeepZoom or Google Earth type interface, but a very functional viewer for a private data source. I was very pleased to find how easy it was to build the required functionality including vector and .sid overlays with layer/legend manipulation.

This is a very simple to use toolkit. If you have had any experience with Google Map API or Virtual Earth it is quite similar. Once a view element is added to your aspx the basic map interface is added server side:

<ttkGIS:XGIS_ViewerIS id="GIS" onclick=”GIS_Click" runat="server" OnPaint="GIS_Paint" Width="800px" Height="600px" OnLoad="GIS_Load" BorderColor="Black" BorderWidth="1px" ImageType="PNG24" Flash="True"></ttkGIS:XGIS_ViewerIS>

The balance of the functionality is a matter of adding event code to the XGIS_ViewerIS element. For example :

    protected void GIS_Load(object sender, EventArgs e)
    {
       GIS.Open( Page.MapPath( "data/lasanimas1.ttkgp" ) );
       GIS.SetParameters("btnFullExtent.Pos", "(10,10)");
       GIS.SetParameters("btnZoom.Pos", "(40,10)");
       GIS.SetParameters("btnZoomEx.Pos", "(70,10)");
       GIS.SetParameters("btnDrag.Pos", "(100,10)");
       GIS.SetParameters("btnSelect.Pos", "(130,10)");

       addresslayer = (XGIS_LayerVector)GIS.API.Get("addpoints19");
    }

The ttkgp project support allows addition of a full legend/layer menu with a single element, an amazing time saver:

<ttkGIS:XGIS_LegendIS id="Legend" runat="server" Width="150px" Height="600px" ImageType="PNG24" BackColor="LightYellow" OnLoad="Legend_Load" AllowMove="True" BorderWidth="1px"></ttkGIS:XGIS_LegendIS>

The result is a simple functional project viewer available over the internet, complete with zoom, pan, and layer manipulation. The real power of the TatukGIS is in the multitude of functions that can be used to extend these basics. I added a simple address finder and PDF print function, but there are numerous functions for routing, buffering, geocoding, projection, geometry relations etc. I was barely able to scratch the surface with my experiments.


Fig2 – TatukGIS Internet Server browser view with .sid imagery and vector overlays

The Bit Extra:
As a bit of a plus the resulting aspx is quite responsive. Because the library is not built with the MS MFC it has a performance advantage over the ESRI products it replaces. The TatukGIS website claims include the following:

"DK runs some operations run even 5 – 50 times faster than the leading GIS development products"

I wasn’t able to verify this, but I was pleased with the responsiveness of the interface, especially in light of the ease of development. I believe clients with proprietary data layers who need a quick website would be very willing to license the TatukGIS Internet Server. Even though an open source stack such as PostGIS, Geoserver, OpenLayers could do many of the same things, the additional cost of development would pretty much offset the TatukGIS license cost.

The one very noticeable restriction is that development is a Windows only affair. You will need an ASP IIS server to make use of the TatukGIS for development and deployment. Of course clients can use any of the popular browsers from any of the common OS platforms. Cloud clusters in Amazon’s AWS will not support TatukGIS IS very easily, but now that GoGrid offers Virtual Windows servers there are options.


Fig3 – TatukGIS Internet Server browser view with DRG imagery and vector overlays

Fig4 – TatukGIS Internet Server browser result from a find address function

Summary: TatukGIS Internet Server is a good toolkit for custom development, especially for clients with ESRI resources. The license is quite reasonable.

Virtual Earth – DeepEarth – Deep Pockets


Fig 1 Browser Virtual Earth Map control with KML overlay in 3D

Microsoft has released a new set of controls with Silverlight 2.0Beta, including the Virtual Earth Map control, Microsoft.Live.ServerControls.VE. This makes it even easier for cross browser map interface solutions. Silverlight like Flash requires a client side code download, which is available for IE, FireFox, Opera, and Safari. This control introduces VE Map to Microsoft’s version of declarative xml vector graphics in the browser, building on the older work of SVG. Having a VE Map control available cross browser makes VE more competitive with Google Map API. Having a Map control with C# event coding rather than javascript makes life for developers more interesting.

The release of SQL Server 2008 and its spatial extensions makes this control even better from a developers perspective. I am looking forward to seeing how to use Linq Sql to tie together spatial Sql Server datasets and VE map controls.

In order to use this control you must register both a Silverlight and a VE Assembly:

<%@ Register Assembly="System.Web.Silverlight"
Namespace="System.Web.UI.SilverlightControls"
TagPrefix="asp" %>

<%@ Register assembly="Microsoft.Live.ServerControls.VE"
namespace="Microsoft.Live.ServerControls.VE"
tagprefix="ve" %>

Once these are added to your aspx page the control element itself looks like this:

<ve:Map ID="Map1" runat="server"
Height="100%" Width="100%"
ZoomLevel="5" Center-Latitude="38" Center-Longitude="-105"
MapStyle="Shaded" MiniMap="True"
MiniMapYoffset="150" MiniMapXoffset="10"
ShowFindControl="False" DashboardSize="Normal" />

This Map1 element has a host of properties and methods as this subset snapshot shows:


Fig 2 Sampling of <ve:Map> properties in the Visual Studio 2008 properties frame

Code behind cs can include any of the Map1 behaviors:

using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using Microsoft.Live.ServerControls.VE;

public partial class display_displayVE : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)····
    {
        if (!Page.IsPostBack)········
           {···········
	Map1.Clear();······
	ShapeLayer shplayer = new ShapeLayer();··
	Map1.AddShapeLayer(shplayer);·········

	ShapeSourceSpecification shapeSpec =
		new ShapeSourceSpecification(DataType.ImportXML,
		"http://localhost/brat/kml/Track.kml", shplayer);············

	Map1.ImportShapeLayerData(shapeSpec, "", true);········
         }····
     }
}

Listing 1 sample C# use of Map1 control in code behind

All of the previous VE Javascript SDK Javascript SDK should now have their equivalent in C#. I can use C# to interact with the VE map object including 3D mode, Traffic overlays, Routing, Geocoding, and Location Find, which means a quick easy way to add full featured maps to any business app. This map object is part of the Silverlight 2.0Beta.

Another interesting part of 2.0Beta is the MultiScaleImage or DeepZoom. I played with this earlier in a simplistic fashion but there is a nice feature I didn’t notice, MultiScaleTileSource. This lets a user add an alternative tile source which has lots of applications. Here is a pretty one by Mike Ormund, coding the Mandelbrot Set as a MultiScaleImage with a custom MultiScaleTileSource:


Fig 3 Mandelbrot Set with DeepZoom MultiScaleTileSource

Here is another blog with some details on using the Silverlight MultiScaleImage with MultiScaleTileSource: http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2008/06/25/10536.aspx

The logical extension of this from a GIS perspective is DeepEarth. DeepEarth is a CodePlex project that applies the MultiScaleTileSource to a Silverlight Map interface. The current version supports the Microsoft Virtual Earth Engine which is interesting in its own right, but can be modified to use other tile source such as Google Map, or any WCS source of your choice. DeepEarth is a fascinating interface. The mousewheel spin zoom and pan is addictive with all the fade in/out animation. This project also has a beautiful little navigation tool, seen in the upper left corner. Clicking on the navigation tool does a little spin sprocket animation to open and close the tool set. However, the real fun is just wheel spin zooming.


Fig 4 Deep Earth Silverlight with MulticaleImage tile sourced to the VE engine. A static image does not do it justice. Deep Earth really invites playing!

Because this directly accesses the VE tile engine it of course will not be legitimate without changes to the Microsoft license restrictions. Here is a quick summary of the commercial VE license:

"Standard version license is $8000 for 1,000,000/year transactions = 8,000,000/year tile renders. Note: no routing in standard
Advanced version license is $15,000 for 1,500,000/year transactions = 12,000,000/year tiles. Includes routing capability"

8,000,000 annual tile renders sounds like a lot of tiles, but playing with the DeepEarth interface and watching tiles roam in and out of view made me wonder. If you put up a public site, for example, what would be an average transaction number per view? I tested a zoom from world down to my house rooftop. Checking against the cached tiles C:\Users\user\AppData\Local\Microsoft\Windows\Temporary Internet Files\Low\Content.IE5 gave 540 tile images. This is just a little bitty zoom though, and I can see an average user stacking up even ten times this amount, but for sake of argument, let’s assume a mere 1000 tile rendering count per site view. Gulp, this leads to only about 8000 user views per year or 22 per day before the overage rates kick in:

"An overage rate (generally $0.01 per transaction) is listed for exceeding the preset number of transactions for use during the term."
Recalling there are 8 render tiles per transaction 0.01/8*1000 = $1.25 per viewer use of the interface!

Even if the Microsoft license were to allow direct VE access, I wonder what will be the chances of a commercial version of this type of interface. It also makes me wonder what kinds of tile rendering counts are generated on the Virtual Earth control? Checking the tile cache after using ve:Map reveals 320 tiles. So roughly 2/3 the count but still $0.80 per view. Seems to be a very useful metric to have before committing to a public website. If my rough calculations are correct then ve:Map could lead to DeepPockets more than DeepEarth.

An alternative to the VE Map control is the now venerable Google Map API recently updated with the Earth mode which gives the browser a bit of the Google Earth 3D view. The license is different:

"Google license: $10,000 annual license fee + page views over 2,000,000/annual"

I guess I would like some clarification on the ‘render transactions’ license of Virtual Earth versus the Google Map license of ‘page views’, but the Google license seems to compare rather favorably based on page views rather than tile renders. I checked the tile cache for a similar navigation using the Google GMap2 object and get about 600 tiles. However, for GMap2 objects this is irrelevant, since there is just a single page view regardless of the navigation tiles downloaded. In this light GMap2 looks really good at $0.005 per user view versus ve:Map at $0.50-$1.00 per user view. This is a 100:1 cost ratio so VE MAP team might need to revisit their pricing. I hope Microsoft can be more competitive eventually, since ve:Map is a nice SIlverlight control. It would also be nice to have some real use metrics for a reality check.


Fig 5 Google Map api control with the new Earth view

Summary:
DeepEarth is a beautiful interface and shows the power of the MultiScaleTileSource, but even if licensing allowed direct access to the VE tile engine or Googles tile engine, it appears cost would make it prohibitive. However, MultiScaleTileSource can be tied to much less ambitious tile engines (free). I am thinking about the WCS ImageMosaic Plugin of the GeoServer project. I imagine adequate performance would require prebuilding a GeoWebCache tile cache. In this scenario the webservice MultiScaleImage can tie into proprietary WCS imagery and still provide the beautiful interactivity of DeepEarth on a more limited scale. Not a bad interface for 6" GDS aerial imagery.

A quick look at GoGrid


Fig 1 a sample ASP .NET 3.5 website running on a GoGrid server instance

GoGrid is a cloud service similar to AWS.( http://www.gogrid.com ) Just like Amazon’s AWS EC2, the user starts a virtual server instance from a template and then uses the instance like a dedicated server. The cost is similar to AWS, starting at about $0.10 per hour for a minimal server. The main difference from a user perspective is the addition of Windows servers and an easy to use control panel. The GoGrid control panel provides point and click setup of server clusters with even a hardware load balancer .

The main attraction for me is the availability of virtual Windows Servers. There are several Windows 2003 configuration templates as well as sets of RedHat or CentOS Linux templates:
· Windows 2003 Server (32 bit)/ IIS
· Windows 2003 Server (32 bit)/ IIS/ASP.NET/SQL Server 2005 Express Edition
· Windows 2003 Server (32 bit)/ SQL Server 2005 Express Edition
· Windows 2003 Server (32 bit)/ SQL Server 2005 Workgroup Edition
· Windows 2003 Server (32 bit)/ SQL Server 2005 Standard Edition

The number of templates is more limited than EC2 and I did not see a way to create custom templates. However, this limitation is offset by ease of management. For my experiment I chose the Windows 2003 Server (32 bit)/ IIS/ASP.NET/SQL Server 2005Express Edition. This offered the basics I needed to serve a temporary ASP web application.

After signing up, I entered my GoGrid control panel. Here I can add a service by selecting from the option list.


Fig 2- GoGrid Control Panel

Filling out a form with the basic RAM, OS, and Image lets me add a WebbApp server to my panel. I could additionally add several WebAPP servers and configure a LoadBalancer along with a Backend Database server by similarly filling out Control Panel forms.This appears to take the AWS EC2 service a step further by letting typical scaling workflows be part of the front end GUI. Although scaling in this manner can be done in AWS it requires installation of a software Load Balancer on one of the EC2 instances and a manual setup process.


Fig 3 – example of a GoGrid WebAPP configuration form

Once my experimental server came on line I was able to RemoteDesktop into the server and begin configuring my WebAPP. I first installedthe Microsoft .NET 3.5 framework so I could make use of some of its new features. I then copied up a sample web application showing the use of a GoogleMap Earth mode control in a simple ASP interface. This is a display interface which is connected to a different database server for displaying GMTI results out of a PostGIS table.

Since I did not want to point a domain at this experimental server, I simply assigned the GoGrid IP to my IIS website. I ran into a slight problem here because the sample webapp was created using .NET 3.5System.Web.Extensions. The webapp was not able to recognize the extension configurations in my WebConfig file. I tried copying the System.Web.Extensions.dlls into my webapp bin file. However, I was still getting errors. I then downloaded the ASP Ajax control and installed it on the GoGrid server but still was unable to get the website to display. Finally I went back to Visual Studio and remade the webapp using the ASP.NET Web App template without the extensions. I was then able to upload to my GoGrid server and configure IIS to see my website as the default http service.

There was still one more problem. I could see the website from the local GoGrid system but not from outside. After contacting GoGrid support I was quickly in operation with a pointer to the Windows Firewall which GoGrid Support kindly fixed for me. The problem was that theWindows 2003 template I chose does not open port 80 by default. I needed to use the Firewall manager to open port 80 for the http service. For those wanting to use ftp the same would be required for port 21.

I now had my experimental system up and running. I had chosen a 1Gb memory server so my actual cost on the server is $0.19/hour which is a little less for your money than the AWS EC2:

$0.10Small Instance (Default)
1.7 GB of memory, 1 EC2 Compute Unit (1 virtual core with 1 EC2 Compute Unit), 160 GB of instance storage, 32-bit platform

But again, running ASP .NET 3.5 is much more complex on EC2, requiring a Mono installation on a Linux base. I have not yet tried that combination and somehow doubt that it would work with a complex ASP .NET 3.5 website, especially with Ajax controls.

The GoogleMap Control with the Earth mode was also interesting. I had not yet embedded this into an ASP website. It proved to be fairly simple. I just needed to add a <asp:ScriptManager ID=”mapscriptmanager” runat=”server”/> to my site Master page and then the internal page javascript used to create the GoogleMap Control worked as normal.

I had some doubts about accessing the GMTI points from the webapp since often there are restrictions using cross domain xmlhttpRequests. There was no problem. My GMTI to KML servlet produces kml mime type "application/vnd.google-earth.kml+xml" which is picked up in the client javascript using the Google API:·
geoXml = new GGeoXml(url);

Evidently cross domain restrictions did not apply in this case, which made me happy, since I didn’t have to write a proxy servlet just to access the gmti points on a different server.

In Summary GoGrid is a great cloud service which finally opens the cloud to Microsoft shops where Linux is not an option. The GUI control panel is easy to use and configuring a fully scalable load balanced cluster can be done right from the control panel. GoGrid fills a big hole in the cloud computing world.

Server Side Detour


Fig 1 – ASP using Ajax ToolKit and LinqDataSource

It has been a while since I used one of the server side web frameworks. Microsoft .NET 3.5 ASP has some attraction, especially since the announcement of SQL Server 2008 geospatial functionality along with Silverlight, WPF, and DeepZoom. There are even hints of a Virtual Earth map element for use in Silverlight. I decided to take a learning detour into ASP Land.

JSP is similar to ASP but never seemed compelling to an individual developer without the division of skill sets found in larger teams. By coding my own servlets instead of deferring to a JSP engine, I found I had more control that translated well into the ping-pong dynamic rendering now called AJAX. My prior experience with server generated html using JSF was not especially fruitful either. Admittedly it was a number of years ago when JSF was quite new, but at that time it was, you might charitably say, “clunky.” The round trips to the server for every little user interaction were not conducive to a good user experience. I guess I didnt find the complexity of a server side JSF layer too compelling, since I could manipulate SVG myself with javascript and send Msxml.XMLHTTP for any parts of my SVG that needed dynamic re-rendering. Now that higher bandwidth is more common, round trips are a bit more responsive but refresh blinks are still noticeable.

With this history in mind I started into ASP land with some reservation.

Microsoft has a very extensive set of tools available for the web developer. The basic ASP controls are all there as well as Linq to SQL, and Ajax Control Kit so ASP has come a lot further than the early days of JSF. The price is a steep learning curve with a wide range of technologies to pull together. Visual Studio 2008 makes a lot of these technologies a matter of drag and drop which means that things are easier to create but more difficult to understand or tweak.

C# is a nice language for pulling all the disparate pieces together, especially since it is so close to Java in syntax and semantics. Stephen Walthers book, ASP .NET 3.5 Unleashed was an invaluable reference for my detour through ASP.

Oversimplified, ASP, like JSP, adds special namespace controls that can be interspersed into normal html. The resulting web form files named with an .aspx extension are dynamically compiled on the server. This server side code in turn is used to create html sent back to the client browser. In addition to Javascript, ASP lets you have a lot of server side control with partial class code-behind created for each aspx page. One nice benefit is that much of the idiosyncrasies between browsers is handled by the compiler instead of the developer.

I was given an opportunity to volunteer for an energy calculator website that required a fairly complex MS SQL Server schema. This was ideal for learning ASP. I was able to adapt the SQL Server Membership capabilities to suit the website requirementsby adding some additional fields to the default aspnet_Users table of ASPNETDB.mdf. Once I had basic registration and login, complete with email notification and role based security, I could move on to the basic web application.

The first iteration involved using the new .NET 3.5 ListView control to create a basic CRUD interface (Create, Read, Update, Delete) to the required tables. ListView is a powerful Control with a great deal of flexibility. It took a little to learn all the ins and outs of events attached to the control, but I eventually had a basic approach worked out. I soon learned that Master pages simplify life considerably. Paying attention to the hierarchy of a sites page layout lets a developer abstract the unchanged into Master pages. As you go deeper into the web application a hierarchy of nested Master pages seemed to work best.

I started building my ListView controls referenced to a SqlDataSource like this:

        <asp:SqlDataSource
            id="electricitysql"
            SelectCommand="SELECT
                    Electricity.*,
                    Locations.locationID,
                    Locations.electricityDeliveryConfigID,
                    energyDeliveryConfig.*,
                    ISNULL(
                        Electricity.monthlycharge/NULLIF(Electricity.units,0),
                        Electricity.monthlycharge
                    ) AS costunit,
                    Electricity.units*energyDeliveryConfig.energyEnvironmentalImpact as co2
                FROM Electricity
                    INNER JOIN Locations ON Electricity.locationID = Locations.locationID
                    INNER JOIN energyDeliveryConfig ON Locations.electricityDeliveryConfigID =
                                      energyDeliveryConfig.energyDeliveryConfigID
                WHERE Electricity.locationID=@locationID ORDER BY billdate ASC;"
            DeleteCommand="DELETE from Electricity WHERE electricityID=@electricityID;"
            InsertCommand="INSERT Electricity (userID, locationID, billdate, units, monthlycharge)
             VALUES (@userID, @locationID, @billdate, @units, @monthlycharge)"
            UpdateCommand="UPDATE Electricity SET billdate=@billdate, units=@units,
               monthlycharge=@monthlycharge WHERE electricityID=@electricityID"

            ConnectionString="<%$ ConnectionStrings:GetPluggedInDB %>"
            Runat="server">
            <SelectParameters>
                <asp:QueryStringParameter Name="locationID" QueryStringField="id" Type="Int32" />
            </SelectParameters>
            <DeleteParameters>
                <asp:Parameter Name="electricityID" Type="Int32"/>
            </DeleteParameters>
            <InsertParameters>
                <asp:Parameter Name="userID" Type="Int32"/>
                <asp:Parameter Name="locationID" Type="Int32"/>
                <asp:Parameter Name="billdate" Type="String"/>
                <asp:Parameter Name="units" Type="Double"/>
                <asp:Parameter Name="monthlycharge" Type="Decimal"/>
            </InsertParameters>
            <UpdateParameters>
                <asp:Parameter Name="billdate" Type="String"/>
                <asp:Parameter Name="units" Type="Double"/>
                <asp:Parameter Name="monthlycharge" Type="Decimal"/>
            </UpdateParameters>
        </asp:SqlDataSource>

 

The complexity of having all this sql inside a web page with additional code behind glue, didn’t appear too concise. Fortunately on further study I realized that ASP .NET 3.5 also has a new technology called LINQ to SQL. Now I could replace the SqlDataSource with a LinqDataSource and make use of all the new ORM tools in VS2008. This is basically just dragging tables from the VS2008 Server Explorer onto a dbml page and then taking advantage of all the automatically created classes that map to the SQL table rows. It meant learning a bit more of Linq query syntax, but it was well worth the effort.

<asp:LinqDataSource
     ID="LinqDataSource1"
     runat="server"
     ContextTypeName="ElectricityDataContext"
     TableName="Electricities"
     EnableDelete="True"
     EnableInsert="True"
     EnableUpdate="True"
     OnInserting="linq_inserting"
     Where="locationID = @locationID AND userID=@userID"
     OrderBy="billdate"
     >
         <WhereParameters>
<asp:QueryStringParameter Name="locationID" QueryStringField="id"
     Type="Int32" />
         	<asp:ControlParameter Name="userID" ControlID="lblUser"
Type="Int32"/>
     </WhereParameters>
</asp:LinqDataSource>

Next on the agenda was delving a bit into AJAX. One requirement of this project was a set of cascading DropDownLists. The selection from the first DropDownList affects the content of the second etc. The content of each DropDownList is populated out of the database. There is a project called the ASP.NET AjaxTool Kit Included in the toolkit is this control, ajaxToolkit:CascadingDropDown, which exactly met the requirements. The ajaxToolkit:CalendarExtender is also much more useable than the simple asp:calendar.

This is quite a bit of capability for actually very little effort. So far I am quite pleased with my foray into ASP .NET land. I did, however, run into one area that caused some delay.

ListView controls are best wrapped in an asp:panel that can have a Scrollbar=”auto” attribute. This allows larger ListView table layouts to have their own scrollbars as needed by the client browser. This all works pretty well. The user can scroll around the table, sort columns, add new records etc. But, when he comes to edit a row that required a scroll, the page refreshes and the next moment the edit row is out of sight with the panel scroll reset to the top of the panel. This is quite confusing to anyone.

The best solution was to add an asp:UpdatePanel with default partial rendering. The UpdatePanel is a quick and dirty approach to AJAX. Any control inside the UpdatePanel <ContentTemplate> becomes an AJAX control with partial rendering happening behind the scenes. In the case of ListView this meant that the Edit command event reset the row layout for editing but did not lose the scroll position. This is nice.

Unfortunately there is a further twist. Scrolling is good to have but really what most would like to see is a fixed header at the top of a scrolling table. Asp controls do not have a nice property for fixed headers of tables inside a Panel control. One solution is setting style=”position:relative;” on the <tr> surrounding the table <th> elements. The header cells are then positioned relative to the top of the table regardless of the scroll position.

This fixes the column headers but the ajax refresh for editing rows will keep the edit row scrolled correctly while throwing the relative head position the scroll amount above its correct location. This is definitely not desirable. I spent a few days searching for some solution and finally came across this approach: Maintain Scroll Position after Asynchronous Postback

    <asp:ScriptManager ID="electrcityscriptmanager"
              EnablePartialRendering="true" runat="server"/>
    <script type="text/javascript">
	    var xPos,yPos;
	    Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(BeginRequestHandler);
	    Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);
        function BeginRequestHandler(sender, args)
        {
            if($get('<%= DataTableView.ClientID %>') != null){
                xPos = $get('<%= DataTableView.ClientID %>').scrollLeft;
                yPos = $get('<%= DataTableView.ClientID %>').scrollTop;
            }
            else {
                xPos=0;
                yPos = 0;
            }
            //alert(xPos+","+yPos);
        }

        function EndRequestHandler(sender, args)
        {
            if($get('<%= DataTableView.ClientID %>') != null){
                $get('<%= DataTableView.ClientID %>').scrollLeft = xPos;
                $get('<%= DataTableView.ClientID %>').scrollTop  = yPos;
            }
        }
</script>

The BeginRequestHandler is fired prior to the partial render and EndRequestHandler after the rendering. So the workaround involves capturing a current x,y scroll position on the panel before the render is fired and then restoring these after the rendering is completed in order to put things back where they should have been left.

Too bad there is no attribute available for panels like the page attribute: MaintainScrollPositionOnPostback=”true” which only works for the enclosing Page scrollbar and will not affect any interior Panel controls.

Once this bit of workaround was applied my “fixed header Ajax partial rendering ASP ListView Scrolling Table” control with full CRUD was finally working the way I needed. The effort involved was not very substantial and now that I’m further along the learning curve I can replicate this functionality across the entire website. ASP at the very least is a good approach to rapid prototyping.

Next on the agenda is exploring the Mono project to see how much of the ASP world can be forced into a Linux OS. Ultimately it would be very useful to deploy ASP websites in an Amazon EC2 AMI instance for inexpensive scaling. It remains to be seen what problems arise in a Mono based ASP platform.

Posted in ASP