Saturday, October 30, 2010

Connection was Unexpectedly Closed

I encountered an issue were a web service was calling a mainframe web service and every other time I would get the following error.

Error: "The underlying connection was closed: A connection that was expected to be kept alive was closed by the server."

As it turned out the mainframe was not setup to keep connections alive. Due to limitations with the mainframe, changing this functionality was not an option. So a simple partial class handled this automatically.

namespace <webservicenamespace> 
{
  public partial class <webserviceproxy> 
  {
    protected override System.Net.WebRequest GetWebRequest(Uri uri) {
      System.Net.HttpWebRequest webRequest = base.GetWebRequest(uri);

      webRequest.KeepAlive = false;

      return webRequest;
    }
  }
}

Saturday, October 2, 2010

Handling Enumerations from a Web Service with Generic Functions

Looking back at some code I ran across a handy piece of code that I wrote to save a good deal of typing, increase maintainability and readability.

Dealing with enumerations from a web service can be confusing at first. The enumeration field names are the same on both sides (client and server) of the web service, however the values are likely not going to be the same. This is especially true if the enumeration is defined with specific values that don't start with 1. The client side will give the enumeration values starting with 1. This means that when saving the value back to a web service object with a property of the enumeration type, you must make sure that the correct enumeration value is returned.

We run into situations where the enumeration value needs to be resolved from enumeration field name and the enumeration field name needs to be resolved from a value. The to just handle this inline can be rather hard to read and requires duplicate typing. Generic functions to the rescue.

Public Shared Function ParseEnum(Of T)(ByVal value As String) As T
    Return CType(System.Enum.Parse(GetType(T), value, True), T)
End Function


Public Function ResolveEnumToValue(Of T)(ByVal value As Object) As String
    Dim genericType As Type = GetType(T)
    Return [Enum].GetName(genericType, value)
End Function

Thursday, June 17, 2010

Using SQL Transactions in Powershell

It occurred to me that I have not seen a write up on System.Transactions.TransactionScope usage in powershell. I have tried this on Powershell v2, not sure if this works in Powershell 1. So here it goes...

The example below just shows the usage, I leave it as an exercise to the reader to add in the database query code.

"Start. " + [DateTime]::Now().ToString();

try {
 $transScope = New-Object System.Transactions.TransactionScope;

 ## Insert Queries

 "Complete";
 $transScope.Complete();
}
catch [Exception] {
    #$_ | fl * -Force
 Write-Host $_.Exception.ToString();
}
finally {
 if ($transScope) {
  $transScope.Dispose();
 }
}

"Done. " + [DateTime]::Now().ToString();

A more complex example just waiting for SQL statements. It shows some nested transactions.
"Start. " + [DateTime]::Now().ToString();

try {
 $transScope = New-Object System.Transactions.TransactionScope;
 
 ## Insert Queries
 
 try {
  ## Performs queries that are not included in a transaction.
  $transScope2 = New-Object System.Transactions.TransactionScope([System.Transactions.TransactionScopeOption]::Suppress);
  
  ## Insert Queries
  
  $transScope2.Complete();
 }
 finally {
  if ($transScope2) {
   $transScope2.Dispose();
  }
 }
 
 ## Insert Queries

 try {
  ## Perform actions that should be included in a side transaction outside of the enclosing transaction
  $transScope3 = New-Object System.Transactions.TransactionScope([System.Transactions.TransactionScopeOption]::RequiresNew);
  
  ## Insert Queries
  
  $transScope3.Complete();
 }
 finally {
  if ($transScope3) {
   $transScope3.Dispose();
  }
 }
 
 ## Insert Queries
 
 "Complete";
 $transScope.Complete();
}
catch [Exception] {
    #$_ | fl * -Force
 Write-Host $_.Exception.ToString();
}
finally {
 if ($transScope) {
  $transScope.Dispose();
 }
}

"Done. " + [DateTime]::Now().ToString();

Wednesday, June 16, 2010

VB.NET Debug Visualizer for Guids for Visual Studio 2010

Every once in a while I must program in VB.NET. My largest frustration is how Visual Studio handles Guids while debugging VB.NET code.

Seeing "System.Guid" as the value for a variable that contains a Guid is really not helpful. Debugging in C# correctly displays the actual value in the same situation.

Visual Studio provides an avenue to rectify this issue. You can create a new class library project and replace the contents of the default class file with the below code snippet.

<Assembly: DebuggerDisplay("{ToString()}", Target:=GetType(Guid))>

Public Class EmptyGuidVisualizerClass
    ' Empty
End Class

After compiling, copy the DLL to "%USERPROFILE%\My Documents\Visual Studio 2010\Visualizers" and restart Visual Studio. The Guids should resolve to their actual values.

After installing this in Visual Studio 2010, I found that it also works in Visual Studio 2008. The DLL should, likewise, be placed in the Visualizers directory in the Visual Studio 2008 folder in My Documents.

I created a batch file that can be used to install the DLL for 2010 and 2008. The batch file and the DLL must be in the same directory.

@ECHO OFF
SET STARTDIR=%CD%

pushd .

cd "%USERPROFILE%\My Documents"

IF EXIST ".\Visual Studio 2008" (
pushd .
echo "2008 Exists!"
cd ".\Visual Studio 2008"

IF NOT EXIST ".\Visualizers" (
 echo "Creating Visualizers Directory."
 mkdir Visualizers
)

copy "%STARTDIR%\GuidVisualizer.dll" .\Visualizers

popd
)

IF EXIST ".\Visual Studio 2010" (
pushd .
echo "2010 Exists!"
cd ".\Visual Studio 2010"

IF NOT EXIST ".\Visualizers" (
 echo "Creating Visualizers Directory."
 mkdir Visualizers
)

copy "%STARTDIR%\GuidVisualizer.dll" .\Visualizers

popd
)

popd

After creating it, I googled and found someone who came up with almost the same code, http://www.michelrenaud.com/?p=7 . This blog post contains pictures if you care to see the end result. Microsoft Connect has a similar resolved issue: https://connect.microsoft.com/VisualStudio/feedback/details/89801/show-guid-value-in-debug.

Friday, May 21, 2010

Use XQuery to convert a timestamp value to a Base64 string

SQL is a very powerful language, even with its limitations. SQL doesn't have the ability to convert Timestamp values to their base64 representations. However, you can use XQuery to do the conversion for you.

In the example below "Version" is of type Timestamp. I didn't notice any performance degradation during my testing.

SELECT  t1.Version
      , cast(N'' as xml).value('sql:column("t1.Version")', 'varchar(20)') 
FROM Table1 t1

This example opens up a new way to solve problems in SQL. It is intriguing to me to think about the other uses for leveraging XQuery to pick up SQL's slack.

Friday, February 5, 2010

GMail Style Multiple Checkbox Shift Selection

A while ago I ran into a situation where there were a list of check boxes in a ASP.NET GridView control and I wanted to be able to Shift+Click the check boxes like GMail or make a selection in Windows Explorer.

Here is the mocked up code that I came up with using jQuery. I make extensive use of is the predicate selector '$='. Which a very useful trick to get around injecting the ASP.NET client id into JavaScript.
var selectedCheckRow = 2;
function itemToggleSelect(cb, e) {
    var checkAll = $("input[id$='CheckAll']"),
        chkVal = cb.checked,
        idVal = cb.id;
    if (!chkVal && checkAll.attr('checked')) {
        $(".selectAllMsg").hide();
        selectAllPages('false');
        checkAll.attr('checked', false);
    }
    // -- Shift-Click Select on Item Grid -- //
    if (!e) e = event;
    CurrentCheckRow = $("#" + idVal)[0].parentNode.parentNode.rowIndex;
    if (e.shiftKey) {
        ((CurrentCheckRow > selectedCheckRow) ?
            $("input[id$='chkAction']").slice(selectedCheckRow - 2, CurrentCheckRow - 2)    // Selecting down
            : $("input[id$='chkAction']").slice(CurrentCheckRow - 2, selectedCheckRow - 2)  // Selecting up
        ).attr('checked', chkVal)
    }
    // Save checkbox row
    selectedCheckRow = $("#" + idVal)[0].parentNode.parentNode.rowIndex;
}
//Expects: 'true' if all pages should be selected
//         'false' if select only viewable items/page.
function selectAllPages(allPages) {
    $(".selectAllPages").val(allPages);
    var selectAll = $(".selectAllMsg > td");
    selectAll.html((allPages == "true") ?
        "All items on all pages have been selected.  <a  href='#' onclick='ToggleAll(false);return false;'>Clear Selection.</a>" :
        "All items on this page are selected.  <a href='#' onclick='selectAllPages(true);return false;'>Select All Items on All Pages.</a>");
}
function ToggleAll(cb) {
    var msg = $(".selectAllMsg"), selectAll,
        chkVal = cb.checked,
        idVal = cb.id;
    if (chkVal) {
        selectAll = $(".selectAllMsg > td");
        selectAll.html("All items on this page are selected.  <a href='#' onclick='selectAllPages(true);return false;'>Select All Items on All Pages.</a>");
        msg.slideDown(0);
    }
    else
    {
        msg.hide();
        selectAllPages('false');
    }
    $("input[id$='chkAction'],input[id$='CheckAll']").attr('checked', chkVal);
}

Demo
The demo code (view the source to see) is setup to mimic an GridView control. To make this demo function you can click a check box, perhaps '3' and then shift+click another check box, perhaps '7'. Not overly complicated, but could definitely save time over developing from scratch.





Select All




1


2


3


4


5


6


7


8


9


10


11


12


13


14


15


16


17