ASP.NET Weblogs

Welcome to ASP.NET Weblogs Sign in | Join | Help
in Search

The Technical Adventures of Adam Weigert

  • C#: My First Extension Method

    I will find many, many uses for this ... maybe someone else will too!

    using System;
    using System.Diagnostics;

    internal static class StringExtensions
    {
        public static T ToEnum<T>(this string value)
            where T : struct
        {
            Debug.Assert(!string.IsNullOrEmpty(value));
            return (T)Enum.Parse(typeof(T), value, true);
        }
    }

    Posted Dec 08 2007, 10:01 AM by adweigert with 1 comment(s)
    Filed under: , ,
  • PowerShell: Try...Catch...Finally Comes To Life

    So, PowerShell has some good error handling, but being so used to .NET, I really missed my Try...Catch...Finally statements. Especially when I needed to make sure a block of code always executed. Well, after some playing, I think I have the solution! I've tested this function in a few different ways. I hope this turns out to be as helpful to someone else as it is for me. Maybe Microsoft will add this functionality to the core of PowerShell.

    function Try
    {
        param
        (
            [ScriptBlock]$Command = $(throw "The parameter -Command is required."),
            [ScriptBlock]$Catch   = { throw $_ },
            [ScriptBlock]$Finally = {}
        )
       
        & {
            $local:ErrorActionPreference = "SilentlyContinue"
           
            trap
            {
                trap
                {
                    & {
                        trap { throw $_ }
                        &$Finally
                    }
                   
                    throw $_
                }
               
                $_ | & { &$Catch }
            }
           
            &$Command
        }

        & {
            trap { throw $_ }
            &$Finally
        }
    }

    # Example usage 

    Try {
        echo " ::Do some work..."
        echo " ::Try divide by zero: $(0/0)"
    } -Catch {
        echo "  ::Cannot handle the error (will rethrow): $_"
        #throw $_
    } -Finally {
        echo " ::Cleanup resources..."
    }

  • PowerShell: Using PowerShell to Debug .NET Class Libraries

    PowerShell is so wicked cool. I love it more and more each day I use it. Latest trick is using it to debug or my class libraries without having to have a supporting unit test or console project.

    Though this method of testing / debuging process isn't as good as unit testing, it sure is handy for some small client utilities or where you just want to "try" something in one of your class libraries without changing all your unit tests.

    What you need to do is set your project to launch an external command and point it to your PowerShell installation, typically: C:\WINDOWS\system32\windowspowershell\v1.0\powershell.exe

    The command line arguments for your debug external program should be: -NoExit -command "& { . .\Debug.ps1 }"

    Then, add a file to your project called Debug.ps1, make sure you set it to copy to the output directory.

    When you run your class library in debug mode it will launch the PowerShell console and then execute the Debug.ps1 file. My file contains something like the following to load my assembly and a few functions to automate some of the things I might do while debugging. After this script runs, you will be left with a fully functioning PowerShell instance that you can use to further test your class library.

    Did I mention this is an awesome trick for building custom PowerShell commands? Well, I'm pretty sure it is, but I have not gotten that far, yet.

    #Debug.ps1
    [System.AppDomain]::CurrentDomain.AppendPrivatePath($PWD)
    [System.Reflection.Assembly]::LoadFrom("DotDeploy.dll")

    function global:New-DeploymentDefinition
    {
        return New-Object DotDeploy.DeploymentDefinition
    }

    function global:New-DeploymentCopyFileTask
    {
        param ( [string]$sourcePath, [string]$destinationPath )
        return New-Object DotDeploy.DeploymentCopyFileTask $source,$destination
    }

    function global:New-DeploymentServer
    {
        param ([string]$server, [int]$port)
        return New-Object DotDeployt.DeploymentServer $server,$port
    }

    $source = New-DeploymentServer "MARIO",9216
    $destination = New-DeploymentServer "LUIGI",9216
    $deployment = New-DeploymentDefinition
    $task = New-DeploymentCopyFileTask "C:\Program Files\DotDeploy\v1.0\Configuration" "C:\Program Files\DotDeploy\v1.0\Configuration"
    $task.Recursive = $true
    $task.InputFilter = "*.xml"
    $deployment.Tasks.Add($task)
    $deployment.Source = $source
    $deployment.Destination = $destination
    $destination.Lock()
    $deployment.Deploy()
    $destination.Unlock()

    Update Note: Make sure when you load your assembly you use LoadFrom and not LoadFile becasue LoadFile will not resolve dependencies but LoadFrom does. You can also append a private path to the current AppDomain as shown (added) in the example.

  • PowerShell: Convert Active Directory IADSLargeInteger to System.Int64

    This PowerShell function will convert an IADSLargeInteger ComObject to a long/Int64 value. Extremely helpful when trying to work with Active Directory attributes like "pwdLastSet" or "lastLogonTimestamp".

    function ConvertADSLargeInteger([object] $adsLargeInteger)
    {
        $highPart = $adsLargeInteger.GetType().InvokeMember("HighPart", [System.Reflection.BindingFlags]::GetProperty, $null, $adsLargeInteger, $null)
        $lowPart  = $adsLargeInteger.GetType().InvokeMember("LowPart",  [System.Reflection.BindingFlags]::GetProperty, $null, $adsLargeInteger, $null)

        $bytes = [System.BitConverter]::GetBytes($highPart)     $tmp   = [System.Byte[]]@(0,0,0,0,0,0,0,0)     [System.Array]::Copy($bytes, 0, $tmp, 4, 4)     $highPart = [System.BitConverter]::ToInt64($tmp, 0)

        $bytes = [System.BitConverter]::GetBytes($lowPart)     $lowPart = [System.BitConverter]::ToUInt32($bytes, 0)       return $lowPart + $highPart }
  • SqlViewState - The Path To Better ViewState Storage

    A while ago, several colleges of mine were having a terrible time with the loading times of some pages of their web application. Come to find out, they were suffering from ViewState bloat. ViewState was something I always tried to stay away from in the past because of this factor. Sure, it was very helpful but I found ways around it.

    However, I have come to a change of heart to realize ViewState is a wonderful thing, except that it can still cause pages to suffer from the ViewState bloat symptom. You could be a frugal programmer and control the ViewState more by only allowing certain pieces into but there are times when you want to store large amounts of data in the ViewState. For example, you may have search results that were very costly to find and you need to persist the results for paging.

    So, I started looking at different devices to store the ViewState in. I thought of putting it into our session state which is stored in a SQL database, but the timeout settings for session and page view state were very different in some cases and this method would not allow for the flexibility that is required. Or perhaps someone avoids session state like the plague or it isn't stored in a central repository in case of a web farm approach.

    The decision was easy, I would create a small table that stores ViewState in it much like the session state. I actually put the table and procedures in the same database as our session state just for consistency. It was also easy to script the job that cleans up timed out ViewState since we already had one for the session state. Here is the install script you will need to run to setup the table, stored procedures, and job to clean up the table every so often.

    [Database Code]

    To keep it simple I simply look for one value, the connection string to use in an appSetting key called “ViewStateConnectionString“. Optionally, you can define a “ViewStateTimeout“ with a value being the number of minutes to wait before clearing the ViewState data. You can also set this value per page if you have certain pages that will live longer on the client before a post back. If the connection string is not provided, it will not affect the ViewState processing as it will resort to the old method. The following is an example of the appSettings section.

    <appSettings>

           <add key="ViewStateConnectionString" value="Server=(local);Database=ASPState;Trusted_Connection=yes;"/>

           <add key="ViewStateTimeout" value="20"/>

    </appSettings>

     

    Here is the class that you will need to inherit from if you want to take advantage of this ViewState change, provided for you in the wonderful language of C#. I apologize for the lack of comments, hopefully it is self explanatory.

    [C# Code]

More Posts « Previous page