Friday, July 06, 2007

Automated SQL Server Backups

SQL Server 2000

  1. Open SQL Server Enterprise Manager
  2. Register your server
  3. Right-click the node Management > Backup, then select menu Add backup devices... We create devices "DBName Mondays.bak" to "DBName Sundays.bak" corresponding to each day of the week but you can use your own naming convention. We have assumed that DBName is the name of the database to backup.
  4. Right-click the node Databases > DBName, then select menu option All Tasks > Backup database...
  5. The SQL Server Backup – DBName dialog box is displayed.
  6. On the General tab, rename the backup "DBName Mondays", click the Remove button if an item appears in the backup to list, then click Add...
  7. In the Select Backup Destination backup select Backup Device and "DBName Mondays" then click OK.
  8. Make sure Database - complete and Overwrite existing media are selected.
  9. Check schedule and click ... to edit. Rename the schedule "DBName Mondays" and schedule to occur weekly on Mondays. Click OK.
  10. On the Options tab, click Verify backup upon completion and Remove inactive entries from transaction log. Keep other options unchecked.
  11. Go through steps 4 to 10 with "DBName Tuesdays" to "DBName Sundays".
  12. Go to the Management > SQL Server Agent > Jobs node, refresh the list and check the 7 backup jobs which you have just created.

SQL Server 2005

This is slightly more complicated in SQL Server 2005 because you cannot use the backup dialog which has no scheduling option. You need to use a maintenance plan. A maintenance plan is an SSIS package, which means you either need SSIS or SP2 installed, because SP2 includes a limited version of SSIS for maintenance tasks including backups.

  1. Open SQL Server Management Studio (Run as Administrator on Windows Vista).
  2. Right-click the node Server Objects > Backup Devices and select menu "Add Backup Device...".
  3. Name your backup device "DBName Mondays" and make it a file named "DBName Mondays.bak".
  4. Repeat steps 2 and 3 for "DBName Tuesdays" to "DBName Sundays".
  5. Start and configure SQL Server Agent which is a requirement for maintenance plans.
  6. Right click the node Management > Maintenance Plans and select menu "New Maintenance Plan..."
  7. Rename your plan "DBName Plan".
  8. Double-click "Subplan_1" to edit its properties.
  9. Name it "DBName Mondays" and create a schedule of the same name recurring weekly every Monday.
  10. Drop a "Back Up Database Task" from the toolbox onto the light yellow design surface.
  11. Right-click the task on the design surface and select menu "Edit...".
  12. Select the database(s) you want to back up, check option "Back up databases across one or more files", then click button "Add..." and select the backup device called DBName Mondays.
  13. Select "Overwrite" if backup file exists, check "Verify backup integrity" and click OK.
  14. On top of the list of subplans of "DBName Plan", click "Add Subplan".
  15. Go through steps 9 to 14 with "DBName Tuesdays" to "DBName Sundays".
  16. Go to the SQL Server Agent > Jobs , refresh the list and check the 7 backup jobs which you have just created.

For both SQL Server 2000 and SQL Server 2005, you can consider adding tasks to shrink databases, rebuild indexes, check database integrity in the scheduled jobs, but this goes beyond the scope of this article. In a following article, we will show you how to schedule FTP transfers to push and/or pull the backup files.

Wednesday, June 27, 2007

Getting metrics from .NET projects

There are loads of free tools available to get metrics from Java projects. I have found much more difficult to find similar tools for .NET projects.

When googling for ".NET project metrics" you get many references to devMetrics from a company called Anticipating Minds. I will spare you the time: Anticipating Minds is no more doing business and devMetrics does not work with .NET framework 2.0 and above.

I have used two complementary tools which give simple but effective metrics:

  1. A Reflector add-in called CodeMetrics, and
  2. Source Monitor from Campwood Software.

Friday, June 22, 2007

The ad war from a user perspective

The ad war between Google, Microsoft and Yahoo is on. This is a summary of what you have probably read in the press:

  • Yahoo Search Marketing (formerly Overture) has only been losing market share for a couple of years and struggles to deploy its new advertising platform, code-named Panama.
  • Microsoft’s advertising strategy has always been confused until recently. They have now decided to go into the advertising space and they want to make it big. See how much they have spent to recently acquire aQuantive. See the pace of upgrades made to AdCenter. See also Microsoft’s track record of turning a late arrival in a competitive market into a great success: Internet Explorer, Windows Mobile, Xbox.
  • Google is the leader with a consistent strategy and a great advertising platform, which not only includes AdWords and its important counterpart AdSense, but also free services like Blogger or Gmail where advertising is leveraged. Finally they have two critical complementary tools which give them a competitive edge, Google Analytics and Google Checkout.

It is difficult to measure how much the advertising platform weighs in the success or failure of its owner. I like to believe that it is a large part of it. I am a user of Yahoo Search Marketing, Microsoft AdCenter and Google’s suite including AdWords, AdSense, Analytics, and Blogger and I report here my experience:

  • Yahoo Search Marketing’s platform is simply a pain to use. Registering is overly complicated with issues regarding restrictions on billing address and currency in relation to the target market. Note that only Yahoo proposes a service fee to help you get started. Vocabulary is confusing but it has been corrected in the new platform. And the worst design issue is certainly the concept of binding an account to a national market, which remains in the new platform. In other words, if you advertise in the US and in 5 European countries, you need 6 different accounts and there is no way you can get a single view of your advertising spend with Yahoo. In my opinion, there is urgency for Yahoo to correct this if they want to survive in the advertising space.
  • Microsoft AdCenter is fairly new and gets improved regularly. It is certainly more rigid than Google. For example, an Ad has a culture which is a combination of language and country. Accordingly, if you want the same Ad to be displayed in the US and in the UK, you need to duplicate it. Google is better in this respect but I think AdCenter is deemed do a reasonable Job after a few revisions. The challenge for Microsoft is to build synergies with other tools in a reasonable time: they definitely need the equivalent of Google AdSense and Google Analytics and they also need to offer users who contribute content on their platform, including Live Spaces , the ability to generate revenue using their AdSense equivalent.
  • Google is I think two years ahead of the competition and their recent acquisition of DoubleClick has given them more comfort against Microsoft. I have very few complaints against their platform apart from the inability to change from credit card to bank account, the inability to get a bank account automatically debited and the incompatibility of AdSense with SSL. Google Analytics is absolutely a must have and I can’t wait for Google checkout to be available in continental Europe.

Thursday, June 21, 2007

Getting scheduled scans to work with Norton Antivirus 10.2 running in unmanaged mode

We use Norton Antivirus (NAV) Corporate Edition which is installed in managed mode on our LAN.

We have been using an old version of NAV on dedicated hosted web servers. Recently we have realized that NAV was triggering ThreadAbortException on long running ASP.NET pages. Excluding files did not solve the problem. We have had to upgrade NAV.

We have installed NAV in unmanaged mode on these servers as per the documentation, but after a couple of days, we have realized that scheduled scans were not working. The reason is explained here.

The workaround which is not given in the Symantec knowledge base is simply to copy (export + import) the following registry keys (and all subkeys) from a computer which has NAV in managed mode to the computer which has NAV in unmanaged mode:
  • HKEY_LOCAL_MACHINE\SOFTWARE\INTEL\LANDesk\VirusProtect6\CurrentVersion\LocalScans\ClientServerScheduledScan_1
  • ...
  • HKEY_LOCAL_MACHINE\SOFTWARE\INTEL\LANDesk\VirusProtect6\CurrentVersion\LocalScans\ClientServerScheduledScan_n

Thursday, March 29, 2007

Ajax extensions services always report “There was an error processing the request.”

I have been puzzled by the following for quite a while.

I use Microsoft Ajax extensions 1.0 to query web services which may raise exceptions. In my development environment, I would always get a nice localized error message but on the production server, the same code would produce a generic “There was an error processing the request”.

After having spent enough time stepping through my code with a debugger, I have decided to look at the Ajax extensions code and I have found the following piece of code in WriteExceptionJsonString of RestHandler.cs.

if (context.IsCustomErrorEnabled)
{
writer.Write(JavaScriptSerializer.SerializeInternal(new WebServiceError(

AtlasWeb.WebService_Error, String.Empty, String.Empty)));
}
else
{
writer.Write(JavaScriptSerializer.SerializeInternal(new WebServiceError(

ex.Message, ex.StackTrace, ex.GetType().FullName)));
}

Where WebService_Error is a resource which is valued “There was an error processing the request.”

This means that if you have enabled custom errors in your web.config on your production environment like I did, your Ajax calls will always report a generic error.

Why have the Microsoft people introduced such a restriction is a mystery to me.

Friday, March 16, 2007

Extender controls may not be registered before PreRender

Today, I have added new AjaxControlToolkit controls to Velodoc pages and I got exception “Extender controls may not be registered before PreRender” from running a page.

All our pages derive from our own WebPage class which derive from the standard Page class. WebPage provides features like custom error handling and QueryString parsing into page properties.

The page where we had the new extender control had the following method:

protected override void OnPreRender(EventArgs e)
{
//The following line is required, otherwise you get "Extender controls
//may not be registered before PreRender."
base.OnPreRender(e);

//Some code that displays errors on postbacks
...
}

The solution to the problem above is to add base.OnPreRender(e); at the beginning of the method.

Wednesday, January 31, 2007

Functional and load testing of ASP.NET Ajax applications – part I

Introduction

Velodoc is developed in ASP.NET C# 2.0 with Visual Studio .NET 2005.

VSTS comes with unit testing, web testing and load testing, considering load testing is actually an execution environment for unit tests and web tests.

Unfortunately Visual Studio web tests work at the protocol level, recording HTTP traffic in order to replay it. The same applies to Redgate’s ANTSLoad and many other load testing tools. Velodoc is an Ajax application and this does not work.

We have started our search for a solution from the following lists of testing tools:

Obviously there are tools like Mercury Winrunner/Loadrunner and the IBM Rational equivalents which certainly cope but they are too expensive.

Our requirements are the following:

  • Test ASP.NET applications
  • Works on Windows XP with IE
  • Compatible with NetAdvantage controls, iFrames, file uploads and Ajax
  • Scripts IE including IE dialogs to drive functional UI tests
  • Several instances can be executed concurrently to create load/stress tests
  • Uses a familiar technology (low learning curve)
  • Open source is a plus and a requirement if the supplier has not been around for a long time.

There are three types of solutions which cope more or less with these requirements:

  • Macro recorders/players
  • Test environments
  • Web application scripting frameworks

Macro recorders/players and test environments

Searching on Tucows, Download.com and other shareware web sites reveals loads of macro recorders. Most of them hook the message pump and replay the windows messages. Obviously, the result is not good. We have tried a dozen of them but only iOpus iMacros 5.2 could do a decent job at automating a file upload from https://www.velodoc.net/. The code is reproduced below:

TAB T=1
TAB CLOSEALLOTHERS
URL GOTO=https://www.velodoc.net
SIZE X=876 Y=627
TAG POS=1 TYPE=INPUT:TEXT FORM=NAME:aspnetForm ATTR=ID: SenderTextBox CONTENT=test1@acme.com
TAG POS=1 TYPE=INPUT:TEXT FORM=NAME:aspnetForm ATTR=ID: RecipientTextBox CONTENT=test2@acme.com
TAG POS=1 TYPE=TEXTAREA FORM=NAME:aspnetForm ATTR=ID: MessageTextBox CONTENT= Test<SP>with<SP>iMacro
FRAME F=1
WINCLICK X=100 Y=429 CONTENT=
WINCLICK X=100 Y=429 CONTENT=C:\test.bin
FRAME F=0
TAG POS=1 TYPE=INPUT:CHECKBOX FORM=NAME:aspnetForm ATTR=ID: SendTermsCheckBox&&VALUE:on CONTENT=YES
WINCLICK X=490 Y=513 CONTENT=

I see at least three drawbacks to using iOpus iMacros as a functional test tool:

  • The lack of assertions and reporting capabilities makes it insufficient for functional testing;
  • The lack of infrastructure makes it insufficient for load testing;
  • The proprietary language reduces the possibilities despite the fact that it can call external scripts or be called via a COM component.

I have also tried several test environments mentioned in the above lists. Generally, recording the file upload test on https://www.velodoc.net/ has always proved difficult but I cannot tell whether it was feasible or not for some of them. I have limited myself to 2 hours per evaluation and the inherent complexity and learning curve was not worth digging passed first impression.

Web application scripting frameworks

I have looked at two open-source frameworks, which both script IE to execute functional tests on the web application:

  • IEUnit 2.3, a framework based on JavaScript
  • WatiN 0.9.5, a framework based on C# .NET

Both frameworks are very easy to start with due to a familiar language and an intuitive API. Additionally both frameworks provide the necessary assertions to report on the success or failure of a test fixture.

Scripting a file upload on the Velodoc home page with IEUnit entails the following JavaScript code:

_.openWindow(https://www.velodoc.net);
_.setField("SenderTextBox",
test1@acme.com);
_.setField("RecipientTextBox",
test2@acme.com);
_.setTextArea("MessageTextBox", "Test with IEUnit");
var fname = "C:\\test.bin";
var cmdShell = new ActiveXObject("WScript.Shell");
cmdShell.Run("C:\\EnterFileName.sbk " + fname, 0, false);
_.setFrame(0);
_.clickObjById("FileInput");
_.setFrame(-1);
_.setCheckBox("SendTermsCheckBox",true);
_.clickObjById("SendWebImageButton");

Where EnterFileName.sbk contains:

var fpath = " " + WScript.Arguments(1);
var popupWin = _.waitForWindow("Choose file", 30000);
_.setFrame(0);
_.findWindow(popupWin, "Edit").sendText(fpath);
_.findWinButton(popupWin, "&Open").click();

Scripting a file upload on the Velodoc home page with WatiN entails the following C# code:

using (IE ie = new IE(https://www.velodoc.net/))
{
ie.ShowWindow(NativeMethods.WindowShowStyle.Maximize);
ie.TextField(Find.ById("SenderTextBox")).TypeText("
test1@acme.com");
ie.TextField(Find.ById("RecipientTextBox")).TypeText("
test2@acme.com");
ie.TextField(Find.ById("MessageTextBox")).TypeText("Test with WatiN");
Frame f = ie.Frame(Find.ById("FileUploadFrame"));
FileUpload fUp = f.FileUpload(Find.ById("FileInput"));
fUp.Set("C:\\test.bin");
ie.CheckBox(Find.ById("SendTermsCheckBox")).Checked = true;
//ie.TextField(Find.ById("SenderTextBox")).FireEvent("onKeyUp");
ie.Button(Find.ById("SendWebImageButton")).ClickNoWait();
SimpleTimer t = new SimpleTimer(60 * 60);
Span s;
do
{
s = ie.Span(Find.ById("DownloadLinkLabel"));
if (!String.IsNullOrEmpty(s.Text))
goto EXIT;
System.Threading.Thread.Sleep(1000);
} while (!t.Elapsed);
throw new WatiN.Core.Exceptions.TimeoutException("...", 60 * 60));
EXIT:
Assert.AreEqual(true, s.Text.Contains(
https://www.velodoc.net/));
}

Conclusion

The beauty of WatiN is that it builds on top of C# and .NET framework. Accordingly you get not only a rich language but also a rich environment. Test code built with WatiN can be executed within NUnit and Visual Studio unit testing projects which means that they can also be executed for load tests which I am going to try next although we know already that launching several instances of IE has its own limitation.

Wednesday, January 24, 2007

Remapping the universe

Following our recent post regarding Bumptop, see in the following Video Jeff Han and Phil Davidson demonstrating how a multi-touch driven computer screen will change the way we work and play.



Source: YouTube

Read the full article.

Tuesday, January 16, 2007

SGen XmlSerializers

My VS2005 C# web project was perfectly working in my development environment but I got the following error after deploying in a production environment:

Configuration Error
Parser Error Message: Cannot deserialize [C:\data.xml].

Using the fusion log viewer (FUSLOGVW.EXE) reveals a binding exception to Assembly.XmlSerializers.dll, where Assembly is the name of the assembly which contains the classes serialized in data.xml.

My ASP.NET application runs as a dedicated application pool under the credentials of a windows user which has very limited rights. The problem is related to the user rights which prevent the ASP.NET process from automatically generating XmlSerializers.

Visual Studio cannot generate XmlSerializers

On the build tab of your VS project properties, there is an option called “Generate Serialization Assemblies” which you can set to “On”.

If you look at MSBuild commands in the output window, doing so actually adds a command line which looks like the following:

C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\bin\sgen.exe /assembly:"Assembly.dll" /proxytypes /reference:"reference1.dll" … /reference:"referenceN.dll" /compiler:/keycontainer:VS_KEY_5EFB7881D71082EDCF85DBBFCD748B9A /compiler:/delaysign-

Note the /proxytypes option which actually prevents SGen from generating your XmlSerializers as specified in the documentation for the XML Serializer Generator Tool (Sgen.exe).

Use SGen as a post-build event

As a consequence you need to add the SGen command as a custom post-build event on the Build Events tab of your VS project properties:

"C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\sgen.exe" /force /assembly:"$(TargetPath)" /compiler:/keycontainer:VS_KEY_5EFB7881D71082EDCF85DBBFCD748B9A /compiler:/delaysign-

Other interesting links

Thursday, January 04, 2007

Unable to validate data error in relation to machine key

I have experienced the following error on a production web site:

Unable to validate data

at System.Web.Configuration.MachineKey.GetDecodedData (Byte[] buf, Byte[] modifier, Int32 start, Int32 length, Int32& dataLength)

Searching on the web, many developers seem to solve the problem at least partially by generating a static key as described in Microsoft's knowledge base.

This is a workaround but not an actual solution to the problem, at least in my scenario where my application runs in a dedicated application pool under limited privileges as described in http://msdn2.microsoft.com/en-us/library/ms998297.aspx.

The fix is to run aspnet_regiis.exe –ga DOMAIN\USER where USER is the identity of the application pool. Also make sure the user is part of the IIS_WPG group.

This command gives not only access to the IIS metabase but also creates the registry keys required in

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ASP.NET\2.0.50727.0\AutoGenKeys

for the application pool to generate machine keys.