Migrating from .NET 1.1 to 3.5

Everybody likes to embrace the latest technology. We start hunting for it as soon as we realize the existing tool/technology is growingolder or not delivering up to the expectations. However, We should not forget the difficulties that come across the transition path. Sometimes, tools fail to deliver the way in which they are marketed. For me, one such tool was Visual Studio 2008.

I recently migrated a fairly big enterprise application from .NET 1.1 to 3.5. I was very happy as the decision was in the favor of both business as well as the development team. I decided to play intelligently and migrated a separate copy of the application beforehand to use it as a reference in future. Obviously, I was supposed to face problems as migration directly from 1.1 to 3.5 is not suggested on the forums, but accroding to my experience, it is not a big deal as long as your application has a good architecture and you know how to use Visual Studio Find and Replace utility:).

The purpose of writing this post is to inform the readers of the steps they should take to avoid spending too much time on migration. I encountered following errors before and after installing Visual Studio 2008 SP1. Make sure you run though the list below before you migrate your web application to .NET 3.5.

  • Thevery first problem you might face is that the .designer.vb has not been generated for all of the web pages in your application after running the automatic migration wizard for the first time. You need to right click on the project and select "Convert to Web Application" many times until you see all of the designer in the project directory.
  • If you stop the migration process half way through due to any reason, then make sure you follow the above step again or IDE will show you designer files excluded from project.

  • Stopping the process half way through might also show you some *.vb files with *.vb.old extension. These are the files that got successfully created last time. You can simply delete them anytime duringor after the exercise.

  • At one point, upon compiling the project, I got many "[Variable_Name]not declared" errors. After digging into the code, I spotted some of the class declarations looked like [Partial] Public Class [Class_Name]. If you witness the same thing then all you need to do is to replace [Partial], which is not a key word in .NET, with Partial using Visual Studio Find and Replace in Files. You can press Ctrl+Shift+H for fire up the utility.

  • The biggest of all problems I faced immediately after installing VS2008 SP1 was the way IDE created the designer files. I started receiving hundred of "[Variable_Name] is already declared as 'Protected[Variable_Name] As [Class_Name]' in this class" errors. Upon investigation, I found that Visual Studio 2008 IDE didn't remove control declarations from *.vb file after creating the same in *.designer.vbwhile converting to web application resulting in a number of multiple declaration errors. I couldn't find any shortcut to get rid of that and had to manually do it for every file.
  • One of the syntax changes that has been introduced in .NET 3.5 is the way it generates child control declarations in HTML. While using DataRepeater and DataGrid on a web page, following changes caught my attention:

    repeater1__ctl0_checkbox1 (.NET 1.1)
    repeater1_ctl00_checkbox1 (.NET 3.5)

  • One of the good things about the latest version of .NET framework is the availability of security features like Event Validataion and Request Validataion. The former reduces the risk of unauthorized postback requests and callbacks and the later prevents from cross site scripting (XSS) by rejecting any HTML in form post. Although both of the features can be disabled at the page level, but it is not recommended generally for security reasons.I took advantage of the event validation by overriding the Render method of the base page:
    Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)
    ClientScript.RegisterForEventValidation([control].UniqueID, String.Empty)
    MyBase.Render(writer)
    End Sub
    However, for request validataion, I had to disable it as my application needs to accept some HTML elements. Check out the below link for more details:
    Protecting Against Script Exploits in a Web Application

So much, so far. I will keep posted more erros as they come. If you have faced any error which is not in the above list then do share it with me, I will add them here.

Relation b/w SQL Server transaction isolation levels and locks

I had a very good discussion with a colleague of mine at work on the impact of SQL statements under the scope of a transaction. We were trying to optimize a stored procedure for the minimum execution time. While going through the SP at one point, We found a SELECT statement followed by an UPDATE statement inside a transaction, something like this:

BEGIN TRANSACTION

SELECT* from dbo.authors WHERE au_fname LIKE 'Johnson'

UPDATE authors SET au_fname = 'Johnson1' WHERE au_id = '172-32-3176'

COMMIT TRANSACTION

My colleague was of the view that, one should always keep the transaction as small as possible and SELECT statement should not unnecessarily be made part of the transaction. This helps ensure the locks will be held for a minimum period of time and maximum availability of the table or rows to other transactions. I couldn't disagree with him on this.

He added that, if the SELECT statement is not contributing in the overall outcome of the transaction, then there is no point in having it inside the transaction. In light of this argument, we can easily take the SELECT statement out of transaction I have mentioned above. However, part of his argument spurred me to do a small research on SQL Server transaction isolation level and locking where he said that all the locks will be held and table/rows will be unavailable for other transactions right from the start of the transaction.

According to my understanding, transaction isolation level defines the behavior of locks. SELECT statements acquire SHARED LOCK while UPDATE, DELETE and INSERT statements acquire EXCLUSIVE. While executing SELECT under READ COMMITTED isolation level which is the default for SQL Server, locks will immediately be released as soon as the execution of SELECT statement is finished. SQL Server will not wait for the transaction to be over and will allow other transaction to modify the table or rows. However, in case of REPEATABLE READ isolation level, every other process will have to wait for the locks regardless of SELECT statement has been executed or not. The below definition of REPEATABLE READ from MSDN helps use understand this point.

"REPEATABLE READ specifies that statements cannot read data that has been modified but not yet committed by other transactions and that no other transactions can modify data (but can be add) that has been read by the current transaction until the current transaction completes"

BEGIN TRANSACITON plays no role in defining the scope of the locks which are not applied until SQL Server reaches to a particular statement (SELECT, INSERET, UPDATE, DELETE). Based upon the definitions of different isolation levels and locks, we can easily understand the association b/w them. In the light of this analysis, for the above transaction, I reached to an understanding that, it will make no difference whether we keep the SELECT statement inside or outside the transaction. It might take longer to come back because of the SELECT statement but, it will not prevent other transaction from acquiring locks until it reaches to UPDATE statement. I supported my argument by running the following test:

Process 1:

Use Pubs

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ

BEGIN TRANSACTION

select * from authors WHERE au_fname like 'Johnson' /* Statement 1 */

Insert Into authors values('172-32-4188', 'ben', 'Johnson', '406 496-7229', 'address', 'city', 'CA', 94445, 1) /* Statement 2 */

select * from authors WHERE au_fname like 'Johnson' /* Statement 3 */

Commit Transaction

Process 2:

Use Pubs

Insert Into authors values('172-32-4188', 'ben', 'Johnson', '406 496-7229', 'address', 'city', 'CA', 94445, 1) //will get executed

UPDATE authors set au_fname = 'Johnson1' where au_id = '172-32-3176' /* will have to wait until transaction in Process 1 is finished.

Enterprise Library customization

Microsoft Enterprise Library is undoubtedly a great resource to support your .NET development. It is a bunch of some excellent tools and programming libraries to facilitate best practices in core areas of programming including data access, security, logging, caching, exception handling and others. Using the library without feeling the need to change any of the code is fairly easy and simple. However, while customizing it, we need to take special care as we might need to touch upon many areas than just source code. Today, I went through this customization process myself and faced a few difficulties which are worth mentioning here in order to help others avoid the same. I wanted to modify the contents of {Message} token for text formatter template and what I experienced was:

  • EntLib41Src folder is the point to start from which has got everything including blocks source code, scripts to build the modified libraries, quick starts etc. We are not supposed to touch actual Enterprise Library installation folder.

  • Before we actually proceed, we can open QuickStarts projects to help ourselves identify the file and method that we wish to change.

  • Now, we modify the code. I commented the call to WriteDescription() and WriteDateTime(DateTime.UTCNow) functions inside Format method and call to this.WriteSource and this.WriteHelpLink functions inside WriteException method in ExceptionFormatter.cs file.

  • We need to create a strong name key in order to generate strong-name EL assemblies. Check this out here: Strong Naming the Enterprise Library Assemblies

  • We can execute BuildLibrary.bat and CopyAssemblies.bat in order to build the modified assemblies and copy them to EntLib41Src\bin\ respectively.

  • Reference the assemblies in the project.

  • Make sure from that point onwards, we use the right copy of Enterprise Library Configuration tool which is inside EntLib41Src\bin\EntLibConfig.exe otherwise, we might end facing errors and exceptions related to assembly versioning and manifest definition mismatch as Tom Hollander describes it in his blog here: Avoiding configuration pitfalls with incompatible copies of Enterprise Library

Khallas! we are done.

Can't delete/rebuild full text catalog

A couple of days ago while working with SQL Server, I found myself in a catch 22 situation .We recently moved our database server and copied all objects including full text catalogs to a new location. While enabling the full text search on the new database, I realized that full text catalogs are still pointing to old location and needs changing. Frankly speaking, I didn't know how to do that and decided to drop the index and recreate as an easy way around it. However, in an effort to do so, I got an error saying "Full text is not enabled on the database. Run sp_fulltext_database 'enable'". When I ran that sp, I got another error saying "F:\MSSQL\FTData\SH_FT_CA..." doesn't exist". It was interesting enough to know that I couldn't drop the catalogue because of being disabled, but couldn't enable it either as it didn't exist at all. Wow! What a deadlock.

Well, with a little effort, I figured out a manual work around which is nothing but running an update command on sysfulltextcatalogs table. However, before I do that, I had to enable the updates for the current server by executing sp_configure for 'allow_updates' option. Long story short, following set of queries helped me update the path and eventually made it possible to drop the catalogues.


SELECT * FROM sysfulltextcatalogs

SP_CONFIGURE 'allow_updates', 0 GO RECONFIGURE WITH OVERRIDE GO

UPDATE SYSFULLTEXTCATALOGS SET path = 'D:\Microsoft SQL Server\MSSQL\FTData' WHERE ftcatid = 5