Sponsored

Tuesday, December 9, 2008

FIX: HTML documents may not be displayed correctly in IIS 7.0 on Windows Vista

Recently I have finally upgraded to Windows Vista from Windows XP. Except regular trouble of upgrading your operation system that feels like moving to a new house (which is people say worse then an earthquake and flooding together) I was quite frustrated by a number of annoying problems with IIS 7 when first it's not installed by default (all right, security is tougher now, but can I at least have an option?), then not all of the components installed that required by ASP.NET and VS2008 (is it so difficult to suggest a correct package?), then again my web app does not work with the default App Domain (why did you guys call it "default" and the real default call "classic"?), and finally everything works but the site does not look like it should be.

I spent some time probing different setting of IIS and finally gave up and looked it up on the Internet. What a relief! It's a Microsoft bug and not me being an idiot! Actually it was submitted on March 17, 2007 and still not in SP1.

So the problem was that the entire static content of the web app including images and styles was not returning to a browser by IIS (content length 0 bytes) because IIS 7 initial configuration was incorrect when it was first installed on Vista.

I am not describing a fix here, read it here: http://support.microsoft.com/kb/930901/en-us

Wednesday, October 1, 2008

Friday, September 26, 2008

Color Picker ASP.NET AJAX extender control

I was looking for a client-side color picker control and found it extremely difficult to find something that would satisfy to my requirements. I have found plenty of pure JavaScript controls written with various levels of proficiency and there was even one ASP.NET color-picker control that I almost liked but still my major requirement was not satisfied: I was looking for AJAX .NET Extender control - easy to use and based on a solid and proven platform.

So, I have researched what other color picker controls do and decided to write the one myself that I would base on Microsoft AJAX .NET platform. After some considerations I've decided to go even further and build an AJAX Control Toolkit Extender control.

As an example I took an AJAX Control Toolkit Calendar extender and in my Color Picker extender control I also internally used another AJAX Control Toolkit control: Popup extender.

Now, what are the advantages of implementing a client control as an ASP.NET AJAX extender?

  1. You use ASP.NET page mark-up to render the control content to the browser.
  2. No need to manually inject JavaScript, HTML and other resources.
  3. You develop JavaScript code in a standalone file leveraging ASP.NET AJAX framework and Visual Studio intellisense abilities.
  4. JavaScript per se is very well structured, easy to read and debug.
  5. Many of the hassles of JavaScript client coding such as cross-browser compatibility, event handling, asynchronous calls are taken care of by ASP.NET AJAX framework.

So, I have spent a few days coding the control and finally it's out there. I have created a Codeplex project for it so if you are interested just go there and download the control and a Demo Web site.

Now, just a few more words about the extender. First, this is how it looks:

Second, it's extremely easy to use. The extender attaches to an ASP.NET TextBox server control and to an optional button that can open a popup window and an element that samples a selected color in the background. User selects a color by clicking on a colored area. Below is a code example of using an extender on an ASP.NET page.

<asp:TextBox ID="TextBox1" runat="server" 
       Columns="7" MaxLength="7"></asp:TextBox>
  <asp:ImageButton ID="ImageButton1" runat="server" 
       ImageUrl="~/Images/icon_colorpicker.gif" />
  <cdt:ColorPickerExtender ID="cpe" runat="server" 
       TargetControlID="TextBox1"
       SampleControlID="ImageButton1"
       PopupButtonID="ImageButton1" />

Feel free to download the extender from the Codeplex, try it and post any comments or suggestions on the Codeplex project page.

Update 2020

Recently, I've visited the old and now archived CodePlex page for the ColorPickerExtender (https://archive.codeplex.com/?p=cpe) and found out that back in the day Microsoft had included that control on the official ASP.NET site (https://docs.microsoft.com/en-us/aspnet/web-forms/overview/ajax-control-toolkit/colorpicker/using-the-colorpicker-control-extender-cs). What a nice thing! Encouraged by this finding I've decided to resurrect the CPE and port it over to Angular, which is currently my favourite client-side framework. I will be introducing a new project on Git some time at the end of 2020, so stay sharp!

Friday, September 19, 2008

Axialis IconWorkshop™ Lite for VS 2008

It's been a little buzz around this free VS2008 plug-in but it really is true and there is a free version of the Axialis IconWorkshop for VS2008. If you want to download and install it please use the direct link because you won't be able to find this page on the Axialis web site. Though to be honest its functionality is not anyhow better then Paint.Net which is also free but fully-functional. Besides being called a VS plug-in it opens up in a separate window. But see for yourself.

Monday, September 15, 2008

Working with VEColor class of VirtualEarth SDK

If you ever wanted to set a color for a custom VEShape object of type polyline or polygon than you must be familiar with the VEColor class that is used to represent a color in VirtualEarth SDK.

I am sure there are reasons behind of the design of the VEColor class, but for those who are used to a standard Web color representation in a form of 6-digit hexadecimal number it's kind of weird to provide 3 integer number in order to construct a color.

So I was in a search for some convenient ways of converting between VEColor and standard Web color and first place I looked through was of course the VirtualEarth Map control because I thought that the VE developers themselves would need a way to perform the same exercise. No surprise there is a couple of non-documented VE objects to support such conversion technique.

Here is a code example of using those objects:

// Create a convertor class
var converter = new VEHexStringToColor();
// Converter returns an instance of a VEColor class
// Transparency value is always set to 1.0
var veColor = converter.Convert("aabbcc");
// Adjust transparency value
veColor.A = 0.7;
// Convert VEColor to a string with a leading '#'
var webColor = VEColorToHexString(veColor);alert(webColor);

Both objects are available on the page after you reference a VE Map control v6.1. Of course there is no guarantee of any support of those objects in any future versions of the VE Map control so use it at your own risk and have fun.

Tuesday, June 17, 2008

Scalable CSS for Ajax Control Toolkit Tabs

If you use Tabs control from AJAX Control Toolkit library you may have noticed that the default CSS definition provided with the control does not display properly when you increase font size on a page, that is the default CSS is not scalable.

Since Tabs allows you to override CSS it's quite easy to fix a problem. Just grab a correct CSS file with the set of images and assign a CssClass property a new class name:

<ajaxToolkit:TabContainer runat="server" CssClass="myTabs" ...>

Now it looks more appropriate:

Friday, May 30, 2008

Access DataItem declaratively using data binding syntax

Sometimes there is a need to access a DataItem object of a data-bound server control. It usually happens when you want to display the value of the bound object as a whole instead of its property.

Standard data binding syntax assumes using a Bind(string name) or Eval(string name) methods in the context of data binding expression where name is a name of a property of the DataItem object. But what if the data item if of type that does not have properties like System.String for examples?

In this case there is another method that you can use: GetDataItem(). It will return to you the current instance of the DataItem object that you can use.

Syntax example:

<%# GetDataItem() %>

That sort of syntax can be used even for DataSource properties in complex nested databound template controls.

Last-Modified HTTP header on ASP.NET page

"Last-Modified" HTTP header is an important part of every web page since it helps browsers to cache pages' content locally and thus save HTML traffic. It is also used by internet search engines in order to determine the relevance of the pages' content and thus improves pages' indexing.

By default, a standard ASP.NET page does not include a "Last-Modified" header in the output HTML. One of the possible explanation for such behavior is that an ASPX page is considered dynamic by nature meaning that its content might be updated every time the page is requested. It is true in many cases for data-driven and interactive pages but most of the dynamic web sites also contain pages that are updated relatively rare or static.

So, when does it make sense to add a "Last-Modified" header to the page? First candidates usually are data-driven pages that display information from some sort of content storage systems (databases, files, etc.) and that information changes but not very frequently so there is a possibility that the same content may be viewed many times. Other apparent candidates are static pages even if they are data-driven but their content does not change for the lifetime.

What are the pages that do not need the "Last-Modified" header? Obvious candidates are interactive pages and pages that displays user session related data.

ASP.NET provides two methods to set the "Last-Modified" header on the page. Both of them belong to the HttpCachePolicy class and are accessible through the Cache property of the Response object:


	Response.Cache.SetLastModified(DateTime date);
	Response.Cache.SetLastModifiedFromFileDependencies();
The first method takes a DateTime parameter that allows you to apply some algorithm for calculating the Last-Modified date of the page, for instance based on information from a database. The second method will calculate the date stamp automatically based for instance on the assembly build date. For the second method you can also include additional file dependencies in date calculation using

	Response.AddFileDependancy(string filename);
For instance if a page displays a content of a static XML file you could include that XML file in the dependency and the "Last-Modified" header's value would be updated based on that file's "Date Modified" attribute.

Friday, May 23, 2008

ScriptManager vs. ToolkitScriptManager

Introduction

ScriptManager is a special ASP.NET server control that should be placed on a page before you can use any of AJAX.NET enabled controls. The same rule is true for the AJAX Control Toolkit controls: they all require a ScriptManager on the page. While AJAX Control Toolkit controls work perfectly fine with the standard ASP.NET ScritpManager the Toolkit includes its own version of the ScriptManager called ToolkitScriptManager that inherits from ScriptManager and is meant to improve some of the ScriptManager's behaviors in particular how it renders out behavior JS scripts. Let's examine how using a ToolkitScriptManager changes a web page's appearance.

Experiment

As a testing example I have created a very simple page consisting of a single Accordion control from the AJAX Control Toolkit library.

<head runat="server">
    <title>Untitled Page</title>
    <style type="text/css">
        .accHead { border:1px solid #445566;font-size:larger;background-color:#aaa;}
        .accHeadSel { border:1px solid #445566;font-size:larger;background-color:#444;color:#fff;}
        .accCont { border:1px solid #ccc;padding:5px;}
    </style>
</head>
<body>
    <form id="form1" runat="server">
    <ajax:ToolkitScriptManager ID="tsm" runat="server"></ajax:ToolkitScriptManager>
    <%-- <asp:ScriptManager ID="sm" runat="server"></asp:ScriptManager>--%>
    <div>
<ajax:Accordion
    ID="MyAccordion"
    runat="Server"
    SelectedIndex="0"
    HeaderCssClass="accHead"
    HeaderSelectedCssClass="accHeadSel"
    ContentCssClass="accCont"
    AutoSize="None"
    FadeTransitions="true"
    TransitionDuration="250"
    FramesPerSecond="40"
    RequireOpenedPane="false"
    SuppressHeaderPostbacks="true">
    <Panes>
        <ajax:AccordionPane ID="AccordionPane1" runat="server"
            HeaderCssClass="accHead"
            ContentCssClass="accCont">
            <Header>Pane Header 1</Header>
            <Content>Content 1</Content>
        </ajax:AccordionPane>        
        <ajax:AccordionPane ID="AccordionPane2" runat="server"
            HeaderCssClass="accHead"
            ContentCssClass="accCont">
            <Header>Pane Header 2</Header>
            <Content>Content 2</Content>
        </ajax:AccordionPane>        
        <ajax:AccordionPane ID="AccordionPane3" runat="server"
            HeaderCssClass="accHead"
            ContentCssClass="accCont">
            <Header>Pane Header 3</Header>
            <Content>Content 3</Content>
        </ajax:AccordionPane>        
    </Panes>            
    <HeaderTemplate>List of Panes</HeaderTemplate>
    <ContentTemplate></ContentTemplate>
</ajax:Accordion>
    </div>
    </form>
</body>

You may have noticed that right after the form tag there are ScriptManager (SM) control and ToolkitScriptManager (TSM) control on the page but one of them is commented out. Next I run a page from VS 2008 two times: first using the SM and second using TSM, and compare the results.

HTML output and traffic

Let's compare the HTML output of two page versions. See a WinMerge screen shot below that shows the SM version in the left pane and the TSM version in the right pane.

First difference you see is that TSM adds its own hidden field on the page (top right pane) and the next and more important difference is that TSM renders one script reference on the page instead of the five ones that SM does.

Now if we examine the page's traffic with the FireBug we'll see how that changes the traffic: first graph refers to the page using the SM control and the second one when the TSM's at work.

Analyzing the graphs it's easy to see that the TSM does reduce a number of browser's round-trips by combining multiple script references into a single one. This advantage will become more attractive as more AJAX-enabled server controls will be placed on a web page that support script combining. However it is not necessarily true that it will always reduce the page loading time. As you can see when TSM returns a combined script to the page it takes some time to perform a work on the server. Correspondingly the amount of work and consequentially the response time directly depend on the number of scripts to combine (that is a number of AJAX server controls) and the size of the scripts to process (white spaces removal and compressing).

So there is no single recommendation that it's always preferable to use TSM instead of SM. In many cases SM version of a page may work faster then a TSM version of the page. Since it's not that difficult to alter a page for both cases I'd advise to test and compare both versions in your particular scenario before making a decision which one to choose.

Thursday, May 22, 2008

ToolkitScriptManager and Web Deployment Project

Problem description
If you use AJAX Control Toolkit in your project you probably use ToolkitScriptManager from the Toolkit instead of standard ASP.NET ScriptManager class. Now if you want to deploy your web application using Web Deployment Project (WDP) for VS2008 then you will find out very quickly that your AJAX enabled application features don't work. The reason for that is there is a JavaScript error on a page saying that the root JavaScript object for AJAX Control Toolkit is not defined on the page and all the subsequent scripts relying on that object have failed. I am not reproducing the exact message here because it may vary in different situations.

Background
You have tested your web application many times in your Dev environments and everything worked just fine. So what you've changed is you used a Web Deployment Project to build and deploy your web application and you presumably wanted to take advantage of a famous precompile and merge feature of the WDP.

Explanation
Now the problem is that the missing JavaScript on the page is rendered by a ToolkitScriptManager object that generate a link to a JavaScript code using a ScriptResource handler which is in its turn supposed to retrieve the code embedded into assembly. Because WDP changes the names and locations of the assemblies ToolitScriptManager was unable to resolve the assembly name and could not generate the link so your page does not have that JavaScript reference any more.

Workaround
Use standard ASP.NET ScriptManager instead of ToolkitScriptManager and everything will work again.

What's next?
I am in a process of investigating whether a ToolkitScriptManager brings any advantages comparing to a new ScriptManager 3.5 in terms of more efficient HTML rendering and will post here my findings as soon as possible.

Also if you are interested in employing a ToolkitScriptManager together with the Web Deployment Project I invite you to vote for this bug on Codeplex.

#if DEBUG in ASP.NET 2.0 code behind

If you use an ASP.NET web site in your solution (another alternative is WAP - web application project) you may have noticed that there is no more compiler options in Configuration Manager that would have allowed you to add compiler constants like DEBUG. So the question pops up whether it's still possible to use very convenient way of excluding debug code from the production version by using #if preprocessor directive. Luckily it turns out that it's still supported and now it's related to a value of a "debug" attribute of a "compilation" element of the Web.config file. If you surround a part of your code with

#if DEBUG
...
#endif

it will be included when debug="true" and excluded when debug="false".

Tuesday, May 6, 2008

Upgrading your WCSF solution from June 2007 release to Feb 2008 release

You need to start from reading the original WCSF Wiki post describing how to perform an upgrade from the previous June 2007 release to the latest Feb 2008 release. In a nutshell there are a few steps that you will need to do:
  1. Install .NET Framework 3.5
  2. Remove WCSF June 2007 release
  3. Upgrade your Guidance Automation software from any earlier release to the Feb 2008 for VS 2008 release
  4. Install WCSF Feb 2008 release
  5. Load your solution in VS2008 and make all the necessary changes.
That's a plan. Most if those steps are straight-forward and don't require additional explanations especially with the help of the original WCSF upgrade instructions. However there are a few tricky moments I'd like to focus on.
  1. When you remove the older Guidance Automation remember the following two rules:
    • First remove all the Guidance Automation packages installed on your machine;
    • Remove first the Guidance Automation Toolkit for VS and then remove Guidance Automation Extensions.
    If you happened to see an exception saying that some Guidance Automation Packages are still not removed while trying to uninstall the Guidance Automation Extensions you need to remove references to those packages first in order to be able to successfully uninstall Guidance Automation Extensions. Go to the Documents and Settings\..\Application Data\Microsoft\Recipe Framework folder and find a RecipeFramework*.xml file. Open it with a text editor and remove the content between GuidancePackages open and closing tags. Now you'll be able to uninstall Guidance Automation Extensions.
  2. After you installed WCSF Feb 2008 you'll need to enable it for your solution. It's done through the Visual Studio Guidance Automation Manager plug-in. The only thing that I'd recommend is to change a content of a vwd.webinfo file in the root fo your web site first because it differs for WCSF Feb 2008 comparing to WCSF July 2007. Make sure that the content of the vwd.webinfo looks like it's described here.
  3. Now you're ready to modify your code and here are the list of mandatory changes that you'll need to do in order to make your application working:
    • Remove the references to the previous WCSF assemblies from all your projects (basically they are foundation modules, business modules and web sites) and add the references to the WCSF Feb 2008 assemblies. Pay attention that there is no more such an assembly as Microsoft.Practices.ObjectBuilder.WCSFExtensions as it is merged into Microsoft.Practices.CompositeWeb.ObjectBuilder
    • Modify all the [ModuleName]ModuleInitializer.cs files: in the ModuleInitializer Load method, use the concrete class CompositionContainerinstead of ICompositionContainer.
    • Modify all the Pages code behind .cs files: a Presenterproperty now has both getter and setter methods and a setter method pattern is a bit different as shown below:
      [CreateNew]
      public [ViewName]Presenter Presenter
      {
          get { return presenter; }
          set
          {
              if (value == null)
                  throw new ArgumentNullException("value");
      
              presenter = value;
              presenter.View = this;
          }
      }
      And also a page base class now should derive from a WCSF base class as shown below:
      public partial class [Module]_[View] : 
      	Microsoft.Practices.CompositeWeb.Web.UI.Page, I[View]
    • Optionally if you used a solution from WCSF_Contrib project for User controls then you'll have to alter those controls the same way as your pages.
So that's basically all. It does not look hard and should not take much of your time. But if you happened to have troubles feel free to post a comment here and I'll try to answer.

Thursday, May 1, 2008

Adding a Web Site to a WCSF solution

WCSF stands for Web Client Software Factory

Whether you are adding a new Web Site to an existing WCSF solution or trying to enable WCSF for an existing solution make sure that a "vwd.webinfo" file is located in the root of a Web Site folder. The Web Site won't be recognized by WCSF's recipes unless there is a "vwd.webinfo". If you already have a Web Site in your solution just copy the file to the root folder of a new web site. If you can't find the file just create the one. Here is how its content should look like:

<?xml version="1.0" encoding="UTF-8"?>
<visualwebdeveloper>
 <globals>
      <userproperties iswebproject="true">
 </globals>
</visualwebdeveloper>

Thursday, April 3, 2008

View State: do not forget to manage!

View State is an essential part of ASP.NET and not paying proper attention to how it's set up in your web application can give you some surprises sometimes not very pleasant ones. For those who wants to refresh their memory about ASP.NET View State I recommend to start from this good article by Dino Esposito. The article is not very new but it's still relevant and it covers many topics that are actual for today's ASP.NET programming.

So now as the background is covered I would like to focus on two main aspects that have to be considered in regards to the View State: performance and security.

What is it to consider performance-wise in regards to the View State? In a nutshell as larger the View State as larger a browser payload as more time is required to process the page on both server and client side meaning worse user experience.

What does the View State have to do with security? As the View State is publicly exposed to a web browser and contains internal data of the ASP.NET page and user controls there is always a risk that its content can be altered and data compromised that could lead to some unexpected behavior of a web application.

So is it inefficient and dangerous to use the View State in your application? Answer is NO: the View State is extremely useful and sometimes absolutely essential for the ASP.NET web application to work properly but don't assume that the default View State settings and behavior are always the best choice for you: always manage them consciously.

Is there best practice about the View State? Of course and there are some of them.

  1. Always explicitly turn off the View State for any control that does not require it to operate. Examples are: Label control, Literal control, Image control, HyperLink control, etc.
  2. If your page does not perform a post back and there is no complex data binding there is a good chance that you can turn off the View State for the entire page in the @Page directive. If you doubt simply try and see how the page works with the View Stated turned off.
  3. If you use complex template based server controls like Login control or CreateUserWizard control, for instance, convert them to templates and check out that the View State of all the child controls is properly managed (always look for Labels and Literals).
  4. When optimizing your ASP.NET application use some third-party browser-based tools to analyze page's View State content and reduce its size as much as possible.
  5. If you use a client-side View State always encrypt it.
  6. Consider moving the View State to a server side: besides security benefit of not exposing the View State publicly and reduced http payload the View State is processed faster on the server. Be aware about server memory consumption when using the View State on the server side. It's much easier to implement the server-side View State in ASP.NET 2.0 then it was with ASP.NET 1.1. Look at the example here.

That's mostly it. Follow the best practices above and feel confident about having your web application's View State managed properly.

Ensure Default Values in ASP.NET Server Controls

Many of ASP.NET server controls base their internal HTML rendering algorithms on the values of their properties. Developers are mostly aware of those properties (not always about their roles in the internal rendering process though) but don't always realize the importance of the default values.

From my experience there is a common assumption that if a property appears empty in the Visual Studio property window that means the default value is empty. Not always true and can be harmful for the output HTML content! Luckily there is always a way to ensure the default values of the properties in ASP.NET markup (.aspx, .ascx). Here are a few examples.

SiteMapPath server control

It has a string property SkipLinkText that by default appears empty in the property window. But in reality if it's not set it's populated from the embedded resource string. That effectively leads to a difference in HTML rendering that does render an <img> tag inside the breadcrumb path with the height and width attributes set to 0 (don't ask me why!).

Some browsers react inadequately on such the HTML if some CSS styling applied to the breadcrumb content. For instance IE6 does not honor a line-height attribute if there is an in line image inside the paragraph.

So to ensure that unnecessary HTML is not rendered in this case always use SkipLinkText="".

ValidationSummary server control

It has a string property ForeColor that defines the color of the text appearing in the control and is prepopulated with the Redvalue. Having a value in this property effectively leads to the control rendering out an inline styling "color:Red;". But if you want to define a text color in the CSS class that you apply to the control you have to explicitly set this property to empty value ForeColor="" otherwise it will always render out the inline styling which will effectively override your CSS settings.

CreateUserWizard server control

This is quite a complex and sophisticated template-based control that comes with ASP.NET Membership framework. From the first sight you assume some degree of intelligence built into the control based on its complexity. For instance, that it does validate user input and render error messages if something is wrong. And it's true except that it does not validate e-mail address string against a regular expression unless a property EmailRegularExpression is set to a proper value and it is not by default. Also it does not provide a developer with such an expression even though it is built into a standard RegularExpressionValidator control.

So be careful and don't forget to set this property EmailRegularExpression="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*" otherwise you will be surprised that a user can enter some garbage into the e-mail field and is not stopped doing that.

So above there are just some examples illustrating an importance of paying attention to such details as default values of the server controls' properties. I am sure you can find more examples based on your own experience.

Using .skin File

Also there is another more efficient way to ensure that the critical default values are properly set across a web application: just add all the default values that you want to ensure to your default .skin file. For example, for above mentioned controls add the following lines there:

<asp:SiteMapPath runat="server" SkipLinkText="" />
<asp:ValidationSummary runat="server" ForeColor="" />
<asp:CreateUserWizard runat="server" EmailRegularExpression="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*" />

Friday, February 29, 2008

Wednesday, February 27, 2008

Dynamic Rendering of META Description HTML tag

For today's search engine optimized web sites having relevant content of the META Description HTML tag on a page is a must. It plays a significant role together with the page title in determining a page relevance ranking in regards to search keywords.

So it becomes necessary to generate a content of the META Description dynamically based on a page content. ASP.NET already provides an easy access to the page TITLE tag allowing to populate it with relevant text simply using a Page.Title property.

Unfortunately it's not the same easy and obvious how to access the META Description from the server-side code.

Luckily ASP.NET is flexible enough and the solution is easy. Simply add a META tag to your page and turn it into a server tag by adding an id and a runat="server" attributes like the following:

<meta name="description" content="your description" runat="server" id="Description" />

Immediately you'll be able to access the content from the code behind by using a Description.Content property.

The explanation is very simple, actually. When ASP.NET parses the mark-up it creates an HtmlMeta server control with the name "Description" that has a Content property of a string type. And, of course, you can employ the same technique if you want to manipulate with other META tags on the page. Just use the proper value of a "name" attribute.