Using WCF with non-microsoft clients

The default wsdl that WCF creates isn't very friendly for human's and other non-microsoft clients to read. To remedy this you can intsall WCFExtras: http://wcfextras.codeplex.com/

To use it, in your endpoint declaration add a "behaviorConfiguration" element with a name something like "WsdlRedirect". Then add an endpointBehaviors declaration something like this:
 
    <behaviors> 
      <endpointBehaviors> 
        <behavior name="WsdlRedirect"> 
          <wsdlExtensions location="https://testwebservices.website.ca/SomeService.svc" 
                          singleFile="True" /> 
        </behavior> 
      </endpointBehaviors> 
 
And add an extension under system.serviceModel like this: 
 
  <system.serviceModel> 
    <extensions> 
      <behaviorExtensions> 
        <add name="wsdlExtensions
             type="WCFExtras.Wsdl.WsdlExtensionsConfig, WCFExtras, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/> 
      </behaviorExtensions> 
    </extensions>

"An attempt was made to load a program with an incorrect format.” in IIS 7

Was working on an old website dev region that hadn't been used since we upgraded to IIS 7 and a 64-bit web server, and was getting this error: "An attempt was made to load a program with an incorrect format.”
 
After some research I found the answer here:


The solution that worked for me was to enable 32-bit applications in the AppPool.

Apple iPad Facebook crash

My wife likes Apple she has an iPhone and she wanted something like the iPhone except a little bigger so she could manage her business social media content easier.

So we got her a first generation iPad. It worked great until she went to share a link in Facebook using Safari and it would crash.  The crash log said it was a memory issue.  I did some research and tried the "disable all the iCloud stuff" and the problem continued. 

Then I discovered this is a problem that started in Sep 2012 and it even happens with the newer iPad's so it can't be a memory problem. It is a problem with Safari on Facebook. So I tried a bunch of other browser's like Dolphin, and Opera and still the same problem.  

Finally was about to start selling her on an Android tablet when didn't I find a fix.  Almost sort of wished I hadn't found a fix because I like Android. It's what I have for my phone. But here it is: the Atomic Lite browser(or pay for the full blown version) solves the problem of crashing on Facebook, and it is a really nice browser. I like it better than any of the other browsers that are available for the iPad first generation.

Visual Studio 2010 with TFS can't edit source code

Once in a while when I open a project in Visual Studio and get latest version of source from TFS and I go to type in a source code file it will not auto check out and will not let me type anything.  The quickest way I have discovered to fix this is to click on another source code tab(or open another source code file if there is only one tab available) then go back to the original source code and you should be able to start typing.

Viewstate MAC failed

When you deploy your ASP.NET website to production you may get an error saying the "Viewstate MAC failed" This happens if your production environment is a web farm.  To fix it you need to add a machineKey entry to the system.web section of your web.config as described here by jnet:

http://www.nopcommerce.com/boards/t/9548/system-logs-what-does-the-error-mean-.aspx

How to fix branches in TFS after an upgrade

We upgraded our TFS servers to 2010 but our branch information was lost. Fortunately +Richard Banks provided an excellent post on how to rectify the situation.  You can read all about it here:

Richard Banks - Agile and .NET: How To Fix Branches After Migration to TFS2010

.NET Enums

I like Enum. I love how you can define an Enum like this:

    Enum ColorType 
        Red 
        Green 
        Blue 
    End Enum

Then use it as a parameter type like this:

    Public Sub ProcessColor(color As ColorType)

    End Sub

And when you go to use it in a method you get intellisense like this:

List of Enums Blue, Green, Red.










Every so often I come across a data model that uses strings to signify types. Like an 'R' for Red and 'G' for Green and a 'B' for Blue. I would love to use my good friend Enum and go:

    Enum ColorType 
        Red = "R" 
        Green = "G" 
        Blue = "B" 
    End Enum

But unfortunately this is not possible.  If you are like me and wish you could do this please go here: http://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/2161129-string-enum-for-both-c-and-vb and Vote now.

Until we get enough votes to get this implemented my current favorite alternative is to define a class like this:

    Class ColorType 

        Private Sub New(aColorType As String) 
            Value = aColorType 
        End Sub 

        Public Shared ReadOnly Property Red() As ColorType
            Get 
                Return New ColorType("R") 
            End Get 
        End Property 

        Public Shared ReadOnly Property Green() As ColorType
            Get 
                Return New ColorType("G") 
            End Get 
        End Property 

        Public Property Value() As String
        Public Shared ReadOnly Property Blue As ColorType
            Get 
                Return New ColorType("B") 
            End Get 
        End Property 

        Public Shared Operator <>(object1 As ColorType, object2 As ColorType) As Boolean
            Return Not object1.Value.Equals(object2.Value)
        End Operator 

        Public Shared Operator =(object1 As ColorType, object2 As ColorType) As Boolean
            Return object1.Value.Equals(object2.Value) 
        End Operator 

        Public Shared Widening Operator CType(aColorType As ColorType) As String
            Return aColorType.Value 
        End Operator 

    End Class 

Unless there is a lot of logic around the different types then it might be good for a Replace Type Code refactoring like: http://www.refactoring.com/catalog/replaceTypeCodeWithSubclasses.html

How to include a file in Visual Studio MSTest

Once in a while I add a xml file to be processed as part of an integration test in a MSTest project in Visual Studio but the file is missing when the test is run.  Here are the steps to get the file to show up when the test is run:

  1. Add file to MSTest project and set it to copy always.
  2. Go to Test -> Edit test settings -> Local(local.testsettings)
  3. Select Deployment
  4. Check “Enable deployment”
  5. Add DeploymentItem(“nameoffile”) attribute to test
  6. RESTART Visual Studio!
Remember to do step 6 because it will only begin working after Visual Studio is restarted.

Show/Hide formatting text in MS Word 2010

Was updating a MS Word 2010 document and coming from a WordPerfect background I like to see the formatting text when I'm editing. A quick search found this: http://answers.microsoft.com/en-us/office/forum/office_2010-word/view-hidden-text/0db765e8-0f42-476e-88dc-267eccdbf45b That pointed me in the right direction.

You click on the File tab then click Options.  On the Word Options dialog click on the Display option on the left menu bar.  Then check the "Show all formatting marks" checkbox. Like this:


Or if you only want to see specific formatting marks you can pick and choose between "Tab characters", "Spaces", "Paragraph marks", "Hidden text", "Optional hyphens", and "Object anchors".

Fixing bad sectors on WHS hard drive

When your WHS starts giving you hard drive errors make a note of where they are happening, somewhere on C:\fs\{drive letter}. Then open a command prompt and run:

chkdsk /r C:\fs\{drive letter}

After a few minutes it will then ask you if you would like to force a dismount. Say No. Then it will ask you if you would like to schedule a chkdsk /r the next time the system restarts. Say Yes. Restart WHS.

404 error in a REST WCF service

I created my first WCF REST service the other day and was getting a 404 error when I deployed the service to our server.  After some research I found the solution here:

http://www.west-wind.com/weblog/posts/2008/Apr/10/WCF-REST-Configuration-for-ASPNET-AJAX-and-plain-REST-Services

I needed to add:

Factory="System.ServiceModel.Activation.WebServiceHostFactory"

to MyService.svc <%@ ServiceHost markup.

There is also a very good write up on WCF REST service design here:

http://msdn.microsoft.com/en-us/library/dd203052.aspx

.NET FxCop recommends not using List<T>

I like to use FxCop when I’m coding and sometimes I get hit with the rule that says do not use List<T>, but it doesn't say what to use instead or it’s not clear what to use instead. After some research I found some suggestions:

http://blogs.msdn.com/kcwalina/archive/2005/09/26/474010.aspx
http://blogs.msdn.com/fxcop/archive/2006/04/27/585476.aspx

That recommend using Collection<T> but neither of them bothers to mention where Collection<T> is. So I did a little more research and I discovered it here:

System.Collection.ObjectModel.Collection<T>

How to check if the current user has rights to read a file in .NET

I could not find any function in .NET that just straight out does this.  Furthermore I could not find any code on the web that explained what would be the best way to go about it.  Finally I found some code here:

(post is no longer there)

that checks if you could write to a file and I modified it to check if you could read:

    Public Shared Function CanReadFile(ByVal fileNameWithPath As String) As Boolean
        Dim currentUser As System.Security.Principal.WindowsIdentity = System.Security.Principal.WindowsIdentity.GetCurrent()
        Dim currentPrinciple As System.Security.Principal.WindowsPrincipal = System.Threading.Thread.CurrentPrincipal
        Dim acl As System.Security.AccessControl.AuthorizationRuleCollection = System.IO.File.GetAccessControl(fileNameWithPath).GetAccessRules(True, True, GetType(System.Security.Principal.SecurityIdentifier)) 
        Dim denyread As Boolean = False
        Dim allowread As Boolean = False
        For Each currentRule As System.Security.AccessControl.FileSystemAccessRule In acl
            If currentUser.User.Equals(currentRule.IdentityReference) Or currentPrinciple.IsInRole(currentRule.IdentityReference) Then
                If currentRule.FileSystemRights = System.Security.AccessControl.FileSystemRights.Read Then
                    If currentRule.AccessControlType.Equals(System.Security.AccessControl.AccessControlType.Deny) Then
                        denyread = True 
                    ElseIf currentRule.AccessControlType.Equals(AccessControlType.Allow) Then
                        allowread = True 
                    End If 
                End If 
            End If 
        Next 
        If allowread And Not (denyread) Then
            Return True 
        Else 
            Return False 
        End If 
    End Function 

.NET generics with private accessors not compatible with MSTest

Was playing around with generics and suddenly my unit test project failed with this error: “Signature of the body and declaration in a method implementation do not match.” After some research I found a post here


that explained my problem was using a private on a generic class, and was a known bug that will not be fixed in VS 2010 as explained here


Changed the private to public and was able to carry on.

Save yourself hours of debugging time in an ASP.NET web site/app.

If you are working on a web application that has added code to the Global.asax that logs and clears all unhandled exceptions, down the road in the development/maintenance unit test cycle you may forget to check that any errors have occurred during your live testing and can’t figure out why your application isn’t working correctly.  To prevent this from happening to you and other developers on your project add a Debug.Assert message just before the code that logs the unhandled exception. For example:

Debug.Assert(False, String.Format("Exception about to be logged to database:{0}", unhandledException))

Then when you are running in debug mode and an unhandled exception occurs you will get a popup like this:


ASP.NET 2.0 page lifecycle

Every once in a while the ASP.NET 2.0 page lifecycle doesn’t quite work as I thought and I have to re-research it again. Here is a link I found that helped me this time. What was of special note to me this time was that a web user control will not have created its child controls until the page.OnPreRenderComplete event. Which, makes complete sense to me now.

http://blogs.thesitedoctor.co.uk/tim/2006/06/30/Complete+Lifecycle+Of+An+ASPNet+Page+And+Controls.aspx

Fixing HTTP Error 401.1 in IIS 7.5 on Windows 7

For a test I was trying to run a website on my local Windows 7 machine in IIS 7.5.

 I put the website files in my C:\inetpub\wwwroot\MyWebsite. I opened IIS 7.5 and right-clicked on Sites and selected "Add Web Site".

In the "Add Web Site" dialog I entered the "Site name", "Physical path" as above and "Host name" and clicked "OK".

For the "Select Application Pool" dialog I selected "Classic .NET AppPool" which is .Net 2.0 with Classic Pipeline.

I double clicked on "Authentication" and disabled everything and enabled "Windows Authentication" as this is a local intranet website.

In "Application Pools" I went into "Advanced Settings" for the "Classic .NET AppPool" and changed the Identity to "Custom account" and entered "my companies domain\my userid" and password, because that is how the website is run on the corporate server under a special account.

I then went to C:\Windows\System32\drivers\etc and edited my hosts file and added:

::1 MyHostName

Where MyHostName is the name I entered in "Host name" when I first created the website above.

I then opened IE 8 and put http://MyHostName/ in the address box and I get a "Windows Security" dialog box asking for my username and password.  I try and enter "my companies domain\my userid" and password and I just keep getting the same dialog three times and then I get a page that says "Server Error in Application 'SiteName'" where SiteName is the name I entered for "Site name" when I created the website.

On this error page it goes on to say that I got the "HTTP Error 401.2 - Unauthorized" error and "You are not authorized to view this page due to invalid authentication headers."

In the "Detailed Error Information" section it says I got error code 0x80070005.

After much research I discovered I needed to add a Multi-String Value to the following registry key HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0 called BackConnectionHostNames with "MyHostName" as the Value.  As described in "Method 1" here: http://support.microsoft.com/kb/896861.

In my research I did come along a nice blog(http://mvolo.com/troubleshoot-iis7-errors-like-a-pro/) that had some really good information but it didn't have the regedit fix I needed.

And a nice site about all the options with Windows Authentication in IIS can be found here http://www.iis.net/configreference/system.webserver/security/authentication/windowsauthentication



VS 2008 Next Error keyboard shortcut

When I’m refactoring some code if there is an interface change I usually make the interface change first and then fix all the error’s that come up.  Using the mouse to go to the errors window and double click on the next error can get tedious so I did some research to figure out a better way and found there is a keyboard short cut "ctrl-shift-F12" in VS 2008 that will take you to the next error.

For more information on keyboard short cuts check this out:

Microsoft .NET: Architecting Applications for the Enterprise

The book Microsoft® .NET: Architecting Applications for the Enterprise: Architecting Applications for the Enterprise (PRO-Developer) by Dino Esposito and Andrea Saltarello is written for Programmers/Application Architects to use the latest state of the industry .NET techniques and technologies for software development.

They provide very clear explanations of the technologies and techniques like WCF, Entity Framework, Domain Driven Design etc. Excellent examples of when and where to use each technology and technique and when not to use them.

They clearly reference where each technique came from and how to find more information. For me it had just the right amount of code examples and written explanations.  Buy a copy today.

Speed Improvement by avoiding exceptions


I learned a neat thing.  If you press ctrl-alt-e in Visual Studio you bring up this dialog:

Exceptions Dialog

Then check the Thrown checkbox for "Common Language Runtime Exceptions" like this:

Exceptions Dialog with CLR Exceptions Checked

Then run the project in debug mode and if an exception occurs the run will break at that point in the code and you can examine what happened.  This is great for finding uncaught exceptions and improper use of exceptions like this:

                Try
                    If c.Contains("somestring") Then Stop
                Catch ex As NullReferenceException
                End Try

One should never do this because it is extremely inefficient.  Exceptions are costly and should always be avoided if possible.  In this case we can avoid this exception by checking c for nothing, like so:

            If Not IsNothing(c) Then
                If c.Contains("somestring") Then Stop
            End If

VB.NET How to time a section of code.

Once in a while I want to see how long a section of code takes to run and I always forget the best way to do this.

endTime.Subtract(startTime).TotalMilliseconds()

It's so simple it's easy to forget I guess.

How to check if a datetime field equals current date in SQL Server Transact SQL

Had to write a SQL Server query to check if a date is the current day. After some searching I found a good way of doing it here: http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=38012

SELECT * FROM table WHERE DATEDIFF(day, StartDate, GETDATE()) = 0

ASP.NET web.config in different evironment solutions

In a website project you generally have a development environment, testing environment, and production environment. Each of these environments has different web.config settings. Fortunately ASP.NET now provides an elegant way of handling these. You can read all about it here:


VS 2008 with Team Explorer Unit Test TestContext Error

After upgrading from VS Team System 2005 to VS 2008 with Team Explorer I had a TestContext error when trying to run a unit test. After some research I found that you have to change the reference to Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll from v8 to v9.

Find files that end with "vbp" in Windows 7 file explorer

I was trying to find an old VB 6 project but I couldn't remember the name of it or where it was on my hard drive but I knew I didn't have very many of them so I opened file explorer and typed "*.vbp" in the search box.

This unfortunately returned way too many results because it included *.vbproj files. I wanted just files that ended with "*.vbp" After some searching I found this http://windows.microsoft.com/en-ca/windows7/advanced-tips-for-searching-in-windows which said you could use:

 System.FileName:~<"notes"

to find files that start with "notes" the ~< means "begins with" so I deduced maybe ~> means "ends with" and sure enough to find files that end with "vbp" put this in the search box:

System.FileName:~>"vbp"

Required reading for anyone coding in VB.NET

While at Tech-Ed 2008 in Orlando I picked up a copy of "Professional Refactoring in Visual Basic" by Danijel Arsenovski a Wrox Programmer to Programmer book by Wiley Publishing, Inc.  This book is absolutely the best book I have seen on doing object oriented VB.NET programming in the real world.  In my opinion it is absolutely required reading for anyone coding in VB.NET.

How to add a Solution Folder to an existing Solution Folder with VS 2005 Guidance Automation

If you have an EnvDTE.Project reference to an existing Solution Folder you can add a solution folder like so:

C#

((EnvDTE80.SolutionFolder)root.Object).AddSolutionFolder("solutionFolder");

or VB

DirectCast(root.[Object], EnvDTE80.SolutionFolder).AddSolutionFolder("solutionFolder")

where "root" is the EnvDTE.Project reference to the existing Solution Folder.

How to unlock a file in Team Foundation Server(TFS)

To unlock a file in Team Foundation Server you have to issue the following command at the Visual Studio Command Prompt:

TF UNDO filename /WORKSPACE:workspace;checkout_user /SERVER:servername

Where you change the lower case words with your particular case.  For more information go here:

How to search and replace a return character in Visual Studio

Every once in a while I need to search and replace a character with a "return" character and I forget how to do it and have to search online.  This latest search I found the answer here(it was there in 2008, but it is there longer):

http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=112303

In your search dialog turn on regular expressions and use "\x0d\x0a" for the "return" character.

VS 2005 Team System VB.NET Unit Test Class and method name are case sensitive

I had changed the name of a class to match Code Analysis class name criteria that specifies what parts of a class name should be upper case/lower case.  I did a global search and replace.  Some time later I ran a unit test and got this error:

System.TypeLoadException: Could not load type

After a bit of research I discovered that even though the class I had changed casing on was a VB class the unit test class is case sensitive.

ASP.NET 2.0 Wizard Control - Cancelling the next/previous button

If your using the ASP.NET 2.0 Wizard control and you want to stop the next button from going to the next step you have to set the event arg property Cancel to true like so:

Private Sub Wizard1_NextButtonClick(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.WizardNavigationEventArgs) Handles Wizard1.NextButtonClick
e.Cancel = True
End Sub

ASP.NET 2.0 Stack Overflow error in Wizard control

Was using the MaintainScrollPositionOnPostback=true in a page directive with the ASP.Net 2.0 Wizard control and started getting a stack overflow error when clicking on a Sidebar button.  Could not find a decent fix so I opted for a workaround and removed the MaintainScrollPositionOnPostback attribute and implemented this:

http://aspnet.4guysfromrolla.com/articles/111704-1.2.aspx

ASP.NET 2.0 RegularExpessionValidator to exclude a specific line.

Say you had the following select:

<select id="ItemSelect" runat="server">
 <option selected="selected">Select your item</option>
 <option>Item one</option>
 <option>Item two</option>
 <option>Item three</option>
</select>

And you wanted to force the user to select Item one/two/three. You could do this by creating a RegularExpressionValidator to to accept anything but the “Select your item” option like so:

<asp:RegularExpressionValidator ID="ItemRegularExpressionValidator" runat="server" ControlToValidate="ItemSelect"
                                ErrorMessage="Item Required" Text="*" SetFocusOnError="true" ValidationExpression="^((?!Select your item).)*$"></asp:RegularExpressionValidator>

Copy contents of a windows popup dialog

Some windows dialog's allow you to highlight part of the text in the dialog and press ctrl-c to copy that text which is great. But some dialog's do not allow this for example this one:


I wanted to copy the the compile error but it won't let me. What you can do in this situation is just click on the dialog title bar to make sure it is selected and press ctrl-c. This copies the whole dialog and then just open Notepad and paste it in Notepad like this:


Then you can highlight the text you want and carry on.

Handling the SelectedIndexedChanged event of a DropDownList in a GridView in ASP.NET 2.0

Say you had a GridView with a dropdownlist like this:

<asp:GridView ID="testGridView" runat="server">
    <Columns>
        <asp:BoundField DataField="TestField" />
        <asp:TemplateField>
            <ItemTemplate>
                <asp:DropDownList ID="TestDropDownList" runat="server" AutoPostBack="true">
                    <asp:ListItem Value="1">Item 1</asp:ListItem>
                    <asp:ListItem Value="2">Item 2</asp:ListItem>
                </asp:DropDownList>
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>

And you set it’s datasource in the page load event like this:

Protected Sub Page_Load(ByVal sender AsObject, ByVal e As System.EventArgs) HandlesMe.Load
    If Not Me.IsPostBack Then
        Dim testTable As New DataTable
        Dim testColumn As New DataColumn
        testColumn.ColumnName = "TestField"
        testColumn.DataType = GetType(String)
        testTable.Columns.Add(testColumn)
        Dim testRow As DataRow
        testRow = testTable.NewRow
        testRow.Item("TestField") = "Item 1"
        testTable.Rows.Add(testRow)
        testRow = testTable.NewRow
        testRow.Item("TestField") = "Item 2"
        testTable.Rows.Add(testRow)
        testRow = testTable.NewRow
        testRow.Item("TestField") = "Item 3"
        testTable.Rows.Add(testRow)
        Me.testGridView.DataSource = testTable
        Me.testGridView.DataBind()
    End If
End Sub

Now say you wanted to add an event handler of the drop down list in the GridView. You may be tempted to try using the AddHandler method in the RowDataBound event of the GridView like this:

Protected Sub testGridView_RowDataBound(ByVal sender AsObject, ByVal e As GridViewRowEventArgs) Handles testGridView.RowDataBound
    If e.Row.RowType = DataControlRowType.DataRow Then
        Dim testDropDownList As DropDownList = CType(e.Row.FindControl("TestDropDownList"),             DropDownList)
        AddHandler testDropDownList.SelectedIndexChanged, AddressOf TestDropDownList_SelectedIndexChanged
    End If
End Sub

Protected Sub TestDropDownList_SelectedIndexChanged(ByVal sender AsObject, ByVal e As EventArgs)
    Dim bla As Integer = 3
End Sub

But you will unfortunately discover that this does not work as a break point set on Dim bla is never reached. You have to tie the event handler directly in the aspx like this:

<asp:DropDownListID="TestDropDownList" runat="server" AutoPostBack="true" OnSelectedIndexChanged="TestDropDownList_SelectedIndexChanged">

Using VB.NET reflection to get a list of the current objects private fields

If you want to get a list of the current objects private fields you can do so like this:

me.GetType.GetFields(system.Reflection.BindingFlags.Instance or Reflection.BindingFlags.NonPublic)

VS Team System 2005 ASP.NET unit test error.

If you get this error message when running an ASP.NET unit test in VS Team System 2005:

The web request 'http://localhost:19298/' completed successfully without running the test. This can occur when configuring the web application for testing fails (an ASP.NET server error occurs when processing the request), or when no ASP.NET page is executed (the URL may point to an HTML page, a web service, or a directory listing). Running tests in ASP.NET requires the URL to resolve to an ASP.NET page and for the page to execute properly up to the Load event. The response from the request is stored in the file 'WebRequestResponse_lnkGetMoreWork_Click.html' with the test results; typically this file can be opened with a web browser to view its contents.

Remove these lines/attributes from the unit test method declaration:

HostType("ASP.NET"), _
AspNetDevelopmentServerHost("%PathToWebRoot%", "/"), _
UrlToTest("http://localhost/")> _

ASP.NET 2.0 DataList - properties set in ItemDataBound event not persisted during postback

If you have a DataList control and capture the ItemDataBound event like this:

Private Sub DataList1_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DataListItemEventArgs) Handles DataList1.ItemDataBound

And then suddenly have the urge to do something to e.item and expect it to exist after a postback you best be a suppressing that urge because nothing you do to e.item in the ItemDataBound event of a DataList control will survive a postback. The reason used to be described here:

VS 2005 ASP.NET 2.0 DropDownList ToolTip in IE7

You can set the title attribute on the drop down list items to have ToolTip popups on your DropDownList items. This does not work in IE6 but works in IE7. For example you can do it right in the aspx like this:

<asp:DropDownList ID="DropDownList1" runat="server">
            <asp:ListItem title="Choice 1 ToolTip" Value="1">Choice 1asp:ListItem>
            <asp:ListItem title="Choice 2 ToolTip" Value="2">Choice 2asp:ListItem>
asp:DropDownList>

Visual Studio will say that “Attribute 'title' is not a valid attribute of element 'ListItem'.” but it will run fine.
Or you can do it in the code behind like this:

Protected Sub DropDownList1_DataBound(ByVal sender As Object, ByVal e As System.EventArgs) Handles DropDownList1.DataBound
Dim toolTip As String = string.Empty
For Each item As ListItem In DropDownList1.Items
toolTip = GetToolTips.(Integer.Parse(item.Value))
item.Attributes.Add("title", toolTip)
Next
End Sub

Where GetToolTips is a custom function to retrieve tooltip text based on the passed in value.

ASP.NET 2.0 Data Binding Tips - How to avoid Eval()

Here is an excellent tip to speed up ASP.NET 2.0 Data Binding by avoiding reflection overhead:

http://www.dasblonde.net/2005/08/22/ASPNET20DataBindingTipsHowToAvoidEval.aspx

If you're in a VB project then you have to use CType to cast Container.DataItem like this:

<asp:Label ID="Label3" runat="server" Text='<%# CType(Container.DataItem, ConfigurationSection).SectionInformation.SectionName %>'></asp:Label>

Another benefit of doing this early binding, if you're using VS 2005, is you get intellisense popup to aid in selecting the right property.

Accessing a property on the MasterPage in ASP.NET 2.0

To access a property on the masterpage in ASP.NET 2.0 you have to cast it like this:

For a Web Application project

CType(MyBase.Master, WebApplication1.Site1)

Or for a website project

CType(MyBase.Master, MasterPage)

Or you can specify the MasterType in the aspx like this:

For a Web Application project

<%@ Page Language="vb" AutoEventWireup="false" MasterPageFile="~/Site1.Master"
CodeBehind="Default.aspx.vb"
    Inherits="WebApplication1._Default" %>
<%@ MasterType TypeName="WebApplication1.Site1" %>

Or for a website project

<%@ Page Language="VB" MasterPageFile="~/MasterPage.master" AutoEventWireup="false" CodeFile="Default.aspx.vb"
    Inherits="Default" title="Untitled Page" %>
<%@ MasterType VirtualPath="~/MasterPage.master" %>

Which will then create a shadow property on Master that does the casting for you so in the code behind you can just use:

Me.Master

Moving A DotNetNuke Install Into Root ( Up A Directory )

Finally managed to get my DNN v4.6.2 install into the root. My problem was I had tried darrenmcleod.com/ as the portal alias but it kept giving me an infinite redirect error.  Then I tried darrenmcleod.com as the portal alias and everything is goodness.  Note that when you make a change like this just through the database you need to do something to cause your application to reload, like editing a line in web.config and saving it.

Dynamic HeaderText for an ASP.NET 2.0 Wizard Control

I wanted to have the Wizard Control Header display the current step’s title, after a little research I found that the ActiveStepChanged event would allow me to do this. So I added an event handler like this:
    Protected Sub Wizard1_ActiveStepChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles Wizard1.ActiveStepChanged
        Me.Wizard1.HeaderText = Me.Wizard1.ActiveStep.Title
    End Sub

Except it didn’t set the Header for the first step so I set the HeaderText manually to the first step’s title like this:
    <asp:Wizard ID="Wizard1" runat="server" HeaderText="Step 1"> 
        <WizardSteps> 
            <asp:WizardStep ID="WizardStep1" runat="server" Title="Step 1"> 
            </asp:WizardStep> 
            <asp:WizardStep ID="WizardStep2" runat="server" Title="Step 2"> 
            </asp:WizardStep> 
        </WizardSteps> 
    </asp:Wizard>

How to make an ASP.NET Web User Control Width editable.

Add a property to your WebUserControl:
Private widthValue As Integer
Public Property Width() As Integer
    Get 
        Return widthValue 
    End Get 
    Set(ByVal value As Integer)
        widthValue = value 
    End Set 
End Property 
Then add a prerender event handler to the WebUserControl, where in this example the MainTable happens to be the outermost container element in the Web User Control with a width attribute:
Private Sub Page_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreRender
    If Me.Width > 0 Then
        Me.MainTable.Width = Me.Width
    End If 
End Sub

Then wherever you use the control you can specify the width if you want to:
<uc2:MyWebUserControl ID="MyWebUserControl1" runat="server" width="650" />

VS 2005 Team System Webtest ValidationRule on an asp:dropdownlist control

With this html:
<select name="ctl00$ContentPlaceHolder1$CompanyDropDownList" id="ctl00_ContentPlaceHolder1_CompanyDropDownList" class="Normal">
  <option selected="selected" value="1">All</option>
  <option value="2">Company 1</option>
  <option value="3">Company 2</option>
  <option value="4">Company 3</option>
  <option value="5">Company 4</option>
  <option value="6">Company 5</option>
 </select>

In my webtest I wanted to verify CompanyDropDownList had selected option 2 "Company 1".
Tried Form Field with form field name ctl00$ContentPlaceHolder1$CompanyDropDownList but it did not work.

Using Required Attribute Value worked with the following values:

Attribute Name             value
Expected Value            2
Ignore Case                  False
Match Attribute Name    selected
Match Attribute Value    selected
Tag Name                     option

Microsoft.ApplicationBlocks. ExceptionManagement The event source x does not exist error

 If you get the following error when using the Microsoft.ApplicationBlocks.ExceptionManagement library:

System.Security.SecurityException: The event source ExceptionManagerInternalException does not exist and cannot be created with the current permissions. ---> System.Security.SecurityException: Requested registry access is not allowed.
at System.ThrowHelper.ThrowSecurityException(ExceptionResource resource)
at Microsoft.Win32.RegistryKey.OpenSubKey(String name, Boolean writable)
at System.Diagnostics.EventLog.CreateEventSource(EventSourceCreationData sourceData)
at System.Diagnostics.EventLog.CreateEventSource(String source, String logName)
at Microsoft.ApplicationBlocks.ExceptionManagement.DefaultPublisher. VerifyValidSource()

One way of solving this is to install the Microsoft.ApplicationBlocks.ExceptionManagement.dll by running the following in a dos window:

C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe Microsoft.ApplicationBlocks.ExceptionManagement.dll

If for some reason your server admin doesn’t want to do that then you can just ask them to create the two event sources manually using eventcreate in a dos window:

eventcreate /t error /id 1000 /so ExceptionManagerInternalException /l application /d "new src ExceptionManagerInternalException in application log"
eventcreate /t error /id 1000 /so ExceptionManagerPublishedException /l application /d "new src ExceptionManagerPublishedException in application log"

Avoid DTC call in Entity Framework 4 on SQL Server 2005

Ok really went down a rabbit hole today but I managed to crawl back out.  I went to create a database connection test. It consisted of first creating a transaction and then select a count of the number of records that match the record I was about to add, add the record, then count again to make sure the count is now different from the first count.

This triggered a distributed transaction coordinator(DTC) error because I didn't have distributed transactions turned on but I didn't want it to start a distributed transaction as they add processing time and are not needed in this scenario.  So after much research I've discovered this apparently wouldn't have occurred if I was using SQL Server 2008 or greater but I of course was connecting to 2005.

In Entity Framework 6(EF6) it looks like they are finally giving us the option to tell the Entity Framework to use an existing transaction and not force a distributed one. Which will be nice when EF6 is released and I upgrade to it.

Until then the way to get Entity Framework 4 to use a single connection and single transaction and not trigger a DTC call is to open a connection manually and pass it into the context when you create it and tell it to not own the connection. Here is an example code:

        Using connection As New EntityConnection("name=MyEntities") 
            connection.Open() 
            Using context As New MyEntities(connection, False)
                Using transaction As New TransactionScope
                    Dim repository As MyRepository = New MyRepository(context)
                    Dim target As MyServices = New MyServices(repository, New InfrastructureFactory())
                    Dim record As MyFileRecord = New MyFileRecord()

                    Dim beforeRecordCount As Integer = GetRecord1Count(context)

                    record.CNTL_ID = Record1_CNTL_ID 
                    record.FAST_PATH = Record1_FAST_PATH 
                    record.CUST_NUM = Record1_CUST_NUM 
                    record.AGT_ID = Record1_AGT_ID 
                    record.AGT_ID2 = Record1_AGT_ID2 
                    record.CVG_TYPE = Record1_CVG_TYPE 

                    target.CreatePolicyInfoRecord(record) 

                    Dim afterRecordCount As Integer = GetRecord1Count(context)

                    Assert.AreNotEqual(beforeRecordCount, afterRecordCount) 
                End Using 
            End Using 
            connection.Close() 
        End Using

NArrange - organize your code effortlessly

The second thing I do(this is the first) with a new install of Visual Studio is I head over to http://www.narrange.net/download.aspx and download the latest version of NArrange.  NArrange is an open source .NET code organizer/formatter/beautifier.

After downloading and installing(and noting the folder where the exe is installed) the NArrange setup.msi, I go into my new install of Visual Studio and click on Tools and select External Tools.

Select External Tools

This opens the External Tools dialogue.  Click Add and in the Title field I put "NArrange" and beside the Command field I click the ...(browse) button and go to the folder where I installed NArrange and select the narrange-console.exe file.  For Arguments I like to only do one file at a time as I'm working so I set it to $(ItemFileName)$(ItemExt) /b and the Initial directory to $(ItemDir).  The /b causes a back up of the file before NArrange makes it's changes, this is necessary to do the restore command below. Then I check the Use Output window checkbox, so that I can see any issues that come up when NArrange runs, and click Apply.

NArrange Command

Next I create a restore command. I click the Add button and in the Title field put "NArrangeRestore" and for the Command field I do the same as before.  For Arguments I do the same as before except put /r for restore instead of /b. The /r will make NArrange restore the file back to what it was before the last time it ran. Set the Initial directory to $(ItemDir), like the first command. Then I check the Use Output window checkbox and click Apply.

NArrange Restore Command

NArrange is now ready for use.  When I have a file I would like to organize I just open it and then go to Tools and select NArrange.

NArrange Run

NArrange then backs up the file and reorganizes it, putting all the Fields in one place and orders them alphabetically and so on for Methods, and Delegates etc, and even sorts the Imports.


NArrange Done

To get Ajax working on an ASP.Net website

I couldn't get Ajax working on this one particular ASP.Net website and after a lengthy search I found the fix here http://geekswithblogs.net/influent1/archive/2007/05/16/112544.aspx.  I had to add this to the web.config:
<system.web> 
    <pages> 
      <controls> 
        <add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> 
        <add tagPrefix="asp" namespace="System.Web.UI.WebControls" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> 
      </controls> 
    </pages> 
</system.web>

Add a field to a Visual Studio 2005 Report Services Report

In the Datasets area right-click on a DataSource and select Add.

Add Field

Enter in the Name of the new field and the Database field or Calculated field.

Add Field Dialog

Then we need to update the tie between the Dataset and SQL Server by clicking on the Data tab and selecting our Dataset in the dropdown and updating the query.

Refactoring with CodeRush Xpress

One of the first things I do with a new install of Visual Studio(VS) is I head over to DevExpress and download/install CodeRush Xpress. CodeRush Xpress is a free refactoring tool from DevExpress for VS 2010 or older(They stopped offering the free version for VS 2012 or newer so now it looks like the first thing I'll be doing with a new install of Visual Studio is beg my boss for a CodeRush license).

If you are not familiar with refactoring and you are interested in being a better coder you should read Martin Fowler's book: Refactoring: Improving the Design of Existing Code (Addison-Wesley Object Technology Series). In it the authors Martin Fowler, Kent Beck, John Brant, William Opdyke and Don Roberts give very practical advice on improving the design of code.

Along with improving the design of code, refactoring can improve the readability of code.  My favorite refactoring pattern for this is Extract Method(EM). When you come across a really long method or find that in a moment of coding frenzie you have created one yourself, it's time to do some EM'ing to make things more readable for the next person that has to look at your code(which may be yourself in which case you will hear the thanks first hand from yourself).

For example take this code I found on an open source project:
  Private Function UpdateHintPath(ByVal projfile As String) As Boolean 

        Dim xmldoc As XmlDocument 
        Dim xnl As XmlNodeList 
        Dim xelement As XmlElement 
        Dim hintpathAttr As String = String.Empty 
        Dim newHintPathAttr As String 
        Dim name As String = String.Empty 
        Dim assmbname As String = String.Empty 
        Dim refinclude As String 
        Dim projGUID As String = String.Empty 
        Dim blDoSave As Boolean = False 
        Dim blUpdateHintPathOk As Boolean = True 
        Dim elementToRemove As New Hashtable 
        Dim attrToRemove As New ArrayList 
        Dim ien As IEnumerator 

        File.SetAttributes(projfile, FileAttributes.Normal) 

        xmldoc = New XmlDocument 
        xmldoc.Load(projfile) 

        If GetDotNetVersion(projfile) = DOTNETVERSION.TWO Then 

            'Get the namespace URI of the projects 
            Dim projectroot As XmlNode = xmldoc.ChildNodes(0) 
            If projectroot.Name.Equals("xml") Then 
                projectroot = xmldoc.ChildNodes(1) 
            End If 
            Dim projectNameSpaceURI As String = CType(projectroot, System.Xml.XmlNode).NamespaceURI 
            Dim nsmgr As XmlNamespaceManager = New XmlNamespaceManager(xmldoc.NameTable) 
            nsmgr.AddNamespace("proj", projectNameSpaceURI) 

            'Remove all project references  - We need to remove the project reference becuase as UBuild build at project level and not sln 
            'if one of the referred project is not already build but is a dependent of the main project being built it will cause the build to fail 
            'So we take out the project reference. 

            xnl = xmldoc.GetElementsByTagName("ItemGroup") 

            For Each xelement In xnl 
                If xelement.HasChildNodes Then 
                    Dim childNodeList As XmlNodeList = xelement.ChildNodes 
                    For Each _child As XmlNode In childNodeList 
                        If _child.NodeType = XmlNodeType.Comment Then 
                            Continue For 
                        End If 
                        Dim child As XmlElement = DirectCast(_child, XmlElement) 
                        If child.Name.Equals("ProjectReference") Then 

                            If Not elementToRemove.Contains(child) Then 
                                elementToRemove.Add(child, xelement) 
                            End If 

                            If child.HasChildNodes Then 
                                If child.GetElementsByTagName("Project").Count = 1 Then 
                                    projGUID = child.GetElementsByTagName("Project").Item(0).InnerText 
                                End If 
                                If child.GetElementsByTagName("Name").Count = 1 Then 
                                    assmbname = child.GetElementsByTagName("Name").Item(0).InnerText 
                                End If 
                            End If 

                            'assmbname = child.ChildNodes(0).InnerText 
                            'projGUID = child.ChildNodes(1).InnerText 

                            Dim newelement As XmlElement = xmldoc.CreateElement("Reference", projectNameSpaceURI) 
                            Dim xmlName As XmlElement = xmldoc.CreateElement("Name", projectNameSpaceURI) 
                            Dim xmlHintPath As XmlElement = xmldoc.CreateElement("HintPath", projectNameSpaceURI) 

                            xmlName.InnerText = CType(htProjGuidAssmb(projGUID), String) 
                            xmlHintPath.InnerText = buildFileLocation & CType(htProjGuidAssmb(projGUID), String) & ".dll" 
                            newelement.SetAttribute("Include", CType(htProjGuidAssmb(projGUID), String)) 

                            newelement.AppendChild(xmlName) 
                            newelement.AppendChild(xmlHintPath) 

                            xelement.AppendChild(newelement) 

                            xmldoc.Save(projfile) 

                            If Not attrToRemove.Contains(newelement) Then 
                                attrToRemove.Add(newelement) 
                            End If 

                        End If '//If child.Name.Equals("ProjectReference") 

                        'Find <Reference> element is present without any child node 
                        'Remove if it is of type <Reference Include="[AssemblyName], Version=1.0.915.2008, Culture=neutral, processorArchitecture=MSIL" /> 
                        If child.Name.Equals("Reference") And child.HasAttribute("Include") And Not child.HasChildNodes Then 

                            refinclude = child.GetAttribute("Include") 

                            If InStr(refinclude, ",") Then 

                                assmbname = child.GetAttribute("Include").Split(","c)(0) 

                                If Not ToBeExcluded(assmbname) Then 

                                    If Not elementToRemove.Contains(child) Then 
                                        elementToRemove.Add(child, xelement) 
                                    End If 

                                    Dim newelement As XmlElement = xmldoc.CreateElement("Reference", projectNameSpaceURI) 
                                    Dim xmlName As XmlElement = xmldoc.CreateElement("Name", projectNameSpaceURI) 
                                    Dim xmlHintPath As XmlElement = xmldoc.CreateElement("HintPath", projectNameSpaceURI) 

                                    xmlName.InnerText = assmbname 
                                    xmlHintPath.InnerText = assmbname & ".dll" 
                                    newelement.SetAttribute("Include", assmbname) 

                                    newelement.AppendChild(xmlName) 
                                    newelement.AppendChild(xmlHintPath) 

                                    xelement.AppendChild(newelement) 

                                    xmldoc.Save(projfile) 

                                    If Not attrToRemove.Contains(newelement) Then 
                                        attrToRemove.Add(newelement) 
                                    End If 
                                End If 

                            Else 
                                refinclude = String.Empty 
                            End If '// If InStr(refinclude, ",") 

                        End If '//If child.Name.Equals("Reference") 

                    Next 
                End If 
            Next 

            'If there are project references found, then lets remove them now 
            If elementToRemove.Count > 0 Then 
                ien = elementToRemove.Keys.GetEnumerator 
                While ien.MoveNext 
                    Dim _childElement As XmlElement = CType(ien.Current, XmlElement) 
                    Dim _parentElement As XmlElement = (CType(elementToRemove(ien.Current), XmlElement)) 
                    _parentElement.RemoveChild(_childElement) 
                End While 
                xmldoc.Save(projfile) 
            End If 

            'Now update all the hint paths 
            xnl = xmldoc.GetElementsByTagName("Reference") 

            For Each xelement In xnl 
                refinclude = "" 
                assmbname = "" 
                If xelement.HasChildNodes Then 

                    If xelement.HasAttribute("Include") Then 
                        refinclude = xelement.GetAttribute("Include") 
                        If InStr(refinclude, ",") Then 
                            assmbname = refinclude.Split(","c)(0) 
                        ElseIf ProjectsToBuildList.Contains(refinclude & ".dll") Then 
                            assmbname = refinclude 
                        ElseIf IsProxy(refinclude & ".dll") Then 
                            assmbname = refinclude 
                        End If 
                    End If 

                    'check if there is a <HintPath> element present 
                    Dim hintpathnode As XmlNode = Nothing 
                    For i As Integer = 0 To xelement.ChildNodes.Count - 1 
                        If String.Compare(xelement.ChildNodes(i).Name, "HintPath") = 0 Then 
                            hintpathnode = xelement.ChildNodes(i) 
                            Exit For 
                        End If 
                    Next 
                    If ((hintpathnode Is Nothing) And Not ToBeExcluded(assmbname) And assmbname.Length > 0) Then 
                        'TODO: Add an <HintPath> element 
                        hintpathnode = xmldoc.CreateElement("HintPath", "http://schemas.microsoft.com/developer/msbuild/2003") 
                        hintpathnode.InnerText = assmbname 
                        xelement.AppendChild(hintpathnode) 
                    End If 

                    Dim childNodeList As XmlNodeList = xelement.ChildNodes 

                    For Each child As XmlElement In childNodeList 

                        If child.Name.Equals("Name") Then 
                            assmbname = child.InnerText 
                        End If 
                        If child.Name.Equals("HintPath") Then 
                            hintpathAttr = child.InnerText 
                        End If 

                        If Not assmbname Is Nothing And assmbname.Length > 0 And ToBeExcluded(assmbname) And IsProxy(assmbname & ".dll") Then 
                            newHintPathAttr = buildFileLocation & assmbname & ".dll" 
                            If proxiesList.Contains(assmbname) And Not File.Exists(newHintPathAttr) Then 
                                File.Copy(CType(proxiesList(assmbname), String), newHintPathAttr, True) 
                            End If 
                            If child.Name.Equals("HintPath") Then 
                                child.InnerText = buildFileLocation & assmbname & ".dll" 
                            End If 
                            blDoSave = True 
                        End If 

                        If child.Name.Equals("HintPath") And Not assmbname Is Nothing And assmbname.Length > 0 And Not ToBeExcluded(assmbname) And Not hintpathAttr Is Nothing AndAlso hintpathAttr.Length > 0 Then 
                            newHintPathAttr = buildFileLocation & assmbname & ".dll" 
                            If Not ProjectsToBuildList.Contains(assmbname & ".dll") And Not File.Exists(newHintPathAttr) And IsProxy(assmbname & ".dll") Then 
                                If proxiesList.Contains(assmbname & ".dll") Then 
                                    File.Copy(CType(proxiesList(assmbname & ".dll"), String), newHintPathAttr, True) 
                                End If 
                            End If 
                            child.InnerText = buildFileLocation & assmbname & ".dll" 
                            blDoSave = True 
                        End If 
                    Next '// child In childNodeList 

                End If '//if element has childnodes 

            Next '//next <Reference> element 

        Else 'DOTNET_VER = 1.0 
            xnl = xmldoc.SelectNodes("//References/Reference") 

            For Each xelement In xnl 

                If xelement.HasAttribute("Name") Then 
                    name = xelement.Attributes.GetNamedItem("Name").Value 
                End If 

                'If proxyAliasList.Contains(name) Then 
                '    If xelement.HasAttribute("Guid") And _ 
                '    xelement.HasAttribute("VersionMajor") And _ 
                '    xelement.HasAttribute("VersionMinor") And _ 
                '    xelement.HasAttribute("Lcid") And _ 
                '    xelement.HasAttribute("WrapperTool") Then 

                '        xelement.RemoveAttribute("Guid") 
                '        xelement.RemoveAttribute("VersionMajor") 
                '        xelement.RemoveAttribute("VersionMinor") 
                '        xelement.RemoveAttribute("Lcid") 
                '        xelement.RemoveAttribute("WrapperTool") 

                '        xelement.SetAttribute("AssemblyName", CType(proxyAliasList(name), String)) 
                '        xelement.SetAttribute("HintPath", buildFileLocation & CType(proxyAliasList(name), String) + ".dll") 

                '        blDoSave = True 
                '    End If 
                'End If 

                'Remove project references 
                If xelement.HasAttribute("Project") Then 
                    xelement.RemoveAttribute("Project") 
                    xelement.RemoveAttribute("Package") 
                    If BuildListMapProjToAssmbName.Contains(projfile) Then 
                        xelement.SetAttribute("AssemblyName", name) 
                        xelement.SetAttribute("HintPath", buildFileLocation & name & ".dll") 
                        blDoSave = True 
                    End If 
                End If 

                If xelement.HasAttribute("AssemblyName") Then 
                    assmbname = xelement.Attributes.GetNamedItem("AssemblyName").Value 
                End If 

                If xelement.HasAttribute("HintPath") Then 
                    hintpathAttr = xelement.Attributes.GetNamedItem("HintPath").Value 
                End If 

                If ToBeExcluded(assmbname) And IsProxy(assmbname & ".dll") Then 
                    newHintPathAttr = buildFileLocation & assmbname & ".dll" 
                    If proxiesList.Contains(assmbname & ".dll") And Not File.Exists(newHintPathAttr) Then 
                        File.Copy(CType(proxiesList(assmbname & ".dll"), String), newHintPathAttr, True) 
                    End If 
                    xelement.SetAttribute("HintPath", buildFileLocation & assmbname & ".dll") 
                    blDoSave = True 
                End If 

                If Not assmbname Is Nothing And Not ToBeExcluded(assmbname) And Not hintpathAttr Is Nothing AndAlso hintpathAttr.Length > 0 Then 
                    newHintPathAttr = buildFileLocation & assmbname & ".dll" 
                    If Not ProjectsToBuildList.Contains(assmbname & ".dll") And Not File.Exists(newHintPathAttr) And IsProxy(assmbname & ".dll") Then 
                        If proxiesList.Contains(assmbname & ".dll") Then 
                            File.Copy(CType(proxiesList(assmbname & ".dll"), String), newHintPathAttr, True) 
                        End If 
                    End If 
                    xelement.SetAttribute("HintPath", buildFileLocation & assmbname & ".dll") 
                    blDoSave = True 

                End If 
            Next 
        End If '//check DOTNET_VER 

        Try 
            If blDoSave Then 
                xmldoc.Save(projfile) 
            End If 
        Catch ex As Exception 
            If dispXMLoutput Then 
                Output("<message loc=""updatehintpath""><![CDATA[ERROR while updating HintPath ! Failed to save : " + projfile + "]]> </message>") 
                Output("<message loc=""updatehintpath""><![CDATA[" + ex.Message + "]]> </message>") 
            Else 
                Output(vbCrLf + "Error while updating HintPath ! Failed to save : " + projfile + vbCrLf + ex.Message, ConsoleTools.ConsoleColor.red) 
            End If 
            WriteLog(vbCrLf + "Error while updating HintPath ! Failed to save : " + projfile + vbCrLf + ex.Message) 
            blUpdateHintPathOk = False 
            Throw ex 
        Finally 
            xmldoc = Nothing 
        End Try 

        File.SetAttributes(projfile, FileAttributes.ReadOnly) 

        Return blUpdateHintPathOk 
    End Function 

According to Visual Studio Code Metrics the Maintainability Index of UpdateHintPath is 16. This is not good.

The first thing you should do before undertaking any refactoring is make sure the code is covered by some automated unit test.  If it isn't then you should apply one or more of the techniques outlined in Michael Feathers awesome book Working Effectively with Legacy Code. Once the code to be refactored is under test and all tests are green then we can proceed.

 For the Extract Method refactoring with CodeRush Xpress we simply highlight the code we want to extract to it's own method and press the ctrl+` key. In this case we will highlight the first part of the big "If" statement:
If GetDotNetVersion(projfile) = DOTNETVERSION.TWO Then
Hit ctrl+` and we get:
Coderush Refactor Popup Menu

Then make sure Extract Method is selected and press Enter.

Extract Method Placement

Next use the Up and Down arrows to move the red line to where you want the new method code to be put and hit Enter.


CodeRush takes a guess at the extracted method name based on a nearby comment which can be bang on sometimes and all you would do is hit Enter and be done, but in this case I would like to change it to something that better describes what the new method is doing UpdateHintPathForDotNetTwo.

Change Method Name

After changing the name and hitting Enter the new method creation is completed and you will notice that Coderush also took a best guess as to what needs to be passed into the new method, more on this later. To get back to the original method all that needs to be done is press the Esc key.

Back in the original method

And there we can see our new method call we just created. Then I repeated the process for the Else statement and called it UpdateHintPathForDotNetOne.

Refactor Else statement

Now we have quite a few parameters that are being passed in unnecessarily to the new methods so we clean those up and here is the final refactored method:
    Private Function UpdateHintPath(ByVal projfile As String) As Boolean 

        Dim xmldoc As XmlDocument 
        Dim blDoSave As Boolean = False 
        Dim blUpdateHintPathOk As Boolean = True 
         
        File.SetAttributes(projfile, FileAttributes.Normal) 

        xmldoc = New XmlDocument 
        xmldoc.Load(projfile) 

        If GetDotNetVersion(projfile) = DOTNETVERSION.TWO Then 
            UpdateHintPathForDotNetTwo(projfile, xmldoc, blDoSave) 
        Else 'DOTNET_VER = 1.0 
            UpdateHintPathForDotNetOne(projfile, xmldoc, blDoSave) 
        End If '//check DOTNET_VER 

        Try 
            If blDoSave Then 
                xmldoc.Save(projfile) 
            End If 
        Catch ex As Exception 
            If dispXMLoutput Then 
                Output("<message loc=""updatehintpath""><![CDATA[ERROR while updating HintPath ! Failed to save : " + projfile + "]]> </message>") 
                Output("<message loc=""updatehintpath""><![CDATA[" + ex.Message + "]]> </message>") 
            Else 
                Output(vbCrLf + "Error while updating HintPath ! Failed to save : " + projfile + vbCrLf + ex.Message, ConsoleTools.ConsoleColor.red) 
            End If 
            WriteLog(vbCrLf + "Error while updating HintPath ! Failed to save : " + projfile + vbCrLf + ex.Message) 
            blUpdateHintPathOk = False 
            Throw ex 
        Finally 
            xmldoc = Nothing 
        End Try 

        File.SetAttributes(projfile, FileAttributes.ReadOnly) 

        Return blUpdateHintPathOk 
    End Function 

Visual Studio Code Metrics is now reporting that the Maintainability Index of the new UpdateHintPath is at a respectable 50. Finally remember to run the unit tests to make sure they are still all green.