Saturday, April 30, 2011

JustDecompile from Telerik (beta available now)

Today I tried out the beta version of JustDecompile from Telerik and my first impressions are: I like it.

One problem I had was that the installer didn’t create a shortcut to the JustDecompile.exe on my computer (hey it’s a beta! problems are expected).

image

Some things that I miss in JustDecompile:

  • Does not provide information regarding the .Net version that the module was built against.
  • Does not provide a list of references used by the module.
  • Does not let you see the list of resources embedded as part of the module.
  • Doesn’t provide you the ability to choose the language to decompile code in (C# is the language used to decompile in this beta version).

I am sure as JustDecompile matures these additional features will be added.

RedGate reverses decision on Reflector and why I don’t care

Redgate sort of reversed its decision on .Net Reflector (http://www.reflector.net/2011/04/why-we-reversed-some-of-our-reflector-decision/), and now it looks like – if you are a “current” user of Reflector, then you will get updated to version 6.8 of Reflector which will come with a perpetual license.

The post goes on to talk about why they (RedGate) made the decision to commercialize Reflector.

And the reason I don’t care:

I completely understand a company wanting to make money of its product. Hell its their right!. And at $35 a tool like Reflector was a steal. But what was not their right is to yank a free version from MY computer and then attempt put a version that eventually would require me to pay for using it (post link). To me it is like Amazon sending me a free book and then burns it while I am reading it. Prior to v7, Reflector was free. If v7 was to be a paid version, then they should have let people keep version 6 on their machines and allowed them to decide if they wanted to upgrade to a paid version or not. I am sure people would have upgraded to the next version of .Net reflector if they thought that the features would be useful to them (which would definitely have happened when Microsoft would have released its next version of .Net). To me, RedGate’s action stank of greediness and frankly they were not thinking long-term.

image
RedGate making me pay for a .Net Reflector version that I was forced to upgrade to.

My problem with Neil Davidson’s post: They don’t seem to realize that people were not pissed that they wanted you to pay for the next version, what people were pissed about was the forced upgrade to a version that needed to be paid for to play with.

Now, as a reaction we have multiple replacements being developed by commercial and the open-source community. ILspy is an open-source alternative that’s worked well for me (http://wiki.sharpdevelop.net/ilspy.ashx). Today, I also tried out JustCompile from Telerik and I like it! (http://blog.aggregatedintelligence.com/2011/04/justdecompile-from-telerik-beta.html).

UPDATE 4/30/2011: If you go to the .Net Reflector site you can only download v7 (paid version) of .Net Reflector. You cannot download v6.x from their website (at least not as of the writing of this update). But I did find an old version of .Net Reflector and when I ran that version, it updated itself to v6.7 (instead of v7). I think it still would be nice if RedGate would provide a download to v6.x from their website (that way every dev that used to use the free version of Reflector would still have access to it and if they wanted the next greatest version, they could pay for it).

Thursday, April 28, 2011

Tasks and the Smart Model

In a previous post I wrote about User Stories and Invest Model.

Here is a SMART model to use to determine if you have good tasks for your user stories or not:

A good task should be:

S Specific
M Measurable
A Achievable
R Relevant
T Time-boxed
   
http://xp123.com/articles/invest-in-good-stories-and-smart-tasks/

User Stories and Invest Model

Is your user-story a good one? Use the INVEST Model as one factor in deciding if it is:

I Independent
N Negotiable
V Valuable
E Estimatable
S Small
T Testable

http://xp123.com/articles/invest-in-good-stories-and-smart-tasks/

Friday, April 22, 2011

WP7 february and march updates – now available

Finally, the February and March updates for my Windows Phone 7 Samsung Focus are available….. installing them right now through zune.

image image

And the installation experience was flawless!

Tuesday, April 19, 2011

Determining the progress of a database restore process

A useful script for determining the progress of a database restore process.
SELECT  r.session_id,r.command,
	r.start_time,
	CONVERT(NUMERIC(6,2),r.percent_complete) AS [Percent Complete],
	CONVERT(VARCHAR(20),DATEADD(ms,r.estimated_completion_time,GetDate()),20) AS [ETA Completion Time],
	CONVERT(NUMERIC(10,2),r.total_elapsed_time/1000.0/60.0) AS [Elapsed Min],
	CONVERT(NUMERIC(10,2),r.estimated_completion_time/1000.0/60.0) AS [ETA Min],
	CONVERT(NUMERIC(10,2),r.estimated_completion_time/1000.0/60.0/60.0) AS [ETA Hours],
	CONVERT(VARCHAR(1000),
	(
		SELECT SUBSTRING(text,r.statement_start_offset/2,
			CASE  WHEN r.statement_end_offset = -1 THEN 1000  ELSE (r.statement_end_offset-r.statement_start_offset)/2  END)
		FROM sys.dm_exec_sql_text(sql_handle))
	)
	FROM sys.dm_exec_requests r WHERE command IN ('RESTORE DATABASE','BACKUP DATABASE')
and here is what the script outputs:
image

Getting Restore FileListOnly data into a table

Restore FileListOnly command is useful for determining the logical name, physical name, etc of a backedup database (*.bak) file.

Running “Restore FileListOnly” outputs a table and I needed to get the data into a table so as to be able to use it in an actual restore method.

Here is how you do it:

--First create a temp table with all the fields that Restore FileListOnly returns:
--list of fields and their definition pulled for Sql Server 2008 from (http://msdn.microsoft.com/en-us/library/ms173778.aspx)

DECLARE @restoreFileListData table (
    LogicalName nvarchar(128),
    PhysicalName nvarchar(260),
    [Type] char(1),
    FileGroupName nvarchar(128),
    Size numeric(20,0),
    MaxSize numeric(20,0),
    FileId bigint,
    CreateLSN numeric(25,0),
    DropLSN numeric(25,0) null,
    UniqueID UniqueIdentifier,
    ReadOnlyLSN numeric(25,0) null,
    ReadWriteLSN numeric(25,0) null,
    BackupSizeInBytes bigint,
    SourceBlockSize int,
    FileGroupID int,
    LogGroupGUID uniqueIdentifier null,
    DifferentialBaseLSN numeric(25,0)NULL,
    DifferentialBaseGUID uniqueIdentifier,
    IsReadOnly bit,
    IsPresent bit,
    TDEThumbPrint varbinary(32));

--Now execute the method and put the data into the temp table:

declare @cmd varchar(max)
set @cmd = 'RESTORE FILELISTONLY FROM  DISK = ''complete path to the bak file'''
insert into @restoreFileListData exec (@cmd);
select *  from @restoreFileListData t;
-- data is now available in the temp table

Friday, April 15, 2011

Powershell: Open current folder in Windows Explorer

The following command can be used to open the current folder in Windows Explorer from the PowerShell command line:

start-process $(get-location)

Thursday, April 14, 2011

select @@SERVERNAME not returning the correct server name

On my machine select @@SERVERNAME was returning “Windows7” instead of the actual server name.

I wanted to use @@ServerName for some script validation and hence needed it to return the correct machine name.

Here is what I had to do:

EXEC  Sp_dropserver 'Windows7'
EXEC  Sp_dropserver 'machineName' –this is not necessary, but on my machine I had a weird conflict and hence had to do it
EXEC  Sp_addserver 'machineName', 'local' –the local argument is REQUIRED

Finally restart your SqlServer instance.

Now run the following command to make sure everything worked correctly.

SELECT @@SERVERNAME AS SqlServerThinksTheServerIs, Serverproperty('Servername') AS theActualServerNameIs

The @@ServerName is especially important for the database deployment scripts created by Visual Studio’s database project as it uses it to validate that the script is being run on the correct machine.

Wednesday, April 13, 2011

My first PowerShell Sql script

The first thing you need to do is initialize the Sql Server Provider.

So first create a script called “InitializeSqlServerProvider.ps1” and put the following code into it:

#
# Add the SQL Server Provider.
#

$ErrorActionPreference = "Stop"

$sqlpsreg="HKLM:\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.SqlServer.Management.PowerShell.sqlps"

if (Get-ChildItem $sqlpsreg -ErrorAction "SilentlyContinue")
{
    throw "SQL Server Provider for Windows PowerShell is not installed."
}
else
{
    $item = Get-ItemProperty $sqlpsreg
    $sqlpsPath = [System.IO.Path]::GetDirectoryName($item.Path)
}


#
# Set mandatory variables for the SQL Server provider
#
Set-Variable -scope Global -name SqlServerMaximumChildItems -Value 0
Set-Variable -scope Global -name SqlServerConnectionTimeout -Value 30
Set-Variable -scope Global -name SqlServerIncludeSystemObjects -Value $false
Set-Variable -scope Global -name SqlServerMaximumTabCompletion -Value 1000

#
# Load the snapins, type data, format data
#
Push-Location
cd $sqlpsPath
Add-PSSnapin SqlServerCmdletSnapin100
Add-PSSnapin SqlServerProviderSnapin100
Update-TypeData -PrependPath SQLProvider.Types.ps1xml
update-FormatData -prependpath SQLProvider.Format.ps1xml
Pop-Location

Once you have that in a script, execute it.

Now you are ready to run commands against your sqlserver using the “Invoke-SqlCmd” cmdlet.

Invoke-sqlcmd -ServerInstance "." -Database "Master" -Query "exec sp_who"

The above command runs the “Sp_Who” stored proc against the local sqlServer instance.

Passing quoted arguments

In PowerShell when you need to pass arguments with spaces in them, you typically quote the phrase that is your argument:

write-host "hello world"

Prints: hello world

But how do you print “hello world”?

You use triple quotes: write-host """hello world"""

Outlook: Meeting requests get deleted when responding to a meeting invite

In Outlook, when I accept a meeting invite, Outlook automatically deletes the invite. This behavior used to bug me, because many times the email would contain important information on stuff that I had to work on.

Finally figured out that this behavior is configurable and you can turn it off through a dialog that is buried many levels deep.

Tools –> Options

Preferences Tab –> click button “Email Options” (under Email section)

Email Options dialog –> click button “Advanced Email Options…”

Advanced Email Options dialog –> Uncheck “Delete meeting request from Inbox when responding”

image

Tuesday, April 12, 2011

Quoted_Identifiers

Recently came across some problems that were being caused by quoted_identifiers being turned off.

Here is what turning it on or off allows you to do:

Two simple queries that are allowed at all times:

select top 100 * from tmpTable
--following 2 queries are not affected by quoted identifiers being turned on or off
--[] and ‘’ are always valid delimiters ([] for identifiers and ‘’ for literals)
select top 100 * from [tmpTable] 
select 'hello world'

set quoted_identifier off

select top 100 * from [tmpTable]
--select top 100 * from "tmpTable" –“” is not allowed as quoted identifiers is off
--as quoted identifiers is off – literals can be delimited by double or single quotes
select "hello world"
select 'hello world'

set quoted_identifier on

select top 100 * from [tmpTable]
select top 100 * from "tmpTable" –“” is allowed for identifiers as quoted identifiers is on
--select "hello world" –“” as a delimiter for literals is not allowed as quoted identifiers is on
select 'hello world'

And the problem I was facing was caused by the following requirement on Quoted Identifiers (from MSDN): SET QUOTED_IDENTIFIER must be ON when you are creating or changing indexes on computed columns or indexed views. If SET QUOTED_IDENTIFIER is OFF, CREATE, UPDATE, INSERT, and DELETE statements on tables with indexes on computed columns or indexed views will fail.

And here is a query to find all stored procs with quoted identfiers turned off (via zvolkov.com).

SELECT
SCHEMA_NAME(s.schema_id)  + '.' + s.name AS name,
s.create_date,
s.modify_date,
OBJECTPROPERTY(s.object_id,'ExecIsQuotedIdentOn') AS IsQuotedIdentOn
FROM sys.objects s
WHERE
s.type IN ('P','TR','V','IF','FN','TF')
AND OBJECTPROPERTY(s.object_id,'ExecIsQuotedIdentOn') = 0
ORDER BY SCHEMA_NAME(s.schema_id)  + '.' + s.name

Monday, April 11, 2011

Routing of Logging Messages–Enterprise Library

A graphic that I drew up to represent the routing of logging messages in EntLib’s Logging Application Block

image

Thursday, April 07, 2011

Example of a good user story

From: http://dannorth.net/whats-in-a-story/

A story should have a title, a narrative and a set of acceptance criteria presented as scenarios.

Title (one line describing the story)

Narrative:
As a [role]
I want [feature]
So that [benefit]

Acceptance Criteria: (presented as Scenarios)

Scenario 1: Title
Given [context]
And [some more context]...
When [event]
Then [outcome]
And [another outcome]...

And here is an example presented by the author in his post:

Story: Account Holder withdraws cash

As an Account Holder I want to withdraw cash from an ATM, so that I can get money when the bank is closed

Scenario 1: Account has sufficient funds
Given the account balance is $100
And the card is valid
And the machine contains enough money
When the Account Holder requests $20
Then the ATM should dispense $20
And the account balance should be $80
And the card should be returned

Scenario 2: Account has insufficient funds
Given the account balance is $10
And the card is valid
And the machine contains enough money
When the Account Holder requests $20
Then the ATM should not dispense any money
And the ATM should say there are insufficient funds
And the account balance should be $20
And the card should be returned

Scenario 3: Card has been disabled
Given the card is disabled
When the Account Holder requests $20
Then the ATM should retain the card
And the ATM should say the card has been retained

Scenario 4: The ATM has insufficient funds
...

Wednesday, April 06, 2011

Exposing the Service Helper page for ASMX web-services

When you access an ASMX based web-service from a browser on the machine that hosts the web-service, you will typically be shown the Service Helper page. The Service Helper page is useful for testing if the webservice is working correctly and provides you with a basic form with text-boxes for every parameter used by the web-service and an Invoke button that allows you to call the web-service method with the provided parameters.

Here is what it may look like:

image

The  service helper page (or as I call it, the Service Invoker page) is not displayed if you attempt to browse to the asmx page from a system other than the hosting webservice. The reason for this is security.

But this is very useful tool for the purpose of debugging and sometimes you just need to be able to access this service helper page from a different machine. Fret not, you can expose the service-helper page via the web.config.

Within the System.Web node add the following lines:

<webServices>
   
<protocols>
       
<add name="HttpSoap12"/>
       
<add name="HttpSoap"/>
       
<add name="HttpGet"/>
       
<add name="HttpPost"/>
   
</protocols>
</webServices>

For more information: MSDN: Configuration Options for XML Web Services Created using ASP.Net

Sunday, April 03, 2011

MVVM–Binding your VM to a Command

This post shows two ways in which you can connect UI elements like buttons in your View (V) to methods in your ViewModel (VM) with zero code in the view’s code-behind.

Here is what the View looks like:

image

The view displays the time and provides two buttons that allow you to update the time that’s being displayed on the page. (two buttons to demo the 2 ways to connect the view to the model)

First the ViewModel's code:

public class CommandingSampleViewModel : ViewModelBase
{
//exposes the UpdateTime method to the View
public DelegateCommand UpdateTimeCommand { get; private set; }

public CommandingSampleViewModel()
{
UpdateTimeCommand = new DelegateCommand(UpdateTime, CanExecuteUpdateTime);
if (IsDesignTime())
{
DateTimeString = "Hello World";
}
else
{
UpdateTime();
}
}

private void UpdateTime()
{
DateTimeString = DateTime.Now.ToString();
}

private bool CanExecuteUpdateTime()
{
return true;
}

public string _dateTimeString;
public string DateTimeString
{
get { return _dateTimeString; }
private set
{
if (_dateTimeString != value)
{
_dateTimeString = value;
RaisePropertyChanged(()=> DateTimeString);
}
}
}
}

The main thing to notice in the code above is the UpdateTimeCommand of type DelegateCommand. In the constructor, the UpdateTimeCommand is initialized and the method that is to be called when the UpdateTimeCommand is invoked from the view. The 2nd argument is a method that is provided for the view to determine if the command can be invoked. (In my sample it always returns true and hence you could use the other overloaded CTOR that doesn’t need the CanExecute method as a parameter).

The ViewModelBase used as the base class for the CommandingSampleViewModel above is defined below:

public class ViewModelBase : NotificationObject
{
protected bool IsDesignTime()
{
return DesignerProperties.IsInDesignTool;
}
}

Now the View’s code:

The first thing you need to do is to connect the View to its ViewModel. We first define the DataContext for the UserControl and then set the DataContext on the grid to the binding of the UserControl (done by simply setting the DataContext to {Binding}).

<UserControl.DataContext>
<vm:CommandingSampleViewModel/>
</UserControl.DataContext>
<Grid x:Name="LayoutRoot" Background="White" DataContext="{Binding}">
</Grid>
</UserControl>

Next we connect up a TextBlock to the DateTimeString property of the ViewModel (CommandingSampleViewModel) defined above:

<Grid x:Name="LayoutRoot" Background="White" DataContext="{Binding}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="Time:" Margin="5"></TextBlock>
<TextBlock Text="{Binding Path=DateTimeString}" Margin="5"></TextBlock>
</StackPanel>
</Grid>

Finally we setup two buttons that are connected to the UpdateTimeCommand defined in the ViewModel.

First, the code for the simplest way to connect up the button to the UpdateTimeCommand and that is to use the Command property of the button. Here we set the Binding Path to the DelegateCommand “UpdateTimeCommand” defined in the ViewModel. That’s all there is to it.

<Button Content="Update Time using direct binding" Command="{Binding Path=UpdateTimeCommand}" Margin="5"></Button>

Another method also available to connect up a View’s button to a DelegateCommand is to use the “Interaction.Triggers”. This method has some extra glue code but one advantage is that it provides a lot more customizability and also allows you to connect the view to the view-model in Expression Blend. Here is what the code looks like:

<Button Content="Update Time using Interaction.Triggers" Margin="5">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<i:InvokeCommandAction Command="{Binding Path=UpdateTimeCommand}"></i:InvokeCommandAction>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>

Within the Interaction.Triggers node, an EventTrigger is defined that connects the Click event of the button to the ViewMode’s method via the InvokeCommandAction node’s Command parameter.

Here is the complete code for the View (including the namespace includes needed for the view)

<UserControl x:Class="Silverlight.DataAccessClient.Views.CommandingSampleView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:vm="clr-namespace:Silverlight.DataAccessClient.ViewModels"
mc:Ignorable="d"
d:DesignHeight="75" d:DesignWidth="400" Height="75">
<UserControl.DataContext>
<vm:CommandingSampleViewModel/>
</UserControl.DataContext>
<Grid x:Name="LayoutRoot" Background="White" DataContext="{Binding}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="Time:" Margin="5"></TextBlock>
<TextBlock Text="{Binding Path=DateTimeString}" Margin="5"></TextBlock>
<StackPanel>
<Button Content="Update Time using direct binding" Command="{Binding Path=UpdateTimeCommand}" Margin="5"></Button>
<Button Content="Update Time using Interaction.Triggers" Margin="5">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<i:InvokeCommandAction Command="{Binding Path=UpdateTimeCommand}"></i:InvokeCommandAction>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
</StackPanel>
</StackPanel>
</Grid>
</UserControl>

There you have it, 2 simple ways in which to connect your view to your view-model’s method with ZERO code-behind in the View.

Here is what it looks like when the user-control is embedded in a Silverlight page:

image

Note: the DelegateCommand used is defined in Microsoft’s Prism framework (a great framework to use as a starting point for your MVVM implementation in Silverlight).

Saturday, April 02, 2011

Denver Auto Show 2011–Coupon Code

Get $2 off on your Denver Auto Show ticker (Adult tix are normally $10).

Use code CAR11 when you purchase the tickets in advance on their website: http://www.paragonexpo.com/index.php/DE-General/ (use the “Buy Tix Now” button).

Friday, April 01, 2011

Entity Framework and Oracle Databases

Earlier this year, Oracle released its data-access component to enable Entity Framework and Linq to Sql against Oracle databases.

The DAC is still in beta, but this is awesome news and will mean that Oracle users can also enjoy the awesomeness that is Entity Framework.

http://www.oracle.com/technetwork/topics/dotnet/downloads/oracleefbeta-302521.html