An Initial Look at .NET Dynamic Data
Introduction

.NET Dynamic data (.NET 3.5 SP1) is a framework that provides dynamic web page templates to support CRUD operations on classes in a Linq to SQL or Linq to Entities model. Allowing you to rapidly develop a data driven web application.

My concern with Dynamic Data was that it would not easily support custom functionality. However I found that Dynamic Data was adequately extensible enabling you to change existing templates, define custom pages and custom field controls (field templates) to achieve the required functionality.

Another neat part of Dynamic Data is that it applies field level validation automatically based on metadata that you define using custom attributes against the model classes.

Meta data is also used to change the way dynamic data processes a table or field, for example it can be used to configure the display name of a table or configure the field template used for a data field.

Creating a Dynamic Data Project

It’s very easy to get started with Dynamic Data, depending on your model type; simply add a new Dynamic Data Web Application or Dynamic Data Entities Web Application project in Visual Studio 2008:

Add a reference to the assembly containing your Linq to SQL/Entities model and register the type of the model in the global.asax file. Setting ‘ScaffoldAllTables’ to true causes the template pages to be configured to all entities in the model :

model.RegisterContext(typeof(MyEntities), new ContextConfiguration() { ScaffoldAllTables = true });

Compile and run the website and see just how much you get for free.

A Quick Look at Extensibility

One thing you will notice very quickly about dynamic data is that it’s not ‘magic’ and that the way things hang together is fairly transparent.

Have a look at the standard PageTemplates under the new project and you will see that apart from the DynamicDataManager they use standard .NET controls and also notice that you have complete control over the page template itself. You can see how each page really is just a template which can support CRUD operations across all the types in the model.

The code behind; in say the Edit page; is very simple, first the details view on the page is registered with Dynamic Data and on page load the MetaTable instance is used to configure the data source. The MetaTable contains the definition of the underlying table being edited which you can utilise to implement custom functionality. You can tweak the existing page templates or add your own pages for specific types by creating a new page with the relevant table name under the CustomPages folder.

The existing FieldTemplates are a good reference to create your own templates.  Field templates derive FieldTemplateUserControl and this base class contains the metadata on the underlying field and its parent data model and also the state of the current row being edited.  To change the field template used by a field all that is required is to decorate the field in the model metadata.

Conclusion

Though in my opinion Dynamic Data is probably best suited to developing prototypes or small data driven applications with limited business processing, I was impressed with the ease at which a Dynamic Data site can be extended with custom functionality.

Also, the nature of Dynamic Data means that theres no reason why you couldn't use it for parts of your application, utilising it for system administration screens for example.

One caveat to bear in mind is that its use of Entity/SQL data sources does mean that you are very tightly coupled to your data context.

I hope to expand on this with some more specific posts on Dynamic Data soon.

A good starting point: http://www.asp.net/dynamicdata/
MSBUILD Property Assertions Using the Error Task
 I defined an ItemGroup for all files and folders under a directory passed as the ‘TargetDir’ property:

<ExistingFiles Include="$(TargetDir)\**\*.*" />

If the ‘TargetDir’ property has an empty value the item collection contains all files and folders of the root directory.

Although the behavior makes sense, it highlights the importance of checking certain properties have been set. This would have been very nasty if the item collection was used in conjunction with the Delete task for example!

The Error task can be used to stop the build based on a certain condition and can be used to check that a property has been set:

<Error Condition="'$(TargetDir)'==''" Text="Target dir property not set, ensure properties file could be located"/>

The complete task reference can be found here http://msdn.microsoft.com/en-us/library/7z253716.aspx.
Add Comment Filed Under [ MSBUILD ]
MSBUILD Automated Deployments of Databases using the MS SDC Task Library

Intro

Following on from my previous post on automated deployment of websites, another common task is database deployment. The freely available Microsoft SDC Task Library contains a library of custom MSBUILD tasks to facilitate this process.

This post describes a generic script I wrote which uses these tasks to create/update a SQL Server database as part of an automated deployment. A subsequent post will look at how Microsoft SDC can be used to apply permissions to the database.

Into Practice

Download the latest version of the SDC task library from http://codeplex.com/sdctasks, and add it to your solution so it’s available to the build process.

Add the following ‘using’ to your build script to import the Micrsoft.Sdc.Tasks.Sql.Execute task. This task is used to run SQL commands and scripts:

<UsingTask AssemblyFile="Microsoft.Sdc.Tasks.dll" TaskName="Microsoft.Sdc.Tasks.Sql.Execute"/>

The Execute command accepts the following main arguments:

  • ServerName: SQL Server instance name to connect to
  • DatabaseName: Database to run SQL scripts/commands against
  • Sql: Optional SQL command to run against the database
  • Path: Optional path to a SQL script to run against the database

For more information on this and the other tasks in the SDC toolkit, refer to the Microsoft.Sdc.Tasks reference compiled help file which comes packaged with the assemblies.

The script allows a database to be created or updated based on a passed ‘DeploymentType’ property, the first task uses a Condition to evaluate if a ‘Create’ deployment is being performed and if true runs a SQL command to create the database. The SQL command is executed substituting the passed ‘DatabaseName’ property:

<Execute ServerName="$(ServerName)" DatabaseName="master" Sql="CREATE DATABASE $(DatabaseName)" CommandTimeout="$(Timeout)" Condition="'$(DeploymentType)'=='Create'"/>

You could use the same method to drop any existing instances of the database on the server.

As well as executing SQL statements the execute command supports running a SQL Script from the file system by specifying the Path argument. I used this in conjunction with MSBUILD batching to run the create/update scripts from a particular folder against the database:

<Execute ServerName="$(ServerName)" DatabaseName="$(DatabaseName)" Path="%(Scripts.Identity)" CommandTimeout="$(Timeout)" Condition="'$(DeploymentType)'=='Create'"/>

Notice the use of the %(Scripts.Identity) notation which causes MSBUILD to run the Execute task for each of files in the Scripts item group. The Scripts item group includes all the *.SQL scripts under the given ‘ScriptBase’ folder and its sub folders and is defined as follows:

<ItemGroup>

  <Scripts Include="$(ScriptBase)\**\*.sql"/>

</ItemGroup>

Folders are supported in order to provide a simple mechanism to define the order that the scripts should be run against the database:

More information on MSBUILD batching can be found at http://msdn.microsoft.com/en-us/library/ms171473(VS.80).aspx, and batching on metadata and conditions at http://msdn.microsoft.com/en-us/library/ms171474(VS.80).aspx.

The same method is used to execute the update scripts:

<Execute ServerName="$(ServerName)" DatabaseName="$(DatabaseName)" Path="%(UpdateScripts.Identity)" CommandTimeout="$(Timeout)" Condition="'$(DeploymentType)'=='Update'"/>

Here is the complete script.

Add Comment Filed Under [ MSBUILD ]
MS Error Code Lookup Tool
The Microsoft Exchange Server Error Code Look-up tool allows you to lookup an error message from the error codes returned by MS Windows libraries.
MSBUILD Automated Deployments of Web Applications using the MS SDC Task Library

Intro

A common scenario of a team build solution is deploying the application on a nightly basis to provide the test team with an up-to-date deployment to test against. Such early visibility will help maintain the quality of the product over the development lifecycle.

The types of projects we work on commonly have a web application component, be it a front end or in the form of WebServices. Using the Microsoft SDC Task Library extensions for MSBUILD, web applications can be automatically deployed and configured under IIS 6.0/7.0 relatively easily.

Into Practice

The SDC Task Library is freely available at http://codeplex.com/sdctasks, the library isn’t limited to deploying websites, tasks include the functionality to execute SQL scripts, run installers, edit xml files and much more.

Download the library and add the Microsoft.Sdc.Tasks.dll assembly somewhere under your solution in source control so it is available during the build process.

To reference a task in the library from you MSBUILD script add a UsingTask. Set the AssemblyFile to the location of the assembly relative to the script and set the TaskName to the name of the Sdc task you want to use including the namespace.

<UsingTask AssemblyFile="Microsoft.Sdc.Tasks.dll" TaskName="Microsoft.Sdc.Tasks.Web.WebSite.Create"/>

Call the Task from within a Target in the usual way, so for example to create a new Website on a server somewhere:

<Create

    MachineName="$(MachineName)"

    Description="$(WebsiteName)"

    Path="$(Path)"

    Port="$(Port)"/>

Each of the Tasks are well documented in the compiled help file, which is included in the download.

Troubleshooting

  • The user that your Team Build Service runs as on the build machine must be an administrator on the machine that is hosting the web application
  • If you are deploying to IIS 7.0 you need to have the IIS 6.0 Management Compatibility services installed
  • IIS including the compatibility services must be installed on BOTH the build server and the remote machine hosting the website.

    This is because; under the covers the Task queries IIS on the remote machine over AD and IIS providers are needed on the remote and the client machine.

    If this isn’t setup correctly you will get a ComException from DirectoryServices with an HRESULT of 0x80005000
Add Comment Filed Under [ MSBUILD ]
Node Sets in XSLT Variables MSXML 4.0

In MSXML 4.0 if you create a variable and assign it some xml...

<xsl:variable name="var">
   <
xsl:copy-of select="/a/b"/>
</
xsl:variable>

... you are not able to directly perform xpath on this variable as its value is stored as a tree fragment rather than a node set. Instead you will need to use the node-set xslt function.

This function is an extension so the following namespace must be added:

xmlns:msxsl="urn:schemas-microsoft-com:xslt"

Then for all xpaths on the variable you can use the function to get the node set:

<xsl:value-of select="msxsl:node-set($var)/c"/>

 

Add Comment Filed Under [ XSLT ]
Cryptic error "Queue 'Message Properties...' is not enabled." when firing an event for a State Machine Workflow

I was getting this rather cryptic exception thrown from the WorkflowQueuingService when firing an event for a State Machine Workflow:

Queue 'Message Properties...' is not enabled.

After some investigation it turns out that what this actually means is that the workflow is not in a valid state to handle the event. In other words; the workflow is not waiting on a StateActivity with an EventDrivenActivity that has a HandleExternalActivity bound to the event being fired.

You can also see this error being raised if your workflow has transitioned to the correct state but the workflow itself is not ready to receive the event (for example if it is still initialising). To resolve this you can set the ExternalDataEventArgs.WaitForIdle property of your event args to true which will cause the runtime to queue the event until the workflow has idled and is therefore ready to receive it.