Homepage | About Me | Testing ASP.net Book | Best Blog Posts | Personal Projects | Follow me on Twitter | GitHub | SlideShare | RSS
Blog.BenHall.me.uk

Partial Methods in Linq

Sunday, July 29, 2007

Following on from my previous post, I noticed Linq takes advantage of the Partial Methods feature in the language so I thought I would take a closer look.

Within VS Beta 2, the DataContext and database objects contain a number of partial methods to allow you to hook into various methods which are called at certain points within the execution.  All of the definitions are in the datacontext.designer.cs file in a region called Extensibility Method Definitions.

The standard methods included within the data context are:

  • partial void OnCreated();
  • partial void InsertCustomer(Customer instance);
  • partial void UpdateCustomer(Customer instance);
  • partial void DeleteCustomer(Customer instance);

OnCreated() is called when the DataContext object is created, while the others are called on SubmitChanges().  Once SubmitChanges() are called, the DataContext will start processing any changes and calling the methods, if they have been implemented.  HOWEVER I found that if you extend one of the methods, then the action would never be passed to the database. This must be a bug, so something to be aware of.  It might be by design and you use this to override the logic - its not very clear.  If they do override the functionality and its not a bug, I don't like the fact that there is no distinction between a method which is a hook and a method which overrides functionality. If it was something like partial override void .... then it would be a lot better that how it is at the moment.

The database entities also have extension points.

  • partial void OnLoaded();
  • partial void OnValidate();
  • partial void OnCreated();
  • partial void OnOrderIDChanging(int value);
  • partial void OnOrderIDChanged();

These partial methods are a little bit more interesting.  OnCreated is called when an object is initialised.  When loading from a database, OnCreated is called first, then OnLoaded is called.  OnXChanging() is called when the property is changed, just before the value is stored in the internal variable, not when SubmitChanges is called. OnXChanged() is called after the value is stored.

The most important method is OnValidate() which is called just before the action is passed to the database.  Here, you can add custom/business logic to verify that the object (can access everything as you are inside the object, for example this.OrderID) is correct and valid before being saved.  If there is a problem, you can throw an exception and catch it by putting a try/catch around db.SubmitChanges(). Very useful feature.

 

All of the code I wrote can be found here : C# Sample Code

Technorati Tags: , ,

Labels: , ,

Partial Methods in C# 3.0 and VB.net 9.0

Partial methods are a new language feature in both VB.net and C# and are designed to enable lightweight event handling and hooks into the class.  The code samples are in C#, but I have provided a link at the bottom for the VB.net version - the principals are the same.

Few important points:

  • Partial methods can only be defined or implemented within a partial class.
  • They must return void however can accept arguments (ref parameters but not out parameters).
  • Must be private

Consider the following C# code which has a simple getter and setter for the name of a person.

partial class Person
{
        string name;

        public string Name
        {
            get { return name; }

            set
            {
                OnNameChanging(value);
                name = value;
                OnNameChanged();
            }
        }

        partial void OnNameChanging(string name);

        partial void OnNameChanged();

}

When a name is set, a call is made to the OnNameChanging method, passing in the value as a parameter. After the name has changed the OnNameChanged method is called.  But these methods are just placeholders/interfaces which could be implemented by a developer.

In a separate partial class we can then implement this functionality which will handle what we want to happen when the methods are called.

partial class Person
{
        partial void OnNameChanged()
        {
            Console.WriteLine("OnNameChanged()");
        }

        partial void OnNameChanging(string name)
        {
            Console.WriteLine("OnNameChanging(string name)");
            Console.WriteLine(name);
        }
}

Now, when we compile, everything will be merged and act as a single class. If we then set the name on the object, the following is wrote out to the console

OnNameChanging(string name)
Ben Hall
OnNameChanged()

But what what happens if no partial class implements the method body for a partial method? Well, the compiler removes calling reference from the code and does not get compiled. If the two methods where not implemented, the setter would look like this:

set
{
  name = value;
}

The result is that it is really effective to include calls to partial methods within generated code, like from a Linq DataContext, because if they are not taken advantage of then they are removed.

Looking forward to seeing how these will be used.

Links

C# Sample | VB.net Sample

http://blogs.msdn.com/wesdyer/archive/2007/05/23/in-case-you-haven-t-heard.aspx
http://blogs.msdn.com/vbteam/archive/2007/03/27/partial-methods.aspx

Technorati Tags: , ,

Labels: , ,

LinqDataSource - Visual Studio 2008 Beta 2

Saturday, July 28, 2007

One of the new features within Visual Studio 2008 is the linqDataSource for ASP.net applications.

This data source allows you to attach directly to a DataContext allowing you to access Linq objects without writing any code.  Because it follows the DataSource interface, existing controls such as the GridView can connect and display data based on it.

The DataSource also handles mappings form GridView requests to the database. For example, Sorting is done server side, querying the database with ORDER BY, while paging using RowNumber feature of SQL Server 2005. 

One note, the Insert, Update and Delete only appears to work if you go via the DataContext and SELECT * on the object. Not sure if this is by design or a bug, i've posted a note on the forum asking.

Using the data source is very simple.  In fact, if you have used one of the existing data sources then its just the same but instead of pointing to a database, you point to the DataContext.  If you haven't, in the Toolbox flyout, under Data you will see the LinqDataSource control.  Drag this onto your form, click the smart tag and you will be able to config the options.  If your DataContext isn't in the list, you need to compile the application for it to be detectable. You can then drag on a GridView control and point it's data source to the Data Source you just created.

Sample code which turns 4 columns from the Northwind.Customer table:

<asp:GridView ID="GridView1" runat="server" AllowPaging="True"
    AllowSorting="True" AutoGenerateColumns="False" DataSourceID="LinqDataSource1">
    <Columns>
        <asp:boundfield DataField="CustomerID" HeaderText="CustomerID" ReadOnly="True"
            SortExpression="CustomerID"></asp:boundfield>
        <asp:boundfield DataField="CompanyName" HeaderText="CompanyName"
            ReadOnly="True" SortExpression="CompanyName"></asp:boundfield>
        <asp:boundfield DataField="Phone" HeaderText="Phone" ReadOnly="True"
            SortExpression="Phone"></asp:boundfield>
        <asp:boundfield DataField="PostalCode" HeaderText="PostalCode" ReadOnly="True"
            SortExpression="PostalCode"></asp:boundfield>
    </Columns>
</asp:GridView>

<asp:LinqDataSource ID="LinqDataSource1" runat="server"
    ContextTypeName="WebPOC.NorthwindDataContext"
    Select="new (CustomerID, CompanyName, Phone, PostalCode)" TableName="Customers">
</asp:LinqDataSource>

Simple and effective control, nice addition to the framework.

 

Technorati Tags: , , ,

Katmai and Orcas Beta 2 - Problems, Problems, Problems

Just tried to install Katmai (SQL Server 2008) on to my dev machine with Visual Studio 2008 on there. After installing, the Management Studio was not on the start menu - strange. As a quick look on the MSDN forum I found a pointer to this in the readme

4.5.1 Remove SQL Server 2005 Workstation Components before Installing SQL Server "Katmai"

Workstation components is an option under the SQL Server 2005 item in Add/Remove.

image 

As uninstalling this, and repairing the SQL Native Client installation, still nothing.  I then re-ran the main install, and selected just the workstation components option.  This went ahead and installed a little bit more but then Windows reported that SSMS crashed, in the setup log saying:

MSI (s) (9C:8C) [16:37:06:048]: Product: Microsoft SQL Server "Katmai" Tools -- Installation failed.

MSI (s) (9C:8C) [16:37:06:057]: Windows Installer installed the product. Product Name: Microsoft SQL Server "Katmai" Tools. Product Version: 10.0.1019.17. Product Language: 1033. Installation success or error status: 1603.

Things just went from bad to worse from then.  I used system restore to roll back my system and start again.  This time, I uninstalled SQL Server 2005 components first, install worked fine this time and didn't fail.  However, when I tried to login to the server from Management Studio I was getting more errors:

A connection was successfully established with the server, but then an error occurred during the login process. (provider: Shared Memory Provider, error: 0 - No process is on the other end of the pipe.) (Microsoft SQL Server, Error: 233)

Within event viewer it said

The Tabular Data Stream (TDS) version 0x73090003 of the client library used to open the connection is unsupported or unknown. The connection has been closed.  [CLIENT: 127.0.0.1]

Same errors when I tried to login from another VM machine with Katmai on and also Visual Studio.  However with Visual Studio, I could connect using the SA login and OLEDB and also sqlcmd, even though I couldn't from Management Studio.  The SqlClient provider is not correctly able to connect to Katmai, even when the server is working.

I tried to connect to Katmai working on another server and this also failed.

After a few hours of playing around I have given up! Not sure if I am going to attempt to uninstall Katmai or just flatten the machine.

Not sure why this is causing problems as Katmai and Visual Web Dev June CTP worked fine side-by-side. I think installing Katmai after Orcas was the killer.

Technorati Tags: ,

Labels: ,

Visual Studio Orcas Beta 2 Online and Available

Thursday, July 26, 2007

The latest version of Orcas has just been posted online. Both the Installation disc images and VPC images can now be downloaded.

Disc available are:

Standard, Pro, Team Suite, Team Foundation Server, Test Load, MSDN Library.

VPC available are: Team Suite, Team Suite and Team Foundation.

http://msdn2.microsoft.com/en-us/vstudio/aa700831.aspx

It's great Microsoft have listened to feedback and offering these as a single ISO, but also offering them via a ActiveX download manager to make life easier for everyone.  However on Vista, it would only let me save it on my C drive and then told me for security it was being saved in a temp folder. Great!

Visual Studio Express Editions, VB, C#, C++, Web Developer.  Both Online and Offline (414mb img) installers are available.

http://msdn2.microsoft.com/en-us/express/future/bb421473.aspx

I'm currently downloading C# Express (20 mins left) and Team Suite Installation (6hours 20mins left).   Wish I was back at Uni, would have been done by now....

Technorati tags: , ,

MIX UK - Registration Open

Wednesday, July 25, 2007

Registration for Mix UK has opened with an early bird discount price of £199 (BARGIN!)

http://www.microsoft.com/uk/mix07/ 

Be quick, I don't think there are a large number of places available.

Technorati tags: , ,

Notepad2 Integration

I've been using Notepad2 for a few weeks now and find it to be a great addition to my toolset, however I don't like the way it doesn't integrate into Windows and is just a standalone exe. With version 2.0.17 just released, I decided I would create a reg file which would setup the integration.  There are posts online which explain how to replace notepad.exe with notepad2.exe but I didn't really want to do that incase I change my mind next week (more than likely).

Registry file to install Notepad2.  This will add a Edit with Notepad2 onto context menus of files, and change the default for txt files to open with Notepad2.  To have Notepad2 be the default for other file types, the registry key for the file needs to point to the value Notepad2. For example:

[HKEY_CLASSES_ROOT\.txt]
@="Notepad2"

Registry file to remove Notepad2. This will remove the context menu items, and set the file association to .txt back to the default. The only other step then is to create a start menu item shortcut, if you want - personally, I never use it.

[Sorry about the .txt extension, host doesn't allow .reg files to be downloaded.  Remove extension to use]

Enjoy.

Technorati tags:

Bloglines

Tuesday, July 24, 2007

BloglinesFor a long time now, I have been a solid user of RSS Bandit and it has served me well.  However, with me working more and more on different machines and no RSS reader on my mobile I came across Bloglines and it has definitely changed my RSS reading experience.

First let me explain why I am moving away from RSSBandit.  I am subscribed to about 250 feeds, and when RSS loads up and checks all my feeds, my certainly PC feels the hit. After it has been left open for a while it consumes as much memory as Visual Studio and if I happen to be running a VM and RSSBandit decides to check for new items, my machine becomes unusable.  I could keep opening and closing when I wasn't using it, but it was painful to load up so I didn't keep wanting to do it.  The second reason why I moved away, was because all my feeds where in one place. I could have installed the application and shared my feeds across my machines, but then I had would have to mark things as read on multiple machines which would have got annoying based on how I used to manage email.  My final reason was the lack of RSS support on my mobile,  I didn't want my phone to handle all of my feeds and I didn't want to be alerted all of the time so a offline application would have not worked for me.  Bloglines solves all of these problems for me.

Transferring from RssBandit to Bloglines was a nice experience.  Both support the OPML format so I could quickly export from RSSBandit and import into Bloglines.  Straight away bloglines displayed me the feed items it already knew about and started processing some of the blogs it wasn't aware of.  Very simple to switch between the two, and if I didn't like bloglines I could switch to another reader without a problem.

After a short while, Bloglines displayed all the news items for all of my feeds.  Bloglines does all the work server side, they keep a cache of all the RSS feeds so some popular ones (which as Scott Hanselman's) will already be in the database so they won't have to go out and hit the feed just for you. Makes it a lot quicker as you don't have to wait 5 minutes for the feeds to be updated and processed, instead they are ready and waiting for you - even if you haven't been on in a while.

The reading experience is surprisingly good. Bloglines have various shortcut keys to help you navigate around. j and k jump forwards and backwards over each unread item in the feed, m collapses the left pane, then n allows you to toggle the keep new status.  This will mark is not as unread, but as something which you should follow up on.  The item is then displayed and the bottom of all your unread items until you remove the flag.  To see past items, you select the range based on a dropdown which keeps the UI clean.  Switching between feeds is also very fast - so lag, no loading screens.

As for reading on my mobile, that's also great. All of your feeds are displayed in a list, then you go into the feed to display all the items. Clean, quick, lightweight, with all the same features as the main site.

image To make life easier, I have added BlogLines and Sub with Bloglines buttons to my links menu in IE7. Now at a click of a button I can access everything straight away. Its Great!

One thing I wish it would do is a directly Post to Del.icio.us, only feeds with it at the bottom of the item have it at the moment, but having it on all of the items would be great.

Technorati tags: , , ,

Labels:

The results are in...

Monday, July 23, 2007

I have just received confirmation of my degree result - I was awarded a First Class Honours!

My grades for each module are:
Computer Science Project - A1
Computer Network Protocols and Architectures  - A1
Further OO Development - A1
Databases - A3
(Grade Mark A1 = 77-100 and A3 = 70-72)

Thank you to everyone who has helped over the past year. It's been a busy year for me, with me being a MSP, entering the Imagine Cup and work on MbUnit all going on at the same time - plus job hunting and keeping up to date with what Microsoft are doing made for a busy year.  But it has all paid off :)

SQLBits - UK SQL Server Community Day

Saturday, July 21, 2007

Hot on the deals of DDD5, information about a new community conference, SQLBits, has been announced. 

"On the 6th October 2007 we will be holding a day long conference full of SQL content. We will have 20 sessions covering everything from Maintenance plans through CLR stored procedures to Data Mining."

If you use, or have an interest in SQL Server then this should be an great day.  I'm really looking forward to it, should be another great event.

Registration opens sometime in August, keep an eye on the RSS for updates.

More information @ http://www.sqlbits.com/

Technorati tags:

DDD5 Podcast

Craig Murphy did a series of podcasts from DDD5 and caught me and Chris Gaskall in the bar after the dinner, and one or two++ beers....

Listen @ 008 - Community Podcast - Post-GeekDinner - Ben Hall - Chris Gaskall

Oh, Craig - don't worry about it, it only left a small bruise :) [When you knocked me off my stool]

Technorati tags: ,

Metallica @ Wembley

Monday, July 09, 2007

Last night (08/07/2007) I went to see Metallica at Wembley Stadium in the Microsoft UK executive box which they have there.

The night was amazing!  There where a number of Microsoft UK employees, MVPs, Student Partners and Student Reps so lots of interesting conversations and it great to meet some new people.  Plus the fact that free food and beer was available made it excellent.  Metallica where really good as well.

Big thank you to Microsoft UK for putting on the event, and inviting me :).  Sadly, it was my last event as a Student Partner :(

Technorati tags: ,

Labels: ,

SQL Server 2008: Table Value Parameters (TVP)

Saturday, July 07, 2007

In this post, I am going to give an overview of the new Table Value Parameters feature coming in SQL Server 2008. Table Value Parameters allow you to pass user defined tables between queries, but also between client and server. With them being tables, you can do various different things with them, for example querying, joining or inserting values just like you would with a normal table. Now, instead of having the query take a long list of parameters they can simply just take a TVP as a parameter.

To create a TVP, you have to define a user defined type and the columns which the TVP will hold. Here we create a type of Customer which can hold an id, their name and postcode.

CREATE TYPE Customer AS TABLE (id int, CustomerName nvarchar(50), postcode nvarchar(50))

Then we create a dummy table to store the information.

CREATE TABLE Customers (id int, CustomerName nvarchar(50)) GO

CREATE TABLE CustomerPostCodes(id int, postcode nvarchar(50)) GO

We now create a procedure which takes a single parameter, which is a TVP. Based on this, we can insert the data into two separate tables, however from the outside its just a single object and a single stored procedure being called.

CREATE Procedure AddCustomers(@customer Customer READONLY) AS

INSERT INTO Customers SELECT id, CustomerName FROM @customer

INSERT INTO CustomerPostCodes SELECT id, postcode FROM @customer

GO

One important point when using TVP's as parameters is that they must have the READONLY attribute. Another important point, the TVPs are actually temp tables stored on the server in tempdb. As you can see, the stored procedure inserts the records from Customer, Customer could actually contain multiple customers into the related table by querying the table.

In order to use a TVP, we need to declare it like we would with a variable.

DECLARE @myNewCustomer Customer;

We can then use the table like we would any other table. INSERT INTO @myNewCustomer VALUES (1, 'Harry', 'NEW')

Finally, we can execute the stored procedure and pass the table as a parameter. EXEC AddCustomers @myNewCustomer GO

If we query the two tables, then it will contain the following records.

id CustomerName ----------- -------------------- 1 Harry

id postcode ----------- ------------ 1 NEW

TVP will solve a lot of problems and allow for a much more streamlined experience. TVP allows for joins, queries etc, and for inserting small number of records (<1000 is recommended). For larger inserts (>1000) - look at the Bulk insert functionality.

But, they would be a bit limited if you could use them only within SQL itself, so there is full support within ADO.net 3.0, using SqlDbType.Structured type. The parameters which can be passed in from ADO.net are DataTables, IEnumerable<SqlDataRecord> and DbDataReader. There is also support for ODBC, SSMS, and within Replication.

For example, adding a datatable as a parameter to the stored procedure from C# would have been something like:

DataTable dt = new DataTable(); dt.Columns.Add.... dt.Rows.Add..... SqlCommand cmd = new SqlCommand("AddCustomer", sqlConn); cmd.Parameters.AddWithValue("@Customer", dt); cmd.ExecuteNonQuery();

Now that's cool. Hope you have found this useful.

Links

Download my SQL sample here

Related Posts

SQL Server 2008- Change Data Capture (CDC)

SQL Server 2008- Declarative Management

SQL Server 2008- SQL MERGE Statement

Katmai June CTP

Labels: , ,

Sandcastle, DocProject and creating custom topics

While looking into DocProject, I wanted to see how easy it would be to add custom topics into a project but didn't get chance to do it in my original post.

One of the nice features of DocProject is that you can add your own code into the build process.  The file BuildProcess.cs has a number of event methods which are called at various points within the build process.  In the How To... there is a a guide to creating custom topics for the webpage, however I wanted to use my existing HTML pages within the help file. It would have been nice just to be able to select these from within the options menu - hint hint Dave.  I am going to create my own for now.

What I want to do, is take a folder and include it within a CHM/Help 1.0 fie.  For this there are two important concepts, one, everything needs to be included in the html folder. Second, the index for the help file is .hhc and .hhk which is loosely based on html file and uses <UI> and <LI> tags for each entry.  For this you should really use a template for your HTML and add content based on that so all the pages look the same, but I'm just going to look at the core concept.

Firstly, I created a directory structure in my solution which looks like below.

  • /Root Folder
    • /Custom Topics
      • /test
        • test.htm
        • HtmlPage2.htm
      • HTMLPage1.htm

This is what I want to appear within my CHM file. However, it's not as simple as it first seems. I included test.htm to be the default page for when a user clicks the Test namespace, as Test is a folder in the structure, it needs a related page.

Firstly, I had to hook into the DocProject build process.  This is really nice as Dave has already provided the methods/events there for you, it was just finding where to place the call as when Sandcastle is creating its own files, it will override any changes you have made previously.  The method BeforeExecuteStep is called before every step in the build process, so I simply did a check to see if the I was before the step I was interested in:

if (step.Name.Equals("Compile Help 1.x"))
                ProcessHelpCustomTopics(context, "Html");

Now a method is called just before the help file is about to be compiled, this method writes out some information to the trace and calls CustomTopics.Import.  Here, I simply copy all the content from Custom Topics into the html folder, keeping the correct folder structure (Method CopyAllFilesInSourceToTarget).  So now all the files are in the correct place, we need to tell the help compiler about them, now this is where it started to get tricky.

There are two important files for the help structure, <Project>.hhc and <Project>.hhk.  Both look very similar but are different. The compiler looks at these files to work out which files to include, and where they should be in the hierarchy of the contents.  Firstly, I thought it would be simple to just create these files automatically based on the directory structure, hence why I wanted to keep the directory structure intact when I copied over the files.  Well, the problem is then you have no control over what order the files should appear in - that's really not good so I had to come up with a not so great solution.  Ideally, it would be an option within the addin dialog where you could build a custom table of contents, but that would require changing the core code.  I have my own .hhc and .hhk files within Custom Topics which simply outline how the table contents should be for that particular folder. Then, the user has the power to say which files should be where and lay it out correctly. I then just merge the two files with the Sandcastle created files for the table of contents.  The contents of hhc file would for example look like this:

<li><object type="text/sitemap"> <param name="Name" value="HTMLPage1"> <param name="Local" value="html\HTMLPage1.htm"> </object> <li><object type="text/sitemap"> <param name="Name" value="Test"> <param name="Local" value="html\test\test.htm"> </object> <ul> <li><object type="text/sitemap"> <param name="Name" value="HTMLPage2"> <param name="Local" value="html\test\HTMLPage2.htm"> </object> </ul>

It works well, the only problem is that the file format is not the easiest to understand, as its not XML and its not really HTML.  But to be fair, Help 1.0 is from 98, and Help 2.0 does have a XML based TOC file.

For a simple file to be displayed in the contents, the file hhc file should have a entry like

<li><object type="text/sitemap"> <param name="Name" value="HTMLPage1"> <param name="Local" value="html\HTMLPage1.htm"> </object>

Notice, li is not closed. If you wanted a page as a child node of another page, underneath an entry like above, you would add
<ul> <li><object type="text/sitemap"> <param name="Name" value="HTMLPage2"> <param name="Local" value="html\test\HTMLPage2.htm"> </object> </ul>

Adding an entry for each page between the ul tags.

Within hhk you simple just have a single entry for all of the pages, like below

<li><object type="text/sitemap"> <param name="Name" value="HTMLPage2"> <param name="Local" value="html/test/HTMLPage2.htm"> </object>

So, its not that difficult, but trying to out it would wasn't a great experience.

You can download my code BuildProcess.cs and CustomTopics.cs.  I have also zipped up the complete project for download here

While, I haven't implemented the support for Help 2.0, you would simply need to copy all of the html into the Html2 folder and modify the HxT file.  Plus, with this solution it also works with the DocSite web applications.

One thing to be aware of was that if I changed BuildProcess.cs without changing the target assembly, then it would never build as there was no point because the the source hadn't changed. That's fine, unless BuildProcess.cs changes, but selecting ReBuild gets around this and forces a fresh build. 

Another tip, Sandcastle builds a lot quicker when your laptop isn't on Power Saving mode...

Labels: ,

SandCastle and DocProject

Creator of DocProject, Dave Sexton, made some interesting comments about his software on my previous posts about Sandcastle and Creating Sandcastle websites which made me want to look at his software again.  DocProject is quite different to the other UI's for Sandcastle as it actually integrates into Visual Studio and MSBuild so very easy to integrate into new and existing solutions,  Dave has also put good How To's on the site for getting started with the project.  For this post, I am using version 1.6.2 RC and June CTP Refresh of Sandcastle.

I plan to have DocProject generate both compiled help in CHM and HxS format and also output a website for an online version of the help files for an existing solution, SandcastleDocumentationTest.  Following Dave's advice, I ran Visual Studio as Administrator on Vista, if you don't you will run into problems and load my solution like normal.  I then add a new project, and under the Visual C# tab select DocProject and the Project Documentation item.  It then gives you a simple wizard, where you can select the output type, assemblies to output, and template is a very simple and straight forward way.  After it has done that, in the solution there will be a project for your documentation.

The first thing I did was do a build, as it uses MsBuild this was done right within Visual Studio which was nice.  It would have been cool if the Sandcastle output was also being displayed as part of the build, within the build windows as Sandcastle tasks a while and knowing what is happening would be nice. (Turns out, after the Addin is loaded, it actually does this, makes for a much better experience - you even get a progress bar on the status.).  Note, while this is building, you can't rebuild your main solution so one of the recommendations is "Open the solution configuration manager and for each configuration (e.g., Debug and Release) uncheck the Build column for the DocProject so that it's only built on-demand and not when the solution is built."  Once the build has finished, in the project directory you will find the complied help files, or select Show All Files in VS for the project and it will be listed within the solution.  So its really simple to get going with this and to output your first project.

Now that we have a base project in place, we can look at extending it.  DocProject integrates into Visual Studio's Options menu (Tools > Options > DocProject) which lead onto my second sight problem, the Addin wasn't being extended into the Options menu, after one or two quick emails to Dave it turns out the problem was with Visual studio and his software did the correct thing.

So, with the addin now loaded correctly, I can look at the software.  With the Options menu, DocProject provides you with the core options for the current active project.  The main options which I like are

  • Use friendly HTML file names
  • API Topic Management, where you can set summaries for the namespaces
  • API Topic Designer, for HTML header and footer for docs

The API Topic Management and Designer are also accessible via a toolbar which is installed.

So that's how to configure the additional options, all the settings are saved into project.xml.  Now we have our documentation being created in an offline format, lets have a look at how to create it in an online format.

The other project template which is provided is for DocSite.  This option creates a ASP.net Ajax enabled website to display the created documentation online. It also outputs the CHM and HxS which are linked to the main site so the user can download them.  This means that you could just have one build which outputs all the three formats for your help which is nice.   The site itself looks really nice, uses ASP.net master pages so can be easily modified and is good enough to put on your site, in fact the Xml MVP's have here.  One problem is that the search doesn't work with partial worlds, for example Hello doesn't bring up HelloWorld which is a shame and the icons look very much like 98 style help - having simple +/- like MSDN could look better.  But that's one of the great things about DocProject, if you want a different icon then you just need to change the style sheet.  But, its great that the site is provided to the standard out the box.

Visit my example here

Finally, as I mentioned.  Because this is just a MSBuild script, it can be easily executed as part of a build and the output included within your install/package.

Summary

So, I was wrong, DocProject is a very nice tool and really worth using, so is SHFB.  My experience was tainted by the Addin problem wasn't the project's fault.  After that was installed, it worked like a dream!  The fact that the website it outputs looks amazing and is ready to go is a big plus, together with the fact that it is just a MSBuild script makes it so simple to integrate into an existing project or build script.

Labels: ,

Visual Studio and moving My Documents

Friday, July 06, 2007

Tonight, I encountered a problem again and one which I think Visual Studio should really be clever enough to handle and know.

On all of my machines, I move My Documents folder onto a separate partition for management, backup and just simply because I don't want all of my work on the main OS partition - if Windows goes down its a lot easier to recover data if its on a separate partition, of course if the drive dies I have a backup just in case.

However, Visual Studio seems to have a big problem with this.  After moving the folder, VS still tries to save and find items in the original location (C:\Users\UserName\Documents\Visual Studio 2005\).  The first time I did this was when I saved a project template into F:\Users\UserName\Documents\Visual Studio 2005\ , and for some strange reason VS wasn't picking it up. Turns out, it was still looking in the old default location.  Tonight, I installed an add-in which was installed into the correct place - F:\Users\UserName\Documents\Visual Studio 2005\Addins, yet Visual Studio was not setup to look in this location. There were environment variables set in the addin dialog, but nothing matching what was actually setup on my system.  I can't believe I am the only person who moves their Documents folder and who has ran into this problem.

To make Visual Studio look in a new locations, in Tools > Options > Environment > Addins add a setting for your Addin directory in VS2005 directory, and then move all the locations in Tools > Options > Projects and Solutions to your location.  Then the only place you have to worry is making sure when you save a project, it is saved in your new location - or where ever else you want.

But really, we shouldn't have to do this. Visual Studio should be working off the relevant path to my documents, and not a hardcoded path which it seems to be.  It's hardly best practice...and it is still the same in 2008.

Technorati tags: , ,

SandCastle - Creating a website

Wednesday, July 04, 2007

Something which I forgot to mention in yesterday's post was that SandCastle can create a website for your API.

When executing the example included within the CTP, in the output folder there is a subfolder called HTML. However, this isn't very useful as it is simply all the pages which are later compiled in the CHM.  However, Sandcastle Help File Builder (SHFB) has an excellent feature, where it takes this output and actually makes it useful.

SHFB takes the Sandcastle HTML files created via either external content or from the XmlComments, together with some magic files, mainly a Tables of contents in XML and some Javascript files which creates a table of contents for use within a HTML page, or use within an ASP.net page - both created for you.  From this page, it loads the HTML, created by Sandcastle, in an IFrame allowing for all of the Help content to be displayed online. Very cool, however it doesn't look very nice.

I have been nice and uploaded the example which SHFB outputs to here with the ASP.net output here.  The project I used was different to the previous post as SHFB couldn't import the example, required a real solution file but its more to demonstrate something.

Just to summarise, SHFB can use the Html outputted from Sandcastle, to convert it into a website which can be uploaded onto a site.

How to use ASP.net to create a 'nice' API website

I am now going to go over the process of creating a website based on the output from SHFB and make it look how you want, this could then be incorporated into your own documentation site.

The first thing I did was create a new ASP.net Ajax enabled C# based website.  I then copied the following files into the solution.

  • html folder
  • icons folder
  • scripts folder
  • styles folder
  • Collapsed.gif
  • Expanded.gif
  • Item.gif

These are all the files I will be using, if you want other items for different requirements you can include them as well. The most important files, are the folders which Sandcastle outputs and WebTOC.xml which SHFB generates.

From this, we can now generate the documentation site based on your own requirements. I simply processed the WebTOC xml file, created a TreeNode for each item, using the Value property for the URL of the related HTML page.  After adding all of them to the TreeView, I hooked into the SelectedNodeChanged event on the TreeView so when a item was clicked, I could load up the related page.

To display the page, I used an embedded iFrame, however to be able to set the URL of the iFrame from the code behind, I had to manually create the HTML for an iFrame within the code-behind and set it to the Text property of a Literal control on the page.

To make the whole thing a bit more pleasing for the user, I wrapped everything in a UpdatePanel and set the UpdateMode to Conditional.

View default.aspx.cs which contains the C# for the site
View my example site
Download all code

That's it, very simple once you have the XML processed into the navigation control.  With the HTML and the WebTOC.xml are left as loose files so an automated process could simply replace these from a newly created output and the site would automatically update.  While my example might not look 'better', it was move to prove a point that it could be done.

Note, full credit goes to Eric Woodruff for creating SHFB and the code for the original example.  Visit Sandcastle Help File Builder

Technorati tags: ,

Labels: ,

SandCastle - What you need to know

Monday, July 02, 2007

Recently, the SandCastle team released the June CTP of their software, so I decided to dig a little deeper and see what Sandcastle offers and how it works.  Note, the Sandcastle team released the June CTP on Friday 22nd, however released a Refresh a few days later renaming the template VSOrcas to Hana and making it look a lot cleaner.  If you was a little quick off the mark with your download, you will have to re-install the refresh.

Sandcastle is a command-line application which takes XMLDocs (/// comments at the top of classes and methods) from your .Net code and output them in a readable and distributable format.  Microsoft are using Sandcastle to produce both internal and external documentation on the .Net framework and seems to have a lively release schedule.

After installing the CTP, as there isn't a GUI or any kind of integration, you are left to search for everything yourself.  Luckily, there are a range of GUI's and help support available online which I will cover later.  For now, I'm just going to cover the core application.

Sandcastle can produce three types of help file format.

  • HTML files
  • CHM (Help 1.0) Format
  • HxS (Help 2.0) Format

These are styled based on predefined themes within the framework, these should fit most of your requirements and you can add your own however that's beyond the scope of this post.  I think you create another folder similar to the ones in C:\Program Files\Sandcastle\Presentation, however I'm not 100% sure on this.  The three styles included are:

  • Codename Hana. This is new within June CTP, this was called VSOrcas however due to VS no longer being called Orcas this had to change.  This will be the template for .Net 3.5 help I think.
  • Prototype.  Some ideas which have been now migrated to Hana
  • VS2005.  2005 style documentation.

This gives you enough flexibility to be able to produce helps files to meet your own needs with the look and feel you want.  Lets have a look at how to create the files.

Included within the install is an example folder which can be used to check everything is working, and for you to quickly see what the output of each template and XmlDoc tag looks like.  Within the directory C:\Program Files\Sandcastle\Examples\Sandcastle there is three files.

  1. build.proj - MsBuild script
  2. test.cs - Documented sample code which will be built.
  3. build_Sandcastle.bat - Batch file for creating the output.

The example is very simple to run, unless your running vista.  If your running vista, the build will try and save files into the Program Files directory, if your not running the command prompt with Administrator rights, its going to fail in a not very helpful way.  Either run the cmd with admin rights (right click > Run As Admin) or copy the examples to a directory you can write too.  I copied the Sandcastle examples directory to my own space to work with. Once you are in a position to run the build you will need to execute the batch file and pass in a parameter for which template you would like to use,  for example "build_Sandcastle.bat Hana" or "build_Sandcastle.bat vs2005".  Creating the example takes a while, a minute on my laptop so if your machine is a little old then it could take longer - or my laptop is just slow. Once it has been done you will notice a lot of new files in the examples directory, but the most important file is in the new Output folder and is called test.chm.  This is the help file created from the XmlDocs using the standard Microsoft Compiled Help Format. 

Screenshot of Hana output
Screenshot of output using the Hana template.

If you want to have a closer look at the samples, you can download Hana here and vs2005 here.  So that's what is created by default, lets have a little closer look at what is going on under the covers.

Within the batch file, there is a number of different commands it executes in order to process the creation of the help file.

  1. Set PATH variables.  When installing Sandcastle, it should create a Environment Variable called DXROOT which points to the install directory.  The script just makes sure all the Path variables are set for it to use the command names without having to type in the directory names.
  2. Create the output directory where all the useful files are to be placed.
  3. Compile the test.cs file.  Output all of the comments to a separate file called comments.xml.  There is an checkbox within VS2005 Build settings for a project to enable this compiler option.
  4. MRefBuilder is then called which reflects on managed assemblies to produce an XML-formatted reflection information file.  This XML file contains everything about the assembly, all the classes, methods, properties, type information etc. Everything you would expect to see via Reflection. Produces (reflection.org)
  5. The code then applies some XSLT to the output file from MRefBuilder to produce reflection.xml.  The transforms it applies depends on the parameter passed in. 
  6. It then calls more XSLT on the reflection.xml to produce manifest.xml.
  7. A batch file is called which copies all of the output from one template to the output folder for local use.
  8. BuildAssembler is called which combines the reflection information generated, together with the comments file to create a set of HTML files.
  9. More XSLT based on reflection.xml is called to create a hhp (HTML Help Workshop Project) file.
  10. The Table Of Contents is then created, again using XSLT and reflection.xml.
  11. Finally, the chm is created using a bit more XSLT and the hhc exe.  Creating the document is complex process, using lots of XSLT but thankfully
  12. There is one more step, Generation of a HxS file.  I will discuss the HxS below.

That's how it creates the file, but now lets look a bit more closely at what is actually created.

CHM (Help 1.0) Format

CHM has been around since Windows 98 and is a way to distribute help files, with open source readers for other platforms.  The format is viewable windows without installing any additional readers, so makes it a perfect choice for targeting the most people with the new templates actually making the contents look acceptable. The format is a bit limiting, doesn't really offer much but offline HTML.  Simple but effective.

HxS (Help 2.0) Format

HxS is a bit more interesting, but also comes with added complexity.  HxS was first released under the VSIP license with VS2003.  It has now been included within the Visual Studio 2005 SDK, which must be installed in order for Sandcastle to be able to create the HxS help files. 

So, why would you actually want to use it?  Well, the purpose of HxS is to integrate into the Visual Studio help system, so instead of having to load a separate file you can simple hit F1 within VS and go to the help section. However, it comes at a cost.

Firstly, you either need to use Visual Studio to view the help file, or a separate application, such as H2Viewer.

Secondly, you need to actually install the help file using a MSI. There is a walk through on MSDN and the process isn't very complicated, however if your install script is not MSI, i'm not sure how easy it is to integrate which could cause some issues.  Also, not sure how to integrate it into an existing MSI however I think this is just because of my limited installer knowledge.

To get the batch script example to work, I had to add the directory of where hxcomp.exe is located to the PATH variable, which on my system was: 

C:\Program Files\Visual Studio 2005 SDK\2007.02\VisualStudioIntegration\Archive\HelpIntegration

You can see the output here, but you will need something to view it.

Hopefully, that has given you an overview so the different sections but doesn't really provide you with any information for your own project so let's look at the GUI support and how to integrate Sandcastle into your build script, but also why you might not want to.

GUI Support

There is a range of GUIs for Sandcastle, each very different and tailor to your own requirements and needs.  There are two main projects on codeplex, one is DocProject which integrates into Visual Studio where you include the template within your solution and reference the assemblies you wish to document, it can then create the help files when the project is built.  It's good as it integrates into Visual Studio, but I found it to be more difficult to configure and it doesn't work well with Vista.  The other is Sandcastle Help File Builder, SHFB, also on codeplex.  I found this to be very easy and straight to the point. You reference an assembly and then set a series of properties for the help file like you would on a object in Visual Studio. It can output both CHM and HxS, but you can also include your own custom files which can then be included as additional 'pages' within the help file, this is good for getting start documents or licensing information - DocProject also allows for this.  You can then click build and have the help files created for you. The only requirements are that Sandcastle is installed, and the Visual Studio SDK if you want Help 2.0 content.  The great thing is, you can save all of the settings in an external file for use again.

Automating

There is two ways to integrate Sandcastle into your build process, one way is via MSBuild with complicated script commands, or if your using SHFB you simply have a command which executes the Console part of the application, passing in the shfb project file which can be saved via the GUI and it will create your help files with the latest source.

<Target Name="PackageBinaries">
   <!-- Build source code docs -->
   <Exec Command="&quot;C:\Program Files\EWSoftware\Sandcastle Help File Builder\SandcastleBuilderConsole.exe&quot; &quot;$(SolutionRoot)\src\MyProjectHelp.shfb&quot;" />
</Target>

If your using DocProject, then you simply need to build the project and this will output the files.

However, you might not want it executing every time you build the system as it will definitely add a lot of time onto your build process.  Just something to take into consideration.

Summary

That is an overview of Sandcastle and what it can offer.  Sandcastle is really good and its improving all the time.  While there is no official GUI's or integration yet, the existing projects available are up to the task in hand. I hope it has been of some use to you, if you have any questions then please let me know.

Links

Samples I created from Example: Hana Help 1.0 | VS2005 Help 1.0 | Hana Help 2.0

Download: http://www.microsoft.com/downloads/details.aspx?FamilyId=E82EA71D-DA89-42EE-A715-696E3A4873B2&displaylang=en

Visual Studio SDK: http://msdn2.microsoft.com/en-us/vstudio/aa700819.aspx

Creating MSI for HxS: How to- Use the Help Integration Wizard to Add a Help Collection to Visual Studio

MSDN: http://msdn2.microsoft.com/en-us/vstudio/bb608422.aspx

Sandcastle projects on Codeplex: http://codeplex.com/tagging/tagdetail.aspx?tagname=sandcastle

Sandcastle Help File Builder

Technorati tags: ,

Labels: ,

Microsoft UK Hacked

You would think that Microsoft would know how to secure there own web application, however it looks like the UK Events section of the site was left open to XSS and SQL Injection attacks which caused Saudi Arabia hackers to deface the page.  A video was online over the weekend showing how it was done, however has now been taken down. Hopefully it will make a reappearance.

I found it assuming.

Saudi hackers spray digital graffiti

Reported at:

http://www.theregister.co.uk/2007/07/02/ms_uk_defacement/ and http://www.zone-h.org/content/view/14780/31/

DDD5 Post Event

Sunday, July 01, 2007

Yesterday I attended DDD5.  This was my third DDD and was definitely the best.  The agenda had some ideal sessions, both thought provoking and informative and I could easily have picked two sessions per slot so had to make some difficult choices.

I've submitted by feedback, which I hope all attendees do, but here is a quick overview of the day:

An introduction to Unit Testing with Mock Objects was good, Colin used Rhino Mocks for the demo and NUnit (why aren't you using MbUnit Colin?) and it was a good introduction.   Pleased he didn't spend too much time talking about TDD, instead focusing on what the talk was actually about.  Need to look at Mocks some more, expect one or two posts on the subject over the next month.

Being lazy is an art form (or: Making your computer work for you) was very cool.  It was Zi's first session and he came across well. The content was also very good, firstly he discussed CodeRush and Refactor! then moved on to discuss DXCore and creating addins for Visual Studio.  I have DXCore installed, but never used it to develop so was really interesting to see how easy and powerful it was to use.

An Appraisal of "Object Thinking" was another really good session.  I haven't read the Object Thinking book, but the talk was still really good and made some good points.  I need to go buy the book now, read it, then re-read his slides.

Do Design Patterns Make Sense in ASP.NET? discusses all the patterns which are used within ASP.net and broken it down in a very understandable way.  However, he didn't answer the question of if they make sense...

Next Generation Data Access with LINQ discussed how to use Linq for data access, with a bit of TDD and DDD thrown in.  Interesting, but covered most of the stuff I have already read - that reminds me I need to finish reading the Linq in Action book.

Grok Talks where held at lunch, they where much better than previous years with help from a Mic and big screen. The Imagine Cup winners did their presentation, which was 'interesting'. I only managed to catch the second half but it was interesting to see how they came across and what they where talking about.

Geek Dinner - After the event I attended the Geek dinner which was held at a different location this year, on the side of the River.  Really nice location, shame about the weather, but it was good, very easy to talk to people but also move around and talk to other people which is not possible at Pizza Express. Plus the beer was following so it was all good.  The food was nice, there wasn't a lot but the beer, atmosphere and venue made up for this.  While it wasn't in the town centre it was still easy to get to so staying at the Novotel wasn't a problem, where I had one or two more beers before heading to bed. I also find the dinner to be a great way to end the day, makes the day more of a event and more fun.

So onto DDD6 (in about 6 months time) which hopefully I will be attending, I might finally submit a session after talking about doing it for so long.  If you haven't been to DDD before, or you have but not gone to the dinner afterwards I really recommend both. Great day, great night, great fun!

Technorati tags: ,

Labels: ,