7/24/2008
LifeCycle Solutions - Home ( the software development blog )
 

<July 2008>
SunMonTueWedThuFriSat
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789

Subscribe to this feed:

RSS 2.0 | Atom 1.0 |CDF





Add to Technorati Favorites

Monday, August 28, 2006

Here it is. So hopefully source code won't mess up our blog's layout anymore, let's see:

(Took out code block)

Nope.  Apparenly, it still causes problems in IE.  We'll keep looking...

Posted by Daniel Root

Wednesday, August 23, 2006

Ever wondered what a secure ASP.NET 2.0 application should look like?  The ASP.NET Internet Security Reference Implementation rolls all of the Patterns and Practices Security Guidance into real-world sample application, complete with full documentation about all of the security features, why and how they were implemented, and the drawbacks to doing so.

If you are doing ASP.NET 1.1 or 2.0 web design, you should download this, read through it, and check out the code.  While the code is 2.0, all of the security concepts- and some of the solutions- map to 1.1 apps as well.

One note: it installs into C:\Program Files\Microsoft\Internet Security Reference Implementation by default.  It took me forever to find it!

Posted by Daniel Root

Referencing fully-qualified object names in SQL Server can be tedious, particularly if you're not using an editor with Intellisense (a la ApexSQL Edit).  If the object you're working with is on a linked server, it becomes even more of a burden to get the full name correct, since it can have 4 parts:  server.database.owner.object

Fortunately, SQL Server 2005 comes to the rescue with a new database feature called synonyms.  Synonyms can be used as an alias to a fully-qualified object name, so the table "ProductionServer.ProductionDatabase.dbo.Parts" can be referenced in your queries as simply "Parts" by issuing the following statement:

CREATE SYNONYM Parts for ProductionServer.ProductionDatabase.dbo.Parts

SELECT * FROM Parts

This can also be done visually in SQL Server Management Studio.
Posted by Brian Parks

Tuesday, August 22, 2006

A quick tip for the Visual Studio 2003 and 2005 code editor: If you want to quickly change the case of some text, just select the text and hit Ctrl-Shift-U for upper or Ctrl-U for lower.  Not exactly earth-shattering, but I was pleasantly suprised when I needed to upper-case a large chunk of text today and found this.

Posted by Daniel Root

Thursday, August 17, 2006

I recently data bound to a DateTime property in ASP.NET 2.0, and couldn't figure out why the formatting wasn't working properly.  I set the DataFormatString property to {0:d}, which should change the column to short date format.  But it wasn't formatting at all.  After a little digging, I found that it was because HtmlEncode wasn't set to false.  Setting HtmlEncode="false" on the column fixed the problem. 

Seems a bit odd at first, but the purpose of HtmlEncode is to prevent cross-site-script attacks.  Here's what's happening:

  • The property's value is retrieved.
  • ASP.NET converts the value to a string and formats it to remove any HTML.  For example a '<' gets changed to '&lt;'.  So, if someone were to somehow add the value <script>doSomethingTricksy()</script> to your database, it wouldn't get run here...
  • ASP.NET applies the DataFormatString, but by now the date is already a string. 
  • Formatting the string "1/1/2005 12:00:00 PM" doesn't do anything.

Since we know the type is a date, and it would be difficult to insert HTML into the date, then it's pretty safe to turn off this feature for this column.  Microsoft has a little note on this issue here.

I say pretty safe, because it's actually still possible that script or other HTML could be inserted into this column.  A recent post by Scott Hanselman may give you a clue.  Suppose you let users define their own DateTime formatting preferences, and did something really evil, like this:

customCulture.DateTimeFormat.ShortDatePattern = Request("format").ToString()
System.Threading.Thread.CurrentThread.CurrentCulture = customCulture
System.Threading.Thread.CurrentThread.CurrentUICulture = customCulture

And then suppose some crafty hacker sent a link to  yourpage.aspx?format=<script>doSomethingTricksy()</script>MM/dd/yyyy.  Any time you databound to a DateTime, if HtmlEncode was false, then the script would be run! Once somebody gets that far, they can do any number of bad things.

Granted, it's a pretty low threat, but it's worth knowing about.

Posted by Daniel Root

One of LifeCycle's favorite .NET object framework gurus, Rocky Lhotka, is on dnrTV again.  This time he discusses using CSLA.NET and ASP.NET 2.0 Object Databinding.
http://dnrtv.com/default.aspx?showID=32

Posted by Daniel Root

Tuesday, August 15, 2006

The Portable Network Graphics (PNG) format is a great image format.  It's file sizes are typically much smaller than GIF or JPG, and it supports alpha transparency.  So, you can have a transparent background on your image, and it will look correct on any page.  With GIF or JPG, a designer would need to carefully adjust the image background to match the page background.  The only problem with PNG, is that IE doesn't support it natively!  Instead of rendering the transparent areas correctly, they are displayed as opaque grey areas.   Fortunately, IE 7 supposedly fixes that, and there are workarounds for IE 5.5 and 6.  Bob Osola has a nice explanation and a javascript fix.

Suppose we wanted to package this solution in a way that makes it easy for ASP.NET developers to use, or we have custom controls that will rely on this fix.  Currently, they would have to keep up with the client script, and reference it from each page in each application they wrote.  Using Web Resources and Client Script Management in ASP.NET 2.0, we can greatly simplify reuse of this script.

Solution Overview
The fix itself is a little javascript that must be run on every page that requires PNG support.  It works by looping through all the elements on a page and, if it's an <img> element with a .png image, applying the CSS filter to fix PNG in IE.  We've modified it slightly to do the same for <input type="image"> elements, such as those rendered by the DataGridView's command button columns.  As is, the developer must add the script to their application, and add this line to the <head> element of each page that needs PNG transparency:

<!--[if lt IE 7]>
<script defer type="text/javascript" src="pngfix.js"></script>
<![endif]-->

But, we want the solution to be easy for developers to use.  From the application developer's perspective, we want the expirience to be:
  • Add a reference to MyCompany.Web.dll
  • Add the line MyCompany.Web.UI.ClientScriptManager.EnablePNGSupport(...) to a control, page, or master page's OnLoad event.
Setting it up
This tells us that we'll need a MyCompany.Web Class Library Project, and a class called 'ClientScriptManager'.  So in VS05, create a project named MyCompany.Web.  For various reasons, it's also a good idea to set the default namespace to empty here.  This will let you set the namespace inside your class, and will make using Web Resources easier.  To do this:
  • Rt Click the project
  • Choose Properties
  • Choose the Application Tab
  • Empty the 'Default Namespace' field.
Embedding Resources
Next, create a folder named Resources, and add the pngfix.js file to it.  To use this javascript file from web applications, it needs to be embedded in the assembly and marked as a web resource.  Follow these steps to do this:
  • Right click the script file and choose 'Properties'
  • Set Build Action to 'Embedded Resource'.
  • Go to the Solution Explorer and click 'Show All Files'
  • Expand the 'My Project' item
  • Open AssemblyInfo.vb
  • Add this line to the bottom: <Assembly: WebResource("pngfix.js", "text/javascript")>
  • Note: If you didn't set the default namespace to empty as above, you'll need to include it here  (ie: "MyCompany.Web.pngfix.js")
To recap, this just told the compiler to take the pngfix.js file and stuff it into the .dll when it's compiled, and mark it as usable by web applications.  This fix also requires a blank image file to work correctly.  Do the same as above for the file blank.gif.

Getting Resources at the Client
The last step is to create a method that will allow developers to easily use this javascript.  This method needs to add a script to the page to set the path to blank.gif, and a script to run the fix in pngfix.js.  But remember that file has been embedded in a dll, so that our developers don't have to keep up with it. This is where Web Resources come in.  To get the content that was embedded into the dll, ASP.NET 2.0 gives us a method named GetWebResourceUrl(...).  When called, this method returns a URL to a special path that looks something like this:

/WebResource.axd?d=rN9s8cQhdsLqV...

This location actually maps to an HttpHandler built in to ASP.NET 2.0, which will do the work of pulling the embedded resource out of our assembly, and returning it to the client.  So, to get the embedded resource- be it a script, image, or any other file, all we need to do is browse to the url provided by GetWebResourceUrl.  But, your developers shouldn't have to worry about all that.

The code below creates a class with a shared method for registering the two scripts needed for this fix to work.  It first checks to see if the browser is IE 5.5 or 6.  Next, it checks to be sure the script isn't already registered, since adding it twice would cause errors. Finally, it registers the scripts.

Imports System.Web.UI.WebControls

Imports System.Web.UI

Imports System.Web

 

 

Namespace MyCompany.Web.UI

    ''' <summary>

    ''' Class for managing client side scripts frequently used by MyCompany web applications.

    ''' </summary>

    ''' <remarks></remarks>

    Public Class ClientScriptManager

 

        ''' <summary>

        ''' Adds client script to add PNG transparency support to Internet Explorer 6.0 and lower browsers,

        ''' if it has not already been added by a previous call to this method.

        ''' </summary>

        ''' <param name="page">The page.</param>

        ''' <remarks>

        ''' <para>IE 6 and lower do not properly display PNGs with transparent backgrounds.

        ''' This method puts a javascript include tag in the page's &lt;head&gt; declaration

        ''' if the browser is IE 6 or 5.5. This fix is based on the one

        ''' found here: http://homepage.ntlworld.com/bobosola

        ''' </para>

        ''' <para>

        ''' Typically this would be done using Page.ClientScript, however that method does

        ''' not support the 'defer' attribute, which is required in this case.

        ''' </para>

        ''' <para>

        ''' To use, add the following to your Page or MasterPage:

        ''' <code>       

        '''   Private Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init

        '''    MyCompany.Web.UI.ClientScriptManager.AddPNGSupport(Me.Page)

        '''   End Sub

        ''' </code>

        ''' </para>

        ''' </remarks>

        Public Shared Sub EnsurePNGSupport(ByVal page As System.Web.UI.Page)

            If HttpContext.Current.Request.Browser.Browser = "IE" Then

                Dim Version As Double = CDbl(HttpContext.Current.Request.Browser.Version)

                If Version < 7.0 And Version > 5.5 Then

                    Dim pageHeader As System.Web.UI.HtmlControls.HtmlHead = page.Header

 

                    If Not pageHeader.Page.ClientScript.IsClientScriptBlockRegistered( "SetBlankImageUrl") Then

                        Dim blankImageScript As String = String.Format("<script type=""text/javascript"">var blankImageUrl = '{0}'</script>", pageHeader.Page.ClientScript.GetWebResourceUrl( GetType(MyCompany.Web.UI.ClientScriptManager), "blank.gif"))

                        pageHeader.Page.ClientScript.RegisterClientScriptBlock( pageHeader.Page.GetType(), "SetBlankImageUrl", blankImageScript)

                    End If

 

                    If Not ContainsControlWithId(pageHeader.Controls, "pngFixBlock") Then

                        Dim scriptBlock As New LiteralControl(String.Format("<script defer type=""text/javascript"" src=""{0}""></script>", pageHeader.Page.ClientScript.GetWebResourceUrl( GetType(MyCompany.Web.UI.ClientScriptManager), "pngfix.js")))

                        scriptBlock.ID = "pngFixBlock"

 

                        pageHeader.Controls.Add(scriptBlock)

                    End If

 

                End If

            End If

        End Sub

 

        ''' <summary>

        ''' Gets a value indicating whether a control with the given id already exists in a collection.

        ''' </summary>

        ''' <param name="controls"></param>

        ''' <param name="id"></param>

        ''' <returns></returns>

        ''' <remarks></remarks>

        Private Shared Function ContainsControlWithId(ByVal controls As ControlCollection, ByVal id As String) As Boolean

            For Each control As Control In controls

                If control.ID = id Then Return True

            Next

            Return False

        End Function

    End Class

End Namespace


Copy the above, and put in a class called 'ClientScriptManager.vb.'

Using the Fix
Build, and if everything worked correctly, your developers can reference the assembly from their projects, and fix PNG transparency with a single line of code in their page's OnLoad event:

MyCompany.Web.UI.ClientScriptManager.EnsurePNGSupport(Me)

An even better option would be to put this in a master page OnLoad event:

MyCompany.Web.UI.ClientScriptManager.EnsurePNGSupport(Me.Page)

Finally, it's worth noting that this would also work for custom controls.  You can use the same technique to embed a png to be used by, say, the ImageUrl property of your control.   The only gotcha is that the script looks for the .png extension to determine if it needs to fix an element, but the URL returned by GetWebResourceUrl doesn't end in '.png'.  To fix this, simply add the extension to the query string:

If Not String.IsNullOrEmpty(Me.ImageUrl) Then

   printLink.ImageUrl = ImageUrl
ElseIf Me.DesignMode Then

   printLink.ImageUrl = Me.Page.ClientScript.GetWebResourceUrl(Me.GetType(), "printer48.png")

Else

   printLink.ImageUrl = Me.Page.ClientScript.GetWebResourceUrl(Me.GetType(), "printer48.png") + "&.png"

End If

Files for this post:
pngfix.js (2.19 KB)
blank.gif (.04 KB)


Posted by Daniel Root

Wednesday, August 09, 2006

If you were intrigued by our previous post on PowerShell, but found it difficult to get started using notepad or your favorite text editor, try this:  PowerShellIDE.
In addition to having useful editor features (like IntelliSense and collapsing code blocks) it also uses the groovy new Office 2007 look and feel.  Free download, for now.

If you're interested in getting a good overview of PowerShell, here's a free e-book.

Posted by Brian Parks

Sunday, August 06, 2006

Microsoft is cranking out ASP.NET 2.0 how-to videos at a record pace.  Brian Goldfarb lists several new ones here. Scott Guthrie lists them also, and includes a few others here, including one on Microsoft's AJAXy toolkit, Atlas.

Posted by Daniel Root

Shaun Walker, Creator & Maintainer of the open-source DotNetNuke project, has posted a "Feature Matrix Showdown" on the DNN site comparing various features of the following solutions:
- DotNetNuke 4.x
- ASP.NET 2.0 (out of the box)
- SharePoint Portal Server 2003 (and Windows Sharepoint Services 2.0)
- Microsoft Office Sharepoint Server 2007 BETA (and Windows Sharepoint Services 3.0)

This is an interesting comparison, and a good starting point for anyone in the market for a portal solution.

Posted by Brian Parks

Friday, August 04, 2006

Online labs are Microsoft's newest way to learn about developer tools and techniques.  These guided tutorials give you a real, live virtual PC pre-installed with everything you need- Visual Studio 05, .NET 2.0, etc.  Just sign up and use the web-based remote desktop client to connect.  There's a list of good .NET 2.0 Labs over at WWWCoder.

Posted by Daniel Root

Thursday, August 03, 2006

Here is a nice short video on setting up security for a folder in ASP.NET 2.0.  This was possible in 1.1, but 2.0 makes it even easier- no code required to secure your site by roles!

Posted by Daniel Root

Tuesday, August 01, 2006

Microsoft's documentation generator, codenamed Sandcastle, is available for download now.  Keep in mind this is a very rough CTP.  It's all command-line driven, though some community efforts have made scripts, etc. to simplify things.  I've run it, and was able to generate a .chm, though with much more effort than nDoc. 

The lack of UI brings up an important point.  This was the code that Microsoft was using to generate MSDN developer content.  Most likely they used it as part of a continuous integration process that generated new documentation in the background.  While GUI may make things easier up front (and I definitely want one, Microsoft), thinking about integrating documentation seamlessly into our build processes using MSBuild and scripts may be helpful as well.
Posted by Daniel Root

The long-awaited arrival of Internet Explorer 7 will be delivered to PCs via Windows Update, according to a recent TechNet notice from Microsoft...worth noting for web designers and developers who will probably want to check their work for proper rendering in the new browser.

The latest beta for IE7 can be downloaded here.  If installing beta software on your PC doesn't seem appealing, try loading it in a virtual test environment with Virtual PC (which is now a free download, unless you are a Mac user). 

Posted by Brian Parks

© 2006 LifeCycle Solutions, LLC | All Rights Reserved