Friday, December 31, 2010

Lost manuals?

Check out this site for copies of manuals that you might have lost: http://www.retrevo.com/samples/index.html

Help for choosing a great #WindowsPhone7 device

This infographic put together by the folks at Technobolt allows you to quickly compare the important features of all the WP7 phones available, so that you can make the best choice based on your needs (Click to view it in its full glory):

I bought the Samsung focus based on its screen type (Super Amoled) and its weight and I love it!

Thursday, December 30, 2010

Interstate Road Conditions–WP7 App

BackgroundThis past week’s weather in the north-east and the impending snow that is about to hit Denver, left me wanting for a simple app that would allow me to quickly assess the conditions of the interstates that I might end up travelling. I have always used the interstate conditions pages on Weather.com (http://www.weather.com/activities/driving/interstate/). But what I wanted was the ability to quickly be able to take stock of interstate conditions in my region.

Out of this need was born the Windows Phone 7 app: Interstate Road Conditions.

It allows you to:

  • Get road conditions for the entire country or
  • Road conditions in one of the 9 regions of the country (North-east, east-central, south-east, north-central, central, south-central, north-west, west-central, south-west).

The maps support pinch to zoom and the application also provides you with direct links to Weather.com pages for the region you are viewing, allowing you to get in-depth and up to date information about road conditions.

Screen shots:

National road conditions mapNational road conditions map - zoomed inCentral road conditions mapCentral road conditions map (tomorrow)Central road conditions map - zoomed inMap in landscape modeWeather.com page in Internet Explorer (opened from a link in the app)

You can download the app (its free), using the following direct link to the application: http://social.zune.net/redirect?type=phoneApp&id=1c22d251-4b12-e011-9264-00237de2db9e

Videocast:

Wednesday, December 29, 2010

Application Version in Windows Phone 7

The typical method of retrieving application version using the code shown below doest work in Windows Phone 7 (it throws an exception).

string version = Assembly.GetExecutingAssembly().GetName().Version.ToString();

Instead you need to use the following code:

public static string GetVersion()
{
const string VerLabel = "Version=";
string assemblyName = System.Reflection.Assembly.GetExecutingAssembly().FullName;
int startIndex = assemblyName.IndexOf(VerLabel) + VerLabel.Length;
int endIndex = assemblyName.IndexOf(',', startIndex+1);
string version = assemblyName.Substring(startIndex, endIndex - startIndex);
return version;
}

Monday, December 27, 2010

Silverlight–Binding to a collection

Typically when you need to bind a value from a collection to a UIElement property you use the format: {Binding NameOfProperty}. (eg: <TextBlock Text=”{Binding FirstName}” />).

But what do you do when you need to bind to a collection of native types (eg: List<string>).

Simple – don’t enter the binding path. So the above textblock definition becomes: <TextBlock Text=”{Binding}” />

Saturday, December 25, 2010

Using Fiddler to inspect web-traffic from WP7 Emulator

  1. Click Tools > Fiddler Options.
  2. Open the Connections tab and put a check in the Allow remote computers to connect box
  3. Close the Options dialog
  4. In the QuickExec box under the session list, type 
    prefs set fiddler.network.proxy.registrationhostname HostName
    where HostName is the name of your computer

Friday, December 24, 2010

Silverlight–Adding columns and rows dynamically

Here is some code that shows you how to add rows and columns dynamically in Silverlight/Windows Phone 7.

The code depends on a Grid called ContentPanel defined in the XAML (found by default on a WP7 page).

ContentPanel.ColumnDefinitions.Clear();
ContentPanel.RowDefinitions.Clear();
int numColumnsToAdd = 4;
int numRowsToAdd = 4;
for (int column = 0; column < numColumnsToAdd; column++)
{
ColumnDefinition cd = new ColumnDefinition();
cd.Width = new GridLength(200);
ContentPanel.ColumnDefinitions.Add(cd);
}

for (int row = 0; row < numRowsToAdd; row++)
{
RowDefinition rd = new RowDefinition();
rd.Height = new GridLength(200);
ContentPanel.RowDefinitions.Add(rd);
}
//add an image into each
for (int row = 0; row < numRowsToAdd; row++)
{
for(int col = 0; col < numColumnsToAdd; col++)
{
TextBlock txt = new TextBlock();
txt.Text = "Hello";
ContentPanel.Children.Add(txt);
Grid.SetColumn(txt, col);
Grid.SetRow(txt, row);
}
}

And here is the result:

image

Stocks 50/200 screencast

http://www.stocks50200.com/2010/12/stocks-50200-screen-cast.html

Free music for podcasts

CCMixter has free music that is licensed under CreativeCommons, so you can include it in your podcasts/screencasts/etc.

http://ccmixter.org/view/media/remix

More free music links: http://creativecommons.org/legalmusicforvideos

Stocks 50/200 on Bing

http://www.bing.com/browse?g=wp7#toc=0&categories_rbid=3&r=16

Think only your windows servers are vulnerable….

A new Apache server exploit has been found that allows hackers to insert malicious script. Read more about it at: http://techcrunch.com/2010/12/21/hackers-embed-spam-into-google-search-listings-for-unsuspecting-sites/.

It is important to remember that the platform itselft doesn’t make your server/applications more or less secure, instead it is how you setup/configure/maintain/secure your server that impacts its vulnerability.

Thursday, December 23, 2010

Stocks 50/200 V1.1 now available

Version 1.1 is now available for download. If you have already downloaded the app, you should be able to upgrade to this version for free (and in most cases automatically).

Or get it using this link: http://social.zune.net/redirect?type=phoneApp&id=5c08bdaa-f4f4-df11-9264-00237de2db9e

Version 1.1 brings charts and some additional stock details to you.

Learn more at: http://www.stocks50200.com/2010/12/stocks-50200-v11-now-available.html

StocksDetails_v2_1 StocksDetails_v2_2

StocksDetails_v2_3

Sunday, December 19, 2010

802.11 a/b/g connection considerations

Based on the XBox 360 network tuner wizard here are some things to know:

802.11a or higher has the least amount of wireless interference. (802.11a is better and can be considered as coming after 802.11b – although both were created at the same time).

802.11b does not support many of the features required by Windows Media Center (802.11b is an early extension to 802.11 standard and is not as good a technology as 802.11a)

802.11g may produce choppy or slowed TV and video (this standard incorporates the best of 802.11 a and b standards)

802.11n is the newest of the standards and consequently considered as the best of the technologies.

More Info: http://en.wikipedia.org/wiki/IEEE_802.11

Friday, December 03, 2010

DebugView doesn’t work with Asp.Net app

I like to use a lot of Debug.WriteLine calls for monitoring how my application is working (especially when I am developing a new feature that might be resource intensive).

Debug.WriteLine will correctly output data to the Output window of Visual Studio. But if you run DebugView (the SysInternals tool for capturing debug data), you will find that DebugView doesn’t capture the debug text.

What I found was that for DebugView to see the debug data, you cannot have the VisualStudio debugger attached to that process. Once I reran my app without debugging (Ctrl + F5), DebugView automatically began displaying the debug text.

Another thing to remember is that you need to enable the “Capture Global Win32” option in DebugView for it to see Asp.Net debug messages.

image

Note:

This behavior is by design according to the Visual Studio team (Only one debug listener can be enabled at any given time). See: http://connect.microsoft.com/VisualStudio/feedback/details/457063/outputdebugstring-doesnt-work-in-the-debugger-vs-2010-pro-beta-1-c

The compiler will automatically ignore all calls to methods in the Debug class if you build your solution in Release configuration. So if you are wondering why your DebugView is not seeing your debug text in production, that is probably why.

Tuesday, November 30, 2010

Sql Server–Execute Permissions

One way to provide users execute permissions on a database: (works in Sql Server 2005 and above)
Create a role and grant it execute permissions. Then add your user to that role.
/* CREATE A NEW ROLE */
CREATE ROLE db_executor

/* GRANT EXECUTE TO THE ROLE */
GRANT EXECUTE TO db_executor

Monday, November 29, 2010

Samsung Focus–Diagnostics commands

via: http://forum.xda-developers.com/wiki/index.php?title=Samsung_Focus

Samsung Focus Diagnostic Mode To access the diagnostic program you will need to dial ##634# from the phone pad.
Diagnostic Commands:

  • *#0*# - LCD Test
  • *#0002*28346# - Audio control utility.
  • *#0011# - Power and Temperature and Network Connection monitoring
  • *#0228# - Battery Information
  • *#0289# - Melody Test\Test External and Internal Speaker
  • *#03# - SMDInfo
  • *#05# - Simple test menu
  • *#06# - Show IMEI #
  • *#0673# - MP3 Test Menu\Shows Audio sound tests
  • *#0782# - Shows Clock & Alarms settings
  • *#0842# - Vibrate test menu
  • *#0987# - Multitouch test
  • *#1111# - Show FTA software version
  • *#1234# - Shows the PDA and the Phone version number
  • *#197328640# - The Root Menu
  • *#2*# - Battery Information
  • *#2222# - Show FTA hardware version
  • *#2263# - RAT Selection option is restricted
  • *#232337# - Bluetooth MAC Address
  • *#2580# - Integrity Control
  • *#3*# - Test Brightness
  • *#32489# - (GSM test) Shows the ciphering status and options to enable or disable it.
  • *#7284# - USB Path control
  • *#745# - Operation (2): Ril log done
  • *#7450# - Operation (99):Error Report off done
  • *#7451# - Operation (99):Error Report off done
  • *#7465625# - Shows status of the Network Service Provider SIM or Corporation lock
  • *#770# - Operation (99):Vphone 770 done!
  • *#771# - Operation (99):Vphone 771 done!
  • *#772# - Operation (99):Vphone 772 done!
  • *#773# - Operation (99):Vphone 773 done!
  • *#774# - Operation (99):Vphone 774 done!
  • *#775# - Operation (99):Vphone 775 done!
  • *#776# - Operation (99):Vphone 776 done!
  • *#777# - Operation (99):Vphone 777 done!
  • *#778# - Operation (99):Vphone 778 done!
  • *#779# - Operation (99):Vphone 779 done!
  • *#780# - Operation (99):SR Test done!
  • *#9090# - Diag Config\UART/USB settings
  • *2767*3855# - Full Reset (Caution every stored data will be deleted.)

Tethering Currently instructions only apply to AT&T network, USA.

  • Open the phone screen composition
  • Enter the code: # # 634 # > Press Call<br.
  • This will open a new screen will be similar but in test mode
  • Then type in the code * # 7284 # > Press Call
  • See the screen that you see in the picture > Select Tethered
  • The phone will restart
  • Attach the USB cable to your phone and PC and wait for it to install drivers
  • You will see the phone modem and you can configure the data connection
  • number: *99***1#
  • user name: WAP@CINGULARGPRS.COM
  • password: CINGULAR1

WP7, Samsung Focus and Tethering

Only available via the diagnostics menu:

Dial ##634#. This will open the diagnostics screen.

Dial *#7284#. This will open the tethering configuration dialog.

Select the option “Modem, tethered call”. The phone will take you through a set of steps to configure tethering and will restart the phone. Voila! tethering is now enabled.

Danger: You run the risk of bricking your phone, getting crazy bills from your carrier, etc. So do the above at your own risk.

Sunday, November 28, 2010

Fear and Risk

If you arent scared then you arent taking a risk

for a nation to remain true to its ideals….

For if this Nation is to remain true to the ideals symbolized by its flag, it must not wield the tools of tyrants even to resist an assault by the forces of tyranny.

Justice John Paul Stevens.

Saturday, November 27, 2010

Determining theme on WP7

Knowing which theme has been selected by the user for their WP7 device is important especially if you are using images or colors that work well for one theme and not another. In this case you will have to change the colors/images depending on the currently selected theme.

Here is the simplest way to determine whether the currently selected theme is “Light” or “Dark”

public static bool LightThemeEnabled
{
get
{
return (Visibility)Application.Current.Resources["PhoneLightThemeVisibility"] == Visibility.Visible;
}
}

The property returns true if the currently selected theme is the light theme and false if the selected theme is the dark theme.

Incidentally, this is one of the easiest reasons for your app to get rejected during certification for the Market Place. So remember to check all your screens under both the Light and Dark themes.

Jailbreaking comes to WP7

Its called ChevronWp7 and you can read more about it at: http://www.istartedsomething.com/20101126/chevronwp7-windows-phone-7-unlocker-released/

Friday, November 26, 2010

WP7 – Screen Capture on Device

One of the biggest features that I miss as a developer/blogger on the Windows Phone 7 device is the ability to take a screen shot.

The saving grace is that it is extremely easy to add code to your app so as to be able to capture the screen and save it to your album. Once the image has been saved, you can upload it to SkyDrive or to your computer via a Sync operation. (This is better than storing it to isolated storage, as that makes it harder to get at the image).

Here is the code:

using System.Windows.Media.Imaging;
using Microsoft.Advertising.Mobile.UI;
using Microsoft.Phone.Controls;
using Microsoft.Xna.Framework.Media;
using System.IO;

public static class Utility
{
/// <summary>
/// Currently supported only on the device. (Does not do anything while running with the emulator)
/// Will throw an exception if called while the device is connected to the computer (tethered mode)
/// so dont do that!
/// </summary>
/// <param name="page">the page whose screen shot needs to be captured</param>
/// <param name="saveName">the name that the image should be saved under - the device seems to ignore this parameter
/// and hence its ok to call this method with the same name multiple times, each image is stored separately</param>
/// <param name="quality">the jpeg image quality parameter</param>
/// <returns>A picture object representing the image</returns>
public static Picture DoCapture(this PhoneApplicationPage page, string saveName, int quality)
{
//first save to bitmap
WriteableBitmap bmp = new WriteableBitmap((int)page.ActualWidth, (int)page.ActualHeight);
bmp.Render(page, null);
bmp.Invalidate();

//get memoryStream from bitmap and save to media library
Picture picture = null;
using (MemoryStream memoryStream = new MemoryStream())
{
bmp.SaveJpeg(memoryStream, bmp.PixelWidth, bmp.PixelHeight, 0, quality);
MediaLibrary mediaTest = new MediaLibrary();

memoryStream.Seek(0, SeekOrigin.Begin);
//name cannot be empty or null
//by default image gets saved to the album "Saved Pictures"
//SavePicture will throw an exception if called while the device is tethered
picture = mediaTest.SavePicture(saveName, memoryStream);
}
return picture;
}
}

And here is one method to call it from one of your application’s pages:

private void ApplicationBarCaptureButton_Click(object sender, EventArgs e)
{
try
{
Picture picture = this.DoCapture("Stocks 50-200.jpg",95);
MessageBox.Show("Screen capture saved: " + picture.Album + " " + picture.Name, "Screen Captured",
MessageBoxButton.OK);
}
catch (Exception exp)
{
MessageBox.Show(exp.Message, "Error saving screen", MessageBoxButton.OK);
throw;
}
}

Something to notice is that as DoCapture was defined as an extension method, I am able to call it using the following syntax: this.DoCapture.

And here is what a saved screen-shot looks like (taken from my WP7 App – Stocks 50-200):

69

Sunday, November 21, 2010

Cool Windows Phone 7 Features via Windows Live

No paying a $100 for a “MobileMe” service. The following awesome features come standard with your Windows Phone 7.

The images say everything:

Map it: see your phone’s approximate location

image

Ring it: Ring your phone, even if its on silent or vibrate mode!

image

Lock it: Lock your phone and even put a “please return” note on it.

image

Erase it: Erase all your personal information remotely.

image

Do more at WindowsPhone.Live.Com

Resetting your iPhone and preparing it for resale

If you plan on selling your iPhone or reselling it, then you should reset it, so as to clear it of all your personal information.

The quick and easy way to do this, is to connect it to iTunes and then using the restore function. (You will be prompted for backing up your phone, but as you plan on not using it – you can just answer no).

image

In addition, the under the Settings application on the iPhone, there is an option for resetting the phone. I am not sure if it is needed – but just to be on the safe side, I reset the device’s settings and content.

Saturday, November 20, 2010

Wp7 App: Stocks 50-200: more information

Read all about the Stocks 50-200 application that should soon hit the Windows Phone 7 marketplace at: http://www.stocks50200.com/2010/11/stocks-50-200.html

http://www.stocks50200.com/

WP7–AdControl–Remote connection to the device has been lost

I was playing with the Windows Phone 7 AdControl and I could not get it working.

I kept getting the following error:

“The remote connection to the device has been lost.  Please verify the device connection and restart debugging.”
image

After hours of debugging I found out the reason I was getting this error was because I had customized the “WMAppManifest.xml” file and had commented out the networking and web-browser component usage capabilities for my test app, as I thought I didn’t need them. Once I uncommented those lines, voila! the adControl began working.

So if you get the above error make sure you are specifying the following capabilities for your application:

<Capability Name="ID_CAP_NETWORKING" />
<Capability Name="ID_CAP_WEBBROWSERCOMPONENT" />

Another thing to take a look at are the AdUnitId and ApplicationId values that you are using while initializing the control.

Stocks 50/200…. Coming Soon

Coming soon at http://www.stocks50200.com/

StartupScreen

Wednesday, November 17, 2010

Sql Server– A function to create a temp-table from a delimited string

Here is a SqlServer user defined function that takes as input a delimiter separated string and the delimiter and returns a table.

CREATE FUNCTION [dbo].[StringToTable]
(   
    @inString varchar(8000),
    @delimiter varchar(30)
)
returns @tempTable table (keyvalue varchar(50))
AS
begin
    declare @item varchar(50)
   
    -- remove leading comma
    if substring(@inString,1,1) = @delimiter
        begin
            set @inString = substring(@inString,2,len(@inString))
        end

    -- put in the comma if not there
    if substring(@inString, len(@inString),1) != @delimiter
        begin
            set @inString = @inString + @delimiter
        end

    -- go through and put all the strings in the table
    while charindex(@delimiter,@inString) > 0
        begin
            set @item = substring(@inString,1,charindex@delimiter,@inString)-1)
            insert @tempTable (keyvalue) values (@item)
            set @inString = substring(@inString,charindex@delimiter,@inString)+1, len(@inString))
        end

return

end

Using the StringToTable method:

select * from StringToTable ('Hello,World', ',')

returns:

keyvalue
Hello
World

Wednesday, November 10, 2010

Creating mock DataTable and DataRow objects

For the purpose of testing….
DataRow cannot be instantiated directly as its constructor is protected.
First create the DataTable with the columns you want it to have and then call DataTable.NewRow(). (This just returns a new DataRow object with the schema as specified in DataTable, to add it to the DataTable call DataTable.Rows.Add().


    DataTable table = new DataTable();
    table.Columns.Add("Column1", typeof(int));
    table.Columns.Add("Column2", typeof(string));
    table.Columns.Add("Column3", typeof(string));
    table.Columns.Add("Column4", typeof(DateTime));
    DataRow dataRow = table.NewRow();
    dataRow["Column1"] = 1;
    dataRow["Column2"] = "1";
    dataRow["Column3"] = "1";
    dataRow["Column4"] = DateTime.Now;
    table.Rows.Add(dataRow);






Sql Server–Refresh Intellisense Symbols

To refresh the intellisense list that Sql Server Management Studio displays when typing queries, uses the “Refresh Local Cache” command in the Edit –> Intellisense menu.

image

Saturday, November 06, 2010

.Net–The difference between IEnumerable and IEnumerator

The easiest way to think about these 2 interfaces:

An object that is enumerable will provide an enumerator that allows you to enumerate over that object – Kapish?!

The interface IEnumerable defines one method: GetEnumerator that returns an object that implements IEnumerator. IEnumerator defines methods such as Current, MoveNext and Reset. Typically an object that implements IEnumerable, does so because it contains a list of data-items. Calling GetEnumerator on that object then provides us with an object that manages the iteration over the list of items contained on that object.

In terms of the “Gang of Four” patterns, IEnumerable and IEnumerator implement the iterator pattern and IEnumerable is the Aggregate and IEnumerator is the Iterator.

Sql Server–Performing updates in batches

If you have a table with millions of rows and you want to update one of its columns, one problem that you can run into is that the update causes the log file to grow to such an extent that you run out of space.

One work-around to this problem with the log file growing very large is to update the table in small batches. (Especially when you use Simple logging, this can lead to the log file not growing by much at all).

Here is how I did it:

1. Added a column called Updated to the table. (This column is used to keep track of if the row was updated or not. Based on your tables structure you may or may not need to do this). This column will be deleted at the end of the script.

2. Update the table using top(1000) option.

3. Delete the column used to keep track of whether the row was updated or not.

ALTER TABLE [dbo].[sample]
ADD [updated] BIT NULL;

while (1 = 1)
begin
	Begin Transaction;
	UPDATE top (1000) [dbo].[sample]
		SET [mySampleData] = newValue,
		[updated] = 1
	FROM   [dbo].[sample]
	WHERE [updated] is null;

	if (@@RowCount = 0)
		break;
	Commit Transaction;
end
Commit Transaction;
go
ALTER TABLE [dbo].[sample] DROP COLUMN [updated]
go

Sunday, October 31, 2010

WCF Code Samples on MSDN

List of all WCF code samples on MSDN as collected by J.D. Meier

http://innovation.connect.microsoft.com/devguidancemaps/wikipage?title=WCF%20Code%20Samples&referringTitle=WCF%20Developer%20Guidance%20Map

A great resource when working with WCF.

Windows Phone–Url formats

Urls used to navigate to different pages must always start with a “/” (forward slash). This is because “NavigationService.Navigate” only allows relative Urls.

Urls used as the source for Image controls can contain a beginning slash, but can also omit them and it will still work.
So both of the following are valid ways to reference images in your WP app. (as long as you have set the build action on the image to Content and the build action to Copy Always/If Newer).

Image Name="image1" Source="Assets/image.jpg"
Image Name="image1" Source="/Assets/image.jpg"

Tips:
Silverlight for Windows Phone 7 only supports Png and Jpeg. Gif is not supported.

Windows Phone - Emulator error on startup–Port is in use

If you get the error “specified communication resource (port) is already in use by another application.”

Browse to the folder: %LocalAppData%\Microsoft\Phone Tools\CoreCon and delete its contents.

Restart Visual Studio. Try and redeploy the app.

Other tips:

The Emulator runs within a virtual machine. Sometimes you might have to do hardcore things to get the emulator working again.

At the command prompt type: sc query vmm. This should return running if the VMM service that hosts the emulator is running.

To restart the service: first type sc stop vmm and then type sc start vmm.

Now restart the emulator.

Thursday, October 28, 2010

PDF–Getting Acrobat to remember the last page opened

It is annoying to read a long e-book that is in PDF format with the Adobe reader, because by default it does not remember the last page you were in when you shut down the reader.

Turns out, Adobe Acrobat can remember the last page you were reading…

Go to preferences (Edit –> Preferences) and set the “Restore last view settings when reopening documents” setting under the Documents categories.

image

Monday, October 25, 2010

Sql Server–Determining version of client drivers

via: http://blogs.msdn.com/b/sqlcat/archive/2010/10/26/how-to-tell-which-version-of-sql-server-data-access-driver-is-used-by-an-application-client.aspx
T-Sql script to determine the version of SqlServer drivers being used by the client:
SELECT session_id, protocol_type,
driver_version = CASE CONVERT(CHAR(4), CAST(protocol_version AS BINARY(4)), 1)
WHEN '0x70' THEN 'SQL Server 7.0'
WHEN '0x71' THEN 'SQL Server 2000'
WHEN '0x72' THEN 'SQL Server 2005'
WHEN '0x73' THEN 'SQL Server 2008'
ELSE 'Unknown driver'
END
FROM sys.dm_exec_connections


Another useful script (this one provides you a string formated like this "SQL Server 10.0.2531.0 - SP1 (Developer Edition (64-bit))")

SELECT 'SQL Server '
    + CAST(SERVERPROPERTY('productversion') AS VARCHAR) + ' - '
    + CAST(SERVERPROPERTY('productlevel') AS VARCHAR) + ' ('
    + CAST(SERVERPROPERTY('edition') AS VARCHAR) + ')'

TFS Build Issues –Path is already mapped in workspace

Issue:

TFS server: running TFS 2008
Team Build Server: running Team Build 2008. VS 2008 is installed and VS 2010 was recently installed on the machine

Error: “The path xxxx is already mapped in workspace xxxx”

We started getting the above error when ever a team build was run and it started happening immediately after installing VS2010 on the build machine.

The problem seems to be that the build machine thinks that a duplicate workspace exists, when it should just think of it as the same workspace. (I am not sure – I am just theorizing here).

Anyways, to fix it here is what I did:

At the VS command prompt I ran the following command: “tf workspaces /owner:{AccountUsedByBuildMachine} /computer:{buildMachineName}”.
The command will list out all the workspaces currently registered to the build account on the build machine.

Next run the following command for each of the above workspaces: “tf workspace /delete {WorkspaceNameToDelete};{AccountUsedByBuildMachine}”. This command will delete the workspace.

Once the workspaces are deleted, you should be able to queue up new builds and they should all work.

Friday, October 22, 2010

Making sense of WCF configuration

Created this diagram as a note to myself regarding the basics of WCF configuration.

WCF Configuration

Things to note:
The ABCs (address, binding, contract) are defined at the EndPoint level. {The address defines where the service is published, the binding defines how to connect to the service and the contract defines what the service can do}
Apart from the Service and Endpoint, none of the other elements are required. (In WCF 4, none of the elements are needed due to auto-configuration, but I still prefer defining the configuration, because of the control it provides me).
You can have multiple end-points for a given service (this allows you to provide endpoints that allow clients to connect using different protocols [bindings]).
The boxes in green, although not required, it is a good idea to define them. (ServiceBehavior defines things such as whether a WSDL document will be generated for the service and BindingConfiguration define specific behavior for each binding that is being used)
The boxes in orange are not required and should be defined only if you need specific control over the endpoint behavior

The diagram below shows how the different sections of the WCF configuration relate to each other.

WCF Configuration2

kick it on DotNetKicks.com

Thursday, October 21, 2010

Enterprise Library–Logging Formatter Token List

Here is the list of tokens available for the text formatter under the logging block:

activity id {activity}
appDomain Name {appDomain}
category {category}
errorMessages {errorMessages}
event Id {eventid}
machine Name {machine}
message {message}
priority {priority}
processId {processId}
processName {processName}
severity {severity}
thread Name {threadName}
timeStamp {timestamp} or {timestamp(local)}
titleToken {title}
win32 ThreadId {win32ThreadId}

Dictionary {dictionary({key} – {value})}

Formatting tokens:
Tab {tab}
NewLine {newline}

Here is a sample template for the text formatter:

"Timestamp: {timestamp(local)}{newline}
{tab}Message: {message}{newline}
{tab}Category: {category}{newline}
{tab}Priority: {priority}{newline}
{tab}EventId: {eventid}{newline}
{tab}Severity: {severity}{newline}
{tab}Title:{title}{newline}
{tab}Machine: {machine}{newline}
{tab}Application Domain: {appDomain}{newline}
{tab}Process Id: {processId}{newline}
{tab}Process Name: {processName}{newline}
{tab}Win32 Thread Id: {win32ThreadId}{newline}
{tab}Thread Name: {threadName}{newline}
{newline}
{tab}Extended Properties: {dictionary({key} - {value})}"

And here is a template formatted for output to XML: (my preferred method for logging to the database)

 template="&lt;log&gt;&lt;timestamp&gt;{timestamp(local)}&lt;/timestamp&gt;
                    &lt;message&gt;{message}&lt;/message&gt;
                    &lt;category&gt;{category}&lt;/category&gt;
                    &lt;priority&gt;{priority}&lt;/priority&gt;
                    &lt;eventId&gt;{eventid}&lt;/eventId&gt;
                    &lt;severity&gt;{severity}&lt;/severity&gt;
                    &lt;title&gt;{title}&lt;/title&gt;
                    &lt;machine&gt;{machine}&lt;/machine&gt;
                    &lt;applicationDomain&gt;{appDomain}&lt;/applicationDomain&gt;
                    &lt;processId&gt;{processId}&lt;/processId&gt;
                    &lt;processName&gt;{processName}&lt;/processName&gt;
                    &lt;win32ThreadId&gt;{win32ThreadId}&lt;/win32ThreadId&gt;
                    &lt;threadName&gt;{threadName}&lt;/threadName&gt;
                    &lt;extendedProperties&gt;
                     {dictionary(&lt;key&gt;{key}&lt;/key&gt;&lt;value&gt;{value}&lt;/value&gt;)}&lt;/extendedProperties&gt;&lt;/log&gt;"
The &lt; and &gt; are there so that you can insert it in the config file without VS complaining about invalid xml characters.

C# 4.0–New Feature: Enums, Flags and HasFlag

C# 4.0 adds a new instance method called “HasFlag” on Enum types.

This is a convenience methods that allows you to check if a flag (bit) has been set on an enum value.

eg:

The System.IO.FileAccess enum is defined as follows:

[Serializable, ComVisible(true), Flags]
public enum FileAccess
{
   Read = 1,
   ReadWrite = 3,
   Write = 2
}

Code:

FileAccess fileAccessMode = FileAccess.Read;

if (fileAccessMode.HasFlag(FileAccess.Write))
{
   ……………
}

if (fileAccessMode.HasFlag(FileAccess.Read))
{
   ……………
}

the above code basically translates to:

if ( (fileAccessMode & FileAccess.Write) == FileAccess.Write)
{
   ……………
}

if ( (fileAccessMode & FileAccess.Read) == FileAccess.Read)
{
   ……………
}

MSDN: http://msdn.microsoft.com/en-us/library/system.enum.hasflag.aspx

Wednesday, October 20, 2010

Five DMV Queries That Will Make You A Superhero!

via: http://glennberrysqlperformance.spaces.live.com/blog/cns!45041418ECCAA960!828.entry

In order to get the best results from these queries, you should run DBCC FREEPROCCACHE on your server a few minutes before you run them. Otherwise, the Age in Cache values will not be the same, which will skew the results of these queries. Of course, you should be aware for the effect of running DBCC FREEPROCCACHE on a production server before you do it.

Query 1 shows you which stored procedures are being called the most often.

    -- Get Top 100 executed SP's ordered by execution count
    SELECT TOP 100 qt.text AS 'SP Name', qs.execution_count AS 'Execution Count',  
    qs.execution_count/DATEDIFF(Second, qs.creation_time, GetDate()) AS 'Calls/Second',
    qs.total_worker_time/qs.execution_count AS 'AvgWorkerTime',
    qs.total_worker_time AS 'TotalWorkerTime',
    qs.total_elapsed_time/qs.execution_count AS 'AvgElapsedTime',
    qs.max_logical_reads, qs.max_logical_writes, qs.total_physical_reads, 
    DATEDIFF(Minute, qs.creation_time, GetDate()) AS 'Age in Cache'
    FROM sys.dm_exec_query_stats AS qs
    CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS qt
    WHERE qt.dbid = db_id() -- Filter by current database
    ORDER BY qs.execution_count DESC

Query 2 shows the top 20 stored procedures sorted by total worker time (which equates to CPU pressure). This will tell you the most expensive stored procedures from a CPU perspective.

    -- Get Top 20 executed SP's ordered by total worker time (CPU pressure)
    SELECT TOP 20 qt.text AS 'SP Name', qs.total_worker_time AS 'TotalWorkerTime', 
    qs.total_worker_time/qs.execution_count AS 'AvgWorkerTime',
    qs.execution_count AS 'Execution Count', 
    ISNULL(qs.execution_count/DATEDIFF(Second, qs.creation_time, GetDate()), 0) AS 'Calls/Second',
    ISNULL(qs.total_elapsed_time/qs.execution_count, 0) AS 'AvgElapsedTime', 
    qs.max_logical_reads, qs.max_logical_writes, 
    DATEDIFF(Minute, qs.creation_time, GetDate()) AS 'Age in Cache'
    FROM sys.dm_exec_query_stats AS qs
    CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS qt
    WHERE qt.dbid = db_id() -- Filter by current database
    ORDER BY qs.total_worker_time DESC
    

Query 3 shows the top 20 stored procedures sorted by total logical reads(which equates to memory pressure). This will tell you the most expensive stored procedures from a memory perspective, and indirectly from a read I/O perspective.

    -- Get Top 20 executed SP's ordered by logical reads (memory pressure)
    SELECT TOP 20 qt.text AS 'SP Name', total_logical_reads, 
    qs.execution_count AS 'Execution Count', total_logical_reads/qs.execution_count AS 'AvgLogicalReads',
    qs.execution_count/DATEDIFF(Second, qs.creation_time, GetDate()) AS 'Calls/Second', 
    qs.total_worker_time/qs.execution_count AS 'AvgWorkerTime',
    qs.total_worker_time AS 'TotalWorkerTime',
    qs.total_elapsed_time/qs.execution_count AS 'AvgElapsedTime',
    qs.total_logical_writes,
    qs.max_logical_reads, qs.max_logical_writes, qs.total_physical_reads, 
    DATEDIFF(Minute, qs.creation_time, GetDate()) AS 'Age in Cache', qt.dbid 
    FROM sys.dm_exec_query_stats AS qs
    CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS qt
    WHERE qt.dbid = db_id() -- Filter by current database
    ORDER BY total_logical_reads DESC

Query 4 shows the top 20 stored procedures sorted by total physical reads(which equates to read I/O pressure). This will tell you the most expensive stored procedures from a read I/O perspective.

    -- Get Top 20 executed SP's ordered by physical reads (read I/O pressure)
    SELECT TOP 20 qt.text AS 'SP Name', qs.total_physical_reads, qs.total_physical_reads/qs.execution_count AS 'Avg Physical Reads',
    qs.execution_count AS 'Execution Count',
    qs.execution_count/DATEDIFF(Second, qs.creation_time, GetDate()) AS 'Calls/Second',  
    qs.total_worker_time/qs.execution_count AS 'AvgWorkerTime',
    qs.total_worker_time AS 'TotalWorkerTime',
    qs.total_elapsed_time/qs.execution_count AS 'AvgElapsedTime',
    qs.max_logical_reads, qs.max_logical_writes,  
    DATEDIFF(Minute, qs.creation_time, GetDate()) AS 'Age in Cache', qt.dbid 
    FROM sys.dm_exec_query_stats AS qs
    CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS qt
    WHERE qt.dbid = db_id() -- Filter by current database
    ORDER BY qs.total_physical_reads DESC

Query 5 shows the top 20 stored procedures sorted by total logical writes(which equates to write I/O pressure). This will tell you the most expensive stored procedures from a write I/O perspective.

    -- Get Top 20 executed SP's ordered by logical writes/minute
    SELECT TOP 20 qt.text AS 'SP Name', qs.total_logical_writes, qs.total_logical_writes/qs.execution_count AS 'AvgLogicalWrites',
    qs.total_logical_writes/DATEDIFF(Minute, qs.creation_time, GetDate()) AS 'Logical Writes/Min',  
    qs.execution_count AS 'Execution Count', 
    qs.execution_count/DATEDIFF(Second, qs.creation_time, GetDate()) AS 'Calls/Second', 
    qs.total_worker_time/qs.execution_count AS 'AvgWorkerTime',
    qs.total_worker_time AS 'TotalWorkerTime',
    qs.total_elapsed_time/qs.execution_count AS 'AvgElapsedTime',
    qs.max_logical_reads, qs.max_logical_writes, qs.total_physical_reads, 
    DATEDIFF(Minute, qs.creation_time, GetDate()) AS 'Age in Cache',
    qs.total_physical_reads/qs.execution_count AS 'Avg Physical Reads', qt.dbid
    FROM sys.dm_exec_query_stats AS qs
    CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS qt
    WHERE qt.dbid = db_id() -- Filter by current database
    ORDER BY qs.total_logical_writes DESC

Enterprise Library – Logging Database creation script

The Enterprise Library database creation scripts can be found in the following location:

Version 3.x : \App Blocks\Src\Logging\TraceListeners\Database\Scripts

Version 5.x : \Blocks\Logging\Src\DatabaseTraceListener\Scripts

(you need to download the source files to get the scripts).

Saturday, October 16, 2010

Zune installation error 0x80070643

Got the 0x80070643 error while trying to install version 4.7 of the software. Seems to be a common problem.

After trying many things:
1. Uninstall old version of Zune
2. Change permissions on “HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components” to the Administrator.
3. Delete the Zune folder in the Program Files folder
4. Created the zune folder in the program files folder

The one thing that seemed to make the installer work was a system restart. Not sure if any of the above steps helped, but if you have the same problem, I would first try and restart the computer. If that doesn’t work, uninstall your existing Zune install and then restart and then reinstall. (imo: I think the problem probably stems from the fact that the installer is trying to install without forcing a system restart – sometimes a system needs to be restarted when attempting an upgrade – nothing wrong with that!)

I love the Zune, Windows Phone 7 platforms. But you would think that when Microsoft is trying to go after the Apple iPhone/iTouch market, they would better test the installer and also have some meaningful error messages that make sense to the masses (what in the world is 0x80070643).

Friday, October 15, 2010

Modelling WSDL documents as UML

A picture says a thousand words and a UML diagram is definitely the easiest way to understand a SOAP based web-service.
I had blogged about HyperModel a while back, which is the best free tool that I have come across for modelling XML documents as UML. (http://www.xmlmodeling.com/download)
I have found it (XmlModelling) immensely useful for understanding Soap-based webservices (such as WCF services) as it breaks down visually the inputs and outputs of an operation and the various data-types and enumerations that the service supports.
Unfortunately there are 2 problems with Hypermodel. 1. Hypermodel hasn’t been updated in a while (last update: 5 July, 2008) – my biggest worry is this awesome tool will just die off and not be updated to support changes to the XML specification. 2: The tool isnt exactly intuitive to use when it comes to modelling WSDL documents.
Here I plan to remedy the 2nd problem:
  1. First you need to download the WSDL documents associated with the web-service. In this case I am going to use this public facing soap-service: http://www.webservicex.net/WeatherForecast.asmx?WSDL
    To do this I am going to use another awesome tool – SoapUI.
    Once installed, you need to import the web-service into SoapUI. After that, right click on the service and select “Export Definition”.
    Image 1
  2. The above step will export the WSDl document. (Note: sometimes the SoapUI file dialog takes a while to become responsive – so be patient). Depending on the WSDL file, you will find that SoapUI exported the wsdl documents as a series of files with the extension .WSDL or .XSD. (note: I found that WCF4 exports a nice set of XSD documents, whereas older versions result in WSDL documents). If the file does not already have a XSD extension, rename the extension. (Hypermodel will only read XSD files).
  3. Start up Hypermodel. (if its your first time starting up Hypermodel, you might have to setup some preferences. Just choose the defaults – as these worked for me).
    Next, open the file menu and select Import XSD.
    Image 2 
  4. The Import XSD command will open the Import XSD Schemas dialog.
    The parent folder is just a way for you to organize your imported XML document. Name it anything you want. The filename, needs to end with .XML, otherwise the Next button will not enable.
    Image 3
    Click Next.
  5. Click next on the next dialog.
    Image 5
  6. If everything ran correctly, you should end up seeing a tree of all the XML objects that were defined in the WSDL document.
    Image 6
  7. You can now select the elements that you need to visualize as UML and select the “Class Dynagram” option from the context menu.
    Image 7
  8. Voila!
    Image 8
You can try generating the UML for the following web-service: http://ws.cdyne.com/delayedstockquote/delayedstockquote.asmx?wsdl
Which should look like this:
image
References:
List of web-services on which you can try the above steps: http://www.visualwebservice.com/web-services.do

Thursday, October 14, 2010

WP7–InputScopeValues and the key layouts

Screen shots of layouts of the different keypad layouts available on the WIndows Phone 7 (as taken from the emulator).

InputScopeValues - http://msdn.microsoft.com/en-us/library/system.windows.input.inputscopenamevalue.aspx

tip: If you want to start your app with the SIP keypad displayed, one easy method is to set focus on a text box on the page.

this.Loaded += 
new RoutedEventHandler((object sender, RoutedEventArgs e) => {txtBox.Focus();});
Default image
Url image
FullFilePath image
FilePath image
EmailUserName
EmailSmtpAddress
image
LogOnName image
PersonalFullName
PersonalNamePrefix
PersonalGivenName
PersonalMiddleName
PersonalSurName
PersonalNameSuffix
image
PostalCode
AddressStreet
image
AddressStateOrProvince
AddressCity
AddressCountryName
AddressCountyShortName
image
CurrenyAmountAndSymbol
CurrencyAmount
image
Date image
DateMonth
DateDay
DateYear
image
DateDay  
DateDayName image
Digits
Number
image
OneChar
Password
image
TelephoneNumber
TelephoneCountryCode
TelephoneAreaCode
TelephoneLocalNumber
image
Time
TimeHour
TimeMinorSec

image
NumberFullWidth
AlphanumericHalfWidth
AlphanumerFullWidth
image
Text
Chat
image
Search image
NameOrPhoneNumber image