David Truxall

Adrift in .Net

<May 2008>
SuMoTuWeThFrSa
27282930123
45678910
11121314151617
18192021222324
25262728293031
1234567


Navigation

Other Good Blogs

My Other Articles on CodeProject

Subscriptions

News

Day of .Net October 20, 2007 - See You there!
View David Truxall's profile on LinkedIn

Post Categories



ASP.NET 2.0 and Global.asax: What not to do

I deployed a site today that has some code in the Global.asax event handlers. I let Visual Studio 2008 add the file to my project when I created it, and it put the code directly in the file inside <script runat="server"> tags. I went with it. So when I deployed the file, none of the events fired. Ever. The lesson is: Don't put your code in the global.asax file. Apparently this problem is by design. There is a vague KB Article on this problem, but the solutions aren't all that helpful, I didn't want to pre-compile, and the first solution made no sense at all. A little searching and I found one good solution: put a class that inherits HttpApplication in the App_Code folder as described here. What I don't understand is why Visual Studio adds the file that way if it isn't going to work on an xcopy deployment. Microsoft seems to go out of their way to protect us from ourselves so often that I am surprised the IDE does something intentionally that won't work.

posted Wednesday, February 06, 2008 8:57 AM by davetrux with 0 Comments

Technical Irony

While looking for a URL rewriting tool for a client I found a reference to a tool, clicked the link and got a 404 error.

posted Friday, January 25, 2008 11:02 AM by davetrux with 0 Comments

Defining Project Success

There is an article in Dr. Dobbs that describes a survey performed by the author. The survey was intended to query Project Managers, IT Managers, IT staff and business stakeholders on what defined the success of a project.

There were definitely some interesting findings:

  • The IT industry has a long way to go to achieve a 100% success rate for projects
  • Agile projects were more successful than traditional waterfall projects
  • Off-shored projects were most likely to fail
  • Respondents rated quality as the most important issue, and rated the importance of following items this way when analyzed as a group:

    Quality > Scope > Staff Health > Time of Completion > Money
  • Project managers differed significantly from all other groups in their perception of success, rating time and money over quality.
  • Business stakeholders placed a higher value on ROI and and shipping when ready than the rest of the groups
  • A majority of respondents in all groups worked on projects they knew would fail from the start, but canceling a troubled project was not viewed as a successful outcome

I am not surprised by project managers having a different view, given that they are trained to value on-time and on-budget projects. Someone has to keep an eye on the bottom line, but I have experienced this gap when a project runs into trouble. I have been thinking about the differences between Agile and Waterfall-style projects and how they differ. I think there is some middle ground between the two that is yet to be identified that gives us the benefits of heavier requirements and design and the responsiveness to change.

posted Monday, January 14, 2008 5:11 PM by davetrux with 0 Comments

Reporting Services - Page Breaks and PDF Files

In Reporting Services reports, page breaks occur when the size of the body exceeds the page size. The crux of the lesson I learned is that the size of a sub-report cannot exceed the size of the parent containing it. Funny page breaks occur in the PDF output if this is the case.

Brian Welcker posted some terrific details on how page breaks work in Reporting Services, this post is essential if you are creating reports.

posted Wednesday, November 07, 2007 11:11 AM by davetrux with 0 Comments

Building a Basic Excel Document with Open XML

I recently gave a talk about Open XML, and found that there were not many complete code samples out there which described how to build Office 2007 documents using .Net and SpreadsheetML. Most of the examples I ran into were snippets or functions, or just examples of the SpreadsheetML. As one of my demos, I created a C# class which builds a basic spreadsheet. This post describes that class.

There are prerequisite installs required to run this code:

  • .Net 3.0 Framework (System.IO.Packaging is part of WPF)
  • SDK for Open XML Formats, which is currently a CTP, so the code is subject to change if the object model changes at all with the final release (so therefore does the code in this post).
  • Code Snippets that are available for Open XML.

The class (called Spreadsheet) does two basic things:

  1. Create a spreadsheet package
  2. Insert data into a worksheet in the newly created package

The first step is creating the package, which consists of XML files for the SpreadsheetML and XML files which manage the relationships between those files. In an Open XML spreadsheet, the minimal spreadsheet package requires three documents containing SpreadsheetML:

  1. A workbook file
  2. A worksheet file
  3. A relationship file

Additionally, SpreadsheetML uses a concept called "Shared Strings". SpreadsheetML dictates storing Shared Strings separately from the worksheet in their own document, so the document stores less data if the document re-uses strings. Strings can also be added to the spreadsheet "in-line" and not used Shared Strings storage. For this example labels are stored as Shared Strings to demonstrate the concept, therefore the spreadsheet package also requires a Shared Strings document.

The SDK for Open XML Formats provides a new component, Microsoft.Office.DocumentFormat.OpenXml.dll, that wraps some of the functionality of creating an Open XML document with System.IO.Packaging. Essentially it manages creating the files and the relationships between the files in the package. Once you have created the files and relationships, you still need to create code to insert actual data into the documents. This example uses two steps:

  1. Create the basic XML document using a template of existing XML
  2. Insert data into the existing XML.

The following are the contents of three small XML files created and added to a Templates directory in the solution. These three files are the basis for the required parts of the package:

The workbook template

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">

    <sheets>

        <sheet name="{1}" sheetId="1" r:id="{0}" />

    </sheets>

</workbook>

Notice that the XML contains .Net placeholders. Later on we can replace these with actual values that can vary at run time.

The worksheet template

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" >

    <sheetData/>

</worksheet>

The shared strings template

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">

</sst>

These XML templates make up the basic content of the package. The C# class contains a CreateSpreadSheet procedure which will create the basic pieces of the package. The main thing to notice is that  by creating the part object (workbook, shared strings, worksheet), you are only creating the part file, not the content of that part file. The templates above become the content for the parts. There is no need to manage the relationship files directly, the API is doing that automatically.

public void CreateSpreadsheet(string path, string firstSheetName)

{

    using (SpreadsheetDocument doc = SpreadsheetDocument.Create(path, SpreadsheetDocumentType.Workbook))

    {

        //Add the workbook

        WorkbookPart workbook = doc.AddWorkbookPart();

 

        //Create the shared strings part

        SharedStringTablePart stringTable = workbook.AddNewPart<SharedStringTablePart>();

        this.AddPartXml(stringTable, this.ReadXML(@"Templates\SharedStringTemplate.xml"));

 

        //Create a worksheet

        WorksheetPart sheet = workbook.AddNewPart<WorksheetPart>();

 

        //Get the relationship id so the workbook and worksheet can be related

        string sheetId = workbook.GetIdOfPart(sheet);

 

        this.AddPartXml(workbook, this.WorkbookXml(sheetId, firstSheetName));

        this.AddPartXml(sheet, this.ReadXML(@"Templates\WorkSheetTemplate.xml"));

 

        doc.Close();

    }

}

The only interesting part is retrieving the ID of the worksheet part when building the workbook part. To create the content of each part the procedure opens an XML file and streams the content into the file. There are helper functions for this, which are really just standard ways of handling XML in .Net:

protected void AddPartXml(OpenXmlPart part, string xml)

{

    using (Stream stream = part.GetStream())

    {

        byte[] buffer = (new UTF8Encoding()).GetBytes(xml);

        stream.Write(buffer, 0, buffer.Length);

    }

}

 

protected string ReadXML(string fileName)

{

    StreamReader reader = new StreamReader(Environment.CurrentDirectory + @"\" + fileName);

    string contents = reader.ReadToEnd();

 

    return contents;

}

 

protected string WorkbookXml(string sheetId, string sheetName)

{

    string contents = this.ReadXML(@"Templates\WorkbookTemplate.xml");

 

    return string.Format(contents, sheetId, sheetName);

}

Notice the WorkbookXml procedure has a call to string.Format to replace some placeholders with actual data: the ID of the worksheet part relationship and the name of the worksheet. The name of the worksheet is important later, when we want to add data to the worksheet.

The second step is to actually add data to the worksheet. The class uses two functions available as Code Snippets (XLInsertStringIntoCell, and XLInsertNumberIntoCell). I won't reproduce the code here as I don't own it, but essentially the functions open the proper parts and insert the data. These functions take in the file, the sheet name, cell reference and cell value as parameters.

Lastly, I wrote a console app to exercise the Spreadsheet class:

class Program

{

    protected static readonly string fileName = "example.xlsx";

    protected static readonly string firstSheetName = "Sheet1";

 

    static void Main(string[] args)

    {

        string path = Environment.CurrentDirectory + @"\" + fileName;

 

        Spreadsheet file = new Spreadsheet();

 

        file.CreateSpreadsheet(path, firstSheetName);

 

        file.XLInsertStringIntoCell(fileName, firstSheetName, "A1", "Category");

        file.XLInsertStringIntoCell(fileName, firstSheetName, "B1", "Value");

        file.XLInsertStringIntoCell(fileName, firstSheetName, "A2", "Red");

        file.XLInsertNumberIntoCell(fileName, firstSheetName, "B2", 30);

        file.XLInsertStringIntoCell(fileName, firstSheetName, "A3", "Blue");

        file.XLInsertNumberIntoCell(fileName, firstSheetName, "B3", 60);

        file.XLInsertStringIntoCell(fileName, firstSheetName, "A4", "Green");

        file.XLInsertNumberIntoCell(fileName, firstSheetName, "B4", 10);

 

        Console.WriteLine("Workbook created at " + path);

 

        Console.ReadKey();

    }

}

Before the comments start to fly, I want to point out a couple things:

  • This bit of code is not that efficient, I realize it opens and closes the package a bunch of times. This is really just to demonstrate what is possible and not what is necessarily the best practice. There are very few code samples available, and I am shooting for simplicity here.
  • I know ExcelPackage is on CodePlex and does a better job of wrapping the APIs involved and is much easier to write code with. Once you have a basic understanding of these APIs you will appreciate for the work being done on that project.

Download the VS 2005 project. Don't forget to install all the prerequisites listed above before trying the project. I didn't include the two functions necessary from the Code Snippets in the project either (since I didn't write that code), you will have to put those in yourself.

posted Tuesday, November 06, 2007 11:40 AM by davetrux with 0 Comments

Why you should care about password length

Jeff Atwood shows us why we should consider better password policies when developing applications or setting company policy.  

As we know, the biggest threat to security is not hackers, but the users themselves making it easy for someone to gain access to protected resources by having ridiculously easy to guess passwords. As developers we are as much at fault for building applications that allow this behavior.  Jeff recommends using pass phrases instead of passwords. A phrase is longer (and thus more resistant to brute force) and easier to remember than a mixed up jumble of nonsensical characters. By adding an unusual word or character pass phrases are very difficult to break with dictionary attacks as well.  Pass phrases are controversial as well, see:

The Great Debates: Pass Phrases vs. Passwords. Part 1 of 3

The Great Debates: Pass Phrases vs. Passwords. Part 2 of 3

The Great Debates: Pass Phrases vs. Passwords. Part 3 of 3

Personally, I think the hard part is convincing users and business owners of an application that longer or more complicated is better. From my own experience I understand users want the simplest password policy possible. Often the business owners of an app don't feel the information being protected is all that important to justify such an imposition for the users, or feel that it becomes a support expense because users can't manage their own data or password very well (a great argument for using something like Windows CardSpace). I think they forget that users re-use the same password everywhere possible: a free e-mail account, network access at work, bank web sites, a blog, a MySpace account, etc. I would not want to be responsible for a malicious person to gain a password from my system and then use that password to systematically destroy someone else's life. Be strong, insist on good password policy.

posted Thursday, October 25, 2007 12:50 PM by davetrux with 0 Comments

Day of .Net Presentation

I thoroughly enjoyed my presentation and the time at Day of .Net this past Saturday. Special thanks to those folks who attended my presentation.

Here is my slide deck.

This is a zip file of the code from the presentation. Remember you need the .Net 3.0 framework and the SDK for Open XML Formats CTP in order to run the code.

posted Monday, October 22, 2007 9:30 AM by davetrux with 0 Comments

Open XML References

Resources

ECMA-376  Standard Specification

Word 2007 Content Control Toolkit

Open XML Code Snippets for Visual Studio 2005

OpenXmlDeveloper.org

Open XML e-book

XML in Office Developer Portal

SDK for Open XML Formats CTP (online)

MSDN Forum for Open XML SDK

Software

Package Explorer

ExcelPackage

Word 2007 Content Control Tookit 

Open XML Code Snippets for Visual Studio 2005

SDK for Open XML Formats CTP (download)

Microsoft .Net Framework 3.0

Articles

Introducing the Office (2007) Open XML File Formats

Building Server-Side Document Generation Solutions Using the Open XML Object Model (Part 1 of 2)

Building Server-Side Document Generation Solutions Using the Open XML Object Model (Part 2 of 2)

Manipulating Excel 2007 and PowerPoint 2007 Files with the Open XML Object Model (Part 1 of 2)

Manipulating Excel 2007 and PowerPoint 2007 Files with the Open XML Object Model (Part 2 of 2)

Dive Into SpreadsheetML (Part 1 of 2)

Dive Into SpreadsheetML (Part 2 of 2)

Manipulating Word 2007 Files with the Open XML Object Model (Part 1 of 3)

Manipulating Word 2007 Files with the Open XML Object Model (Part 2 of 3)

Manipulating Word 2007 Files with the Open XML Object Model (Part 3 of 3)

Blogs

Wouter van Vugt

Brian Jones

Kevin Boske

posted Friday, October 19, 2007 11:24 AM by davetrux with 0 Comments

ASP.NET Web Project Build Events

I have a web project (the original 2005 web project type, not a web application project) and had a problem getting files copied to the bin directory. Essentially, one of the library projects referenced by the web project has an XML file in the project output, but when the solution is built, the XML file in the bin directory of the library project is not pulled into to the bin directory of the web project. Of course, a post-build event seemed like the thing to do, but web projects don't have support for that.

A little digging and I found this post by Scott Guthrie that describes a "Build Helper Project". You simply add an empty class library project to your solution. You then use the build events in the empty project use to add build events to your web project. You just make sure the project build order is correct so the events get called when you need them.

posted Monday, October 08, 2007 9:28 AM by davetrux with 0 Comments

Speaking at Day of .Net in Ann Arbor

I will be speaking at Day of .Net in Ann Arbor, MI on October 20th. It's a Saturday, and it's a completely free event. I will be presenting Creating Office Documents with Open XML. I will be going over the Packaging API and how to programmatically create and manipulate Office docs.

There are four concurrent sessions all day long covering many aspects of .Net.

See you there!

 

Day of .Net October 20, 2007 - See You there!

posted Thursday, October 04, 2007 10:03 AM by davetrux with 1 Comments

Laws from DDJ

Got my new November Dr. Dobbs issue today. The back column "Swaine's Flames" has reminded me of some programming "laws" that I have seen before. I have added my own corollaries for each:

Kernighan's Law: "Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it."

My corollary: "The developer who's code that you inherit believed they were twice as smart as they really are."

Eagleson's Law: "Any code of your own that you haven't looked at for six or more months might as well have been written by someone else."

My corollary: "You can recognize that you have written code to solve a particular problem but will be unable to locate the specific instance you recall."

posted Monday, October 01, 2007 9:50 PM by davetrux with 0 Comments

Links for VSTS Database Professional Edition

Resources

Team Site
http://msdn2.microsoft.com/en-us/teamsystem/aa718764.aspx

Product Forum
http://forums.microsoft.com/msdn/showforum.aspx?forumid=725&siteid=1

Good Blogs
http://blogs.msdn.com/camerons
http://blogs.msdn.com/sachinre

 

Downloads

Service Release 1
http://support.microsoft.com/kb/936612/

PowerTools
http://go.microsoft.com/fwlink/?LinkId=88852

posted Tuesday, September 25, 2007 10:00 AM by davetrux with 0 Comments

Day of .Net in Ann Arbor, MI

Registration is now open for Day of .Net in Ann Arbor on October 20th, 2007 at Washtenaw Community College in Ann Arbor, MI. Register here for this completely-free, all day learning event. Start planning now to take advantage of this event!

Day of .Net October 20, 2007 - See You there!

posted Tuesday, September 11, 2007 8:40 AM by davetrux with 0 Comments

Use RunAs to Connect to SQL Servers in Another Domain

Doh! Another simple thing I wish I knew (or thought of) previously: Using RunAs to connect to SQL Servers in other domains

posted Friday, September 07, 2007 9:31 AM by