Friday 28 August 2009

Data Entry Applications

ASP.NET Dynamic Data

TierDeveloper

Some Useful Extension Methods

In
Syntax:

public static bool In(this T e, params T[] list)
{
return list.Any(l => e.Equals(l));
}

Example:

var array = new [] {1,2,3,4};
var index = 1;
if (index.In(array))
// do some action

ToEnum
Syntax:
public static T ToEnum(this string value)
{
return (T)Enum.Parse(typeof(T), value);
}

Example:
public enum SessionKey
{
IsLoggedIn, ReportId
}
//---------------
var myString = "ReportId";
switch (myString.ToEnum())
{
case SessionKey.ReportId:
// do some action
case SessionKey.IsloggedIn:
// do some action
}

More to learn:

Tuesday 25 August 2009

SQL Server - How to Run Scripts in a Transactional Way?

SQL Server 2000:

Approach1: Use @@ERROR
You have to repeat checking @@ERROR after each script:
BEGIN T1


INSERT INTO [ReportSystem] ([ReportSystemId], [ReportSystemName], [BaseReportUrl]) VALUES(2, 'QlikView', NULL);


IF (@@ERROR <> 0) GOTO DoRollBack


DELETE FROM ReportSystem


IF (@@ERROR <> 0) GOTO DoRollBack


DELETE FROM FilterParameterType


IF (@@ERROR <> 0) GOTO DoRollBack

COMMIT T1

RETURN

DoRollBack:
ROLLBACK TRAN T1
PRINT 'Rolled back'

Approach2: Use sp_executesql

BEGIN T1

declare @rc int;

declare @sql nvarchar(500);

set @sql = N'DELETE FROM FilterParameterType; DELETE FROM ReportSystem;';

exec @rc = sp_executesql @sql;

if @rc <> 0 ROLLBACK T1

COMMIT T1

SQL Server 2005:

Approach1: Use TRY...CATCH

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

Monday 24 August 2009

SQL Server - Schema Information

SQL Server 2000:

-- What columns does this table have?
SELECT SC.NAME AS ColumnName
FROM SYSOBJECTS SO
INNER JOIN SYSCOLUMNS SC ON SO.ID = SC.ID
WHERE SO.XTYPE = 'U' AND SO.NAME = 'ReportRole'
ORDER BY SO.NAME, SC.NAME

-- What user tables exist in this database?
SELECT SO.NAME AS TableName
FROM SYSOBJECTS SO
WHERE SO.XTYPE = 'U'
ORDER BY SO.NAME


-- Does this table have any identity column?
IF (OBJECTPROPERTY(OBJECT_ID('tableName'), 'TableHasIdentity') = 1)
PRINT 'Table has an identity column'
ELSE PRINT 'Table does not have an identity column'

SQL Server 2005:

Saturday 22 August 2009

Different Ways of INSERTING Data INTO a Table

Approach1: Using INSERT VALUES

INSERT INTO Table1 (FirstCol, SecondCol)
VALUES ('First',1);
INSERT INTO Table1 (FirstCol, SecondCol)
VALUES ('Second',2);

Approach2: Using INSERT SELECT

INSERT INTO Table1 (FirstCol, SecondCol)
SELECT 'First',1;
INSERT INTO Table1 (FirstCol, SecondCol)
SELECT 'Second',2;

Approach3: Using INSERT UNION ALL

INSERT INTO Table1 (FirstCol, SecondCol)
SELECT 'First' ,1
UNION ALL
SELECT 'Second' ,2

Approach4: Using INSERT SELECT FROM

INSERT INTO Table1 (FirstCol, SecondCol)
SELECT FirstName, number FROM Table2


Approach 5: Using SELECT INTO – Temp table

The following statement creates an in-memory table named “TempTable” and inserts the specified data into that:

SELECT FirstName, LastName
INTO TempTable
FROM Person.Contact

Approach 6: Using SELECT INTO – Permanent table

The following statement inserts the data from an existing table named “Table2” into another existing table named “Table1”:

SELECT FirstName, LastName
INTO db1Name.dbo.Table1
FROM dbo2Name.dbo.Table2

Tip: this approach is helpful when you want to send data from a table in a server into another table in another server

Tuesday 18 August 2009

Understanding XAMLPad and XAMLPadX



XamlPad (xamlpad.exe) is a basic visual editor for Extensible Application Markup Language (XAML).

Location: C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\XamlPad.exe (you need to install Windows SDK obviously)

Features:
  • Real-time editing and display of XAML content.
  • Auto parse, syntax validation and redisplay of content.
  • Basic text editing commands, including copy, paste, undo and find.
  • XAML errors are reported in the status bar.
  • XAML contents is shown in a visual tree
  • Use XamlPad.exe to load your XAML file
XamlPadX:


My thoughts:
This is a very basic tool and doesn't have intellisense, so if you have access to Visual Studio, don't bother using this tool!

Monday 17 August 2009

Understanding Microsoft Expression Studio 3.0 Quickly

Microsoft Expression Studio provides a set of professional design tools for .NET web, desktop, WPF or Silverlight applications.

This package contains Expression Web, Expression Blend, Expression Design and Expression Encoder and SketchFlow tools.

For instance, your professional designer can design a rich UI using Expression tools and produce a XAML result. Then your professional WPF developer gets the XAML and develops code and logic for it.

Expression Web:

To build websites; similar to DreamWeaver and FrontPage but with more features and supports AJAX, C#, etc.

Expression Blend:

Using which you can create rich UI (e.g. 3D) for .NET, WPF and Silverlight.

Expression Design:

Using which you can build designs and vector assets (similiar to Photoshop but with different features)

Expression Encoder:

For instance you can publish videos from your webcam to Silverlight. You can also customize your videos; adding titles, etc.

SketchFlow:

It is a great tool for prototyping.

For a full list of features, see this.

Sunday 16 August 2009

Windows SDK .NET 3.0 Samples

The Windows SDK samples for .NET Framework 3.0 include samples for .NET Framework 2.0, Windows Communication Foundation, Windows Presentation Foundation, Windows Workflow Foundation, and Cross Technology samples. These samples can be downloaded from here or are available when the Windows SDK is installed locally.

Friday 7 August 2009

Unit Testing - How to unit test a method that uses ConfigurationManager?

Problem:

By default, you can't unit test any method that uses ConfigurationManager class like following:

public static string GetFromWebConfig(WebConfigKey key)
{
var str = ConfigurationManager.AppSettings[key.ToString()];
if (str == null)
{
throw new ApplicationException("Key: " + key.ToString() + " does not exist in the web.config");
}
return str;
}
Note: WebConfigKey is an "enum"

My Solution: Enable Dependency Injection

1. Create an Interface

Create an interface that provides you the properties which are needed by ConfigurationManager

public interface IConfigurationManager
{
NameValueCollection AppSettings {get;}
}
2. Create a Wrapper

Create a ConfigurationManagerWrapper class which is to be used for production code:

public class ConfigurationManagerWrapper : IConfigurationManager
{
#region Fields and Properties

static ConfigurationManagerWrapper instanceHolder = new ConfigurationManagerWrapper();

public static ConfigurationManagerWrapper Instance
{
get { return instanceHolder; }
}

public NameValueCollection AppSettings
{
get
{
return ConfigurationManager.AppSettings;
}
}

#endregion

#region Constructors

private ConfigurationManagerWrapper()
{
}
#endregion
}
Note: the above class uses a thread-safe singleton pattern

3. Overload your original method
public static string GetFromWebConfig(WebConfigKey key)
{
return GetFromWebConfig(key, ConfigurationManagerWrapper.Instance);
}

public static string GetFromWebConfig(WebConfigKey key, IConfigurationManager configurationManager)
{
var str = configurationManager.AppSettings[key.ToString()];
if (str == null)
{
throw new ApplicationException("Key: " + key.ToString() + " does not exist in the web.config");
}
return str;
}
Note: the first method is to be used directly by the production code and passes a singleton instance of ConfigurationManagerWrapper. The second code will be used directly by the testing framework to benefit from dependency injection.

4. Write the test

[TestMethod()]
public void GetFromWebConfigTest()
{
// setup
var key = WebConfigKey.SecondsToCache;
var expected = "60";
mocks = new Mockery();
var configurationManager = mocks.NewMock();
Expect.Once.On(configurationManager).GetProperty("AppSettings")
.Will(Return.Value(new NameValueCollection {{key.ToString(), expected}}));

// exercise
var actual = Utils.GetFromWebConfig(key, configurationManager);

// verify
Assert.AreEqual(expected, actual);
mocks.VerifyAllExpectationsHaveBeenMet();
}
Note: NMock has been used.

Challenging Myself:
How is it possible to keep the original method and just create the wrapper and the interface at the time the test runs only so that we don't need to make any changes to the production code? I guess using Reflection, etc.

Thursday 6 August 2009

ASP.NET Dynamic Data - Generate the Metadata Classes from Entity Framework Quickly

Problem:
It's time-consuming to write the metadata classes for your entity framework assuming you have many classes.

Solution:
Run my following class using
EFMetadataGenerator.Generate( "MIPortalModel" ,@"c:\MIPortalEntities.cs");

Then all the metadata classes including their properties will be generated for you.
using System;
using System.Linq;
using System.Reflection;
using System.Text;

/// <summary>
/// Summary description for EFMetadataGenerator
/// </summary>
public class EFMetadataGenerator
{
/// <summary>
/// </summary>
/// <param name="fromNamespace">This is the namespace of your EntityFramework</param>
/// <param nam/// </summary>e="toFile">This is the path of the file on which you want the results to be saved</param>
public static void Generate(string fromNamespace, string toFile)
{
var result = new StringBuilder();
result.Append(AddHeader(fromNamespace));
var modules = Assembly.GetExecutingAssembly().GetModules();
foreach (var module in modules)
{
var types = module.GetTypes().Where(t => t.Namespace == fromNamespace);
foreach (var type in types) {
result.Append(GenerateMetadataClasses(type));
}
}
result.Append(AddFooter());
System.IO.File.WriteAllText(toFile, result.ToString());
}

private static string AddHeader(string namespaceName)
{
var sb = new StringBuilder();
sb.Append("using System;" + GetNewLine(1));
sb.Append("using System.ComponentModel;" + GetNewLine(1));
sb.Append("using System.Data;" + GetNewLine(1));
sb.Append("using System.Data.Objects;" + GetNewLine(1));
sb.Append("using System.ComponentModel.DataAnnotations;" + GetNewLine(1));
sb.Append(GetNewLine(1) + "namespace " + namespaceName + GetNewLine(1)); sb.Append("{" + GetNewLine(1));
return sb.ToString();
}

private static string AddFooter() { return "}"; }

private static string GenerateMetadataClasses(Type type)
{
var className = type.Name;
var metadataClassName = type.Name + "_MD";
var sb = new StringBuilder();
sb.Append(GetTab(1) + "#region " + className + GetNewLine(2));

// generate the partial class
sb.Append(GetTab(1) + "[MetadataType(typeof(" + metadataClassName + "))]" + GetNewLine(1));
sb.Append(GetTab(1) + "public partial class " + className + GetNewLine(1));
sb.Append(GetTab(1) + "{" + GetNewLine(1) + GetTab(1) + "}" + GetNewLine(2));
// generate the metadata class
sb.Append(GetTab(1) + "public class " + metadataClassName + GetNewLine(1));
sb.Append(GetTab(1) + "{" + GetNewLine(1));
var properties = type.GetProperties();
foreach (var propertyInfo in properties)
{
sb.Append(GetTab(2) + "public object " + propertyInfo.Name + " { get; set; }" + GetNewLine(1));
}
sb.Append(GetTab(1) + "}" + GetNewLine(2));
sb.Append(GetTab(1) + "#endregion " + className + GetNewLine(2));
return sb.ToString();
}

private static string GetNewLine(int count)
{
var sb = new StringBuilder();
for (var i = 0; i < count; i++) sb.Append("\r\n");
return sb.ToString();
}

private static string GetTab(int count)
{
var sb = new StringBuilder();
for(var i = 0; i< count; i ++) sb.Append("\t");
return sb.ToString();
}
}

Wednesday 5 August 2009

ASP.NET Dynamic Data - How to add a ReadOnly attribute to a Property

Problem:
I have the following property on my entity framework designer that I want to make it ReadOnly:

[global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
[global::System.Runtime.Serialization.DataMemberAttribute()]
public int FilterParameterId
{
get
{
return this._FilterParameterId;
}
set
{
// etc
}
}
Solution:
1.
Make two copies of the Text.ascx field template and name one ReadOnlyText.ascx (is used on edit page and list) and the other ReadOnlyText_Edit.ascx (is used on Insert page) then annotate the field as follows

2.
[MetadataType(typeof(FilterParameter_MD))]
public partial class FilterParameter
{
}
3.
public class FilterParameter_MD
{
[UIHint("ReadOnlyText")]
public object FilterParameterId { get; set; }
}

Sunday 2 August 2009

Unit Testing - HttpSimulator

Have you ever wondered how to simulate HttpContext so that you can write your unit tests? TypeMock can do that but it's not a free tool.

HttpSimulator is a component composed of 2 classes; I am not sure whether Phil Haak has written it himself but it solves that problem nicely. You can download it from the bottom of this post.

Code sample:

Test:
public static HttpSimulator CreateHttpSimulator()
{
return new HttpSimulator("/", @"c:\inetpub\").SimulateRequest();
}

[TestMethod()]
public void SetSessionTest()
{
using (Helper.CreateHttpSimulator())
{
// setup
var expectedValue = 2;
// exercise
Utils.SetSession(SessionKey.Basket, expectedValue);
// verify
var actualValue = Utils.GetFromSession(SessionKey.Basket);
Assert.AreEqual(expectedValue, actualValue);
}
}
System Under Test:

public static void SetSession(SessionKey key, object value)
{
HttpContext.Current.Session[key.ToString()] = value;
}

public static object GetFromSession(SessionKey key)
{
if (HttpContext.Current == null HttpContext.Current.Session == null)
throw new ApplicationException("HttpContext.Current.Session is null");

if (HttpContext.Current.Session[key.ToString()] == null)
return null;

return HttpContext.Current.Session[key.ToString()];
}

Saturday 1 August 2009

Collaborative Application Markup Language (CAML)

Collaborative Application Markup Language, or CAML for short, is an XML-based language that SharePoint uses for queries, configuration, and rendering of data in addition to other uses. CAML has some similiarities to SQL in function.

CAML has several subsets, called schemas, that are used for different tasks. For example the View schema is used for defining visual rendering of data while the Query schema is used for extracting data.

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

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