Friday, June 29, 2007

Today while I was working on my usual solution inside Visual Studio I have encountered a serious problem with how Visual Studio, SourceSafe and Web Site projects interact. My solution that I was working with consists of several projects including few Web Sites. My environment is configured to use SourceSafe database as a version control system. Nothing unusual - a 100% Microsoft only environment. I had been working like this without any changes to the configuration for a long time but I noticed that no matter what I do, my solution file (.suo) is growing larger and larger...

Since .suo (solution user options) files only contain information about my options e.g.: opened files, break points etc I thought that it will not hurt much if I just delete this file. I didn't care about opened files nor the location of breakpoints. Besides, sometimes deleting the .suo file is just the only option to restore Visual Studio to a working state after it refuses to open a project file. On top of this, I have deleted the .suo file many times before without any negative effect. So I did again, but this time I was hit right between the eyes and I'm still recovering from the blow.

After deleting the file and starting the solution I got the following message:

"The Open from Source Control operation is still in progress but you can start working now. The rest of the projects will be retrieved asynchronously."

I thought, oh... OK, the message was not a warning and there are a lot of useless messages in Visual Studio so there is no need to worry. I was WRONG, but it came out some time later.

Everything opened correctly and it even seamed to work, but the pages looked different from what I was expecting. They looked exactly the same way as before I made my last changes that I didn't commit before the deletion of .suo file.

After a bit of investigating and testing I have found the problem. And the problem that is! It appears that if you have a file checked out inside of the Web Site project than the fact it is checked out is somehow remembered inside the .suo file. If you delete a .suo file then Visual Studio will try to be "smart" and will get the latest version of that file from the source control - SourceSafe in this case. What this means of course is that any changes in the checked out file will be lost WITHOUT ANY chance to stop and WITHOUT ANY warning message!!!

This issue is only a problem for Web Site projects. Other project types like Class Library are not affected. Now the questions are obvious: why Visual Studio is using .suo files to keep tract of what is checked in and what is checked out inside Web Site projects? Are .scc and .vspscc files not enough? Why would it even try to get the latest version? Is the fact that the file on the disk is not Read Only and is different from the version in the Source Safe not enough to at least issue a warring/question?

In my opinion it is obviously a bug and it has just caused me to lose half a day of work!

Friday, June 29, 2007 1:52:19 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [1]  | 
 Monday, June 25, 2007

Almost every time I'm working on an ASP.NET project I create a Visual Studio solution that consists of at least two projects: the web project and a class library. The first one is obviously needed. As for the second, what I put there include all kinds of ASP.NET related classes such as the BasePage class or just custom controls. This makes it easy to use those controls since Visual Studio (usually) automatically adds them to the Toolbox.

There are times however, when I need to make something quick. Perhaps a small project to test a new idea. In those cases, I rarely go for the 2+ projects solution layout since Visual Studio is standing in my way a bit - i.e. by hiding the possibility of adding new project to an already existing Web Site project (solution node is not visible on the tree view in Solution Explorer, but it is still possible to add the project using File menu). So I end up with only one project and the App_Code folder.

Working with App_Code is not a problem as long as you don't need to make some configuration in the Web.config file. Some elements require you to specify a type name. Normally in such a case, you need to provide a valid type format name in a form of <typename>,<assemblyname>. As long as you know the assembly name it's OK, but wait! There is no explicit assembly for App_Code. There is however an assembly behind the App_Code directory. It is simply called App_Code!

That said, it is usually enough to just specify the type name, without assembly name, for types defined in the App_Code directory.

So what about controls? In order to work with a control defined in App_Code directory we need to either register it on a page or in a Web.config file. There is however one issue. In order to register a control in a Web.config we need a namespace. By default however, neither pages nor classes added to an App_Code folder have a namespace. This is only a minor inconvenience because ASP.NET does not prevent us from adding a missing namespace declaration to a class in an App_Code directory. By adding such a namespace to a class representing ASP.NET Control, we can then add a registration in a Web.config file like the following one:

<pages>
  <controls>
    <add namespace="MyControls" tagPrefix="m"/>
  </controls>
</pages>

Notice that assembly attribute is not required.

For working with code, there is also a special class that helps with issues arising from the fact that there is no explicitly assembly nor a namespace for types in an App_Code directory. If at any time, there is a need to work with a type object of a class from the mentioned directory, .NET framework offers us a class called BuildManager which defines a GetType. Using this method it is possible to get an instance of a type object by providing just a name of a class defined in the App_Code directory.

kick it on DotNetKicks.com

Monday, June 25, 2007 6:17:51 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
 Wednesday, June 20, 2007

After reading my article on recursive properties of ASP.NET controls, where I point out that not all properties are recursive, I have decided to fix one annoying behavior. The problem is that one of the most important property of all, the EnableViewState property is not recursive. This of course makes it useless in most scenarios. Never will we be able to rely on it while authoring our controls since ViewState can be disabled on any of the parent controls thus preventing our control from saving its state.

To solve this a very simple method can be used to check for the state of EnableViewState property:

public bool IsViewStateEnabled(Control control)
{
    if (control.Parent == null)
    {
        return control.EnableViewState;
    }
    return control.EnableViewState && 
        IsViewStateEnabled(control.Parent);
}
Wednesday, June 20, 2007 7:44:05 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
 Tuesday, June 19, 2007

ASP.NET, or more accurately Web Forms, offer us a completely new way to create web pages. We can now work with control just like Windows developers. We even get to use an event driven model. How make best use of this? Below I present a useful pattern that I'm almost always following while working with ASP.NET.

Suppose that you are building a web application with lots of pages and forms for data input. On those forms you typically have input fields in form of TextBoxes, DropDownLists etc. Usually there are also some buttons that allow for invoking actions. Those actions include things like "Add", "Update" or "Cancel".

The standard way to create a form for inputing data would be to use mentioned before standard ASP.NET controls. That is fine. It gives us access to all that ASP.NET Web Forms can offer in terms of Page structure and event model. There is however one issue. In most cases there we will be several pages with the same buttons on them. Take for example the "Cancel", "Add" or "Update" buttons. Almost every time there is a data to be edited, there will be those buttons. If we use the "out of the box" approach, we end up with code similar to the following, on lots of pages:

<asp:Button ID="Add" runat="server" Text="Add" />

At first glance, there is not much wrong with it. If you look closer however, we can see the potential problems. One of the is certainly the Text property.

Why is it a problem? Suppose that now we need to localize the application? In this case, we will have to make a change in many places. Simple technique would be to decorate the Button control with attributes used by the Localization feature of ASP.NET like meta:resourcekey. But still we end up with one major problem: every time a change is required (that cannot be dealt with using Localization, Skins or other built in feature), we have to make it in many places. As we know: change in many places is a BAD PRACTICE.

What if we find out, that our add buttons need to have some special CssClass attribute? What if all our "Cancel" Buttons should have CausesValidation property set to false? Once again: a change is required in many places - which is ... BAD PRACTICE!

For localization, we can add an implicit localization attributes as mentioned above. What about CausesValidation or CssClass properties? Some of them we can try to set using Skin files, but as you will sooner or later discover, theming support in ASP.NET is VERY limited, especially when it comes to localization. You cannot localize skin files, some of the properties are not themeable etc. There are many examples of potential problems but what is a solution? It seams that there has to be a better way.

In my practice I have found that it is usually good not to use the standard controls that come with ASP.NET but rather make new ones that directly inherit from them. Doing so we inherit all the functionality without loosing anything (almost). As an example, take the aforementioned "Cancel" button. If we create a new control like this:

public class CancelButton : Button
{
    protected override void OnInit(EventArgs e)
    {
        Text = "Cancel"; // get value from resource
        CausesValidation = false;
        base.OnInit(e);
    }
}

And on pages, instead of the standard button, use this new control:

<my:CancelButton ID="Add" runat="server" />

In doing we allow ourselves to make changes in one place that will affect the whole application. In this way, without much work, we have gained a lot of flexibility for the future and saved a lot of potential work. If some time in the future, we need to localize the Text property for all Cancel buttons, we can do it in just one place which is a GOOD PRACTICE.

Benefits do not end there! If some day, there is a requirement, that all buttons should now be LinkButtons instead of normal Buttons we can easily do it bu just changing the base class from which our CancelButton inherits and the same technique can be used with other controls too (as long as their public interfaces match at least in naming).

Now the question is if you should always use the inherited controls. As usual, there is no simple answer to that question. There is a cost of having a lots of additional classes in the project if we try to follow this rule. Imagine that just for standard buttons, there will be quite a few: Add, Cancel, Remove, Back, Change, Edit just to mention some of them. For small, fast'n'dirty projects it will of course be a huge overkill (or will it?), but if you know that the project is not a small task, it is, in my opinion, a thing that should be seriously considered.

kick it on DotNetKicks.com

Tuesday, June 19, 2007 8:32:37 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [4]  | 

I'm a big ASP.NET lover mostly because of the fact that I can work with HTML in a more abstract way presented to me in form of controls. While authoring controls, it is always my goal to write as little HTML code as possible. To make it possible I relay heavily on composite controls. Sometimes however it is not possible or simply to complex to achieve a result using a composition of controls. That's where the Render method comes in handy.

Using Render method and accompanying HtmlTextWriter object we can write plain HTML using writer.Write() method. This however forces us to write HTML which I try to avoid. Here also the  HtmlTextWriter offers some alternatives that include writer.RenderBeginTag() method and HtmlTextWriterTag enumeration. Using them, we can generate HTML in a way that allows for some degree of compile time checking and some enhancements. If we just used the following code:

writer.RenderBeginTag("h1");

there is little that protects us from misspelling the tag name. There is also no way for a RenderBeginTag method to help us adjust the output to target concrete platform. We are simply telling it to write "h1" element and so it does because we expect it to. Consider however an alternative version:

writer.RenderBeginTag(HtmlTextWriterTag.H1);

This time, instead of passing "h1" string literal, we pass a value of a HtmlTextWriterTag enumeration. Now we are suggesting that we need the H1 element, but we leave a space for interpretation. What the writer object renders is up to it. Keep in mind however that HtmlTextWriter class and moreover the XhtmlTextWriter class are there to allow for customization. If there is a device that requires all tags to be uppercase, than it can be done using a special writer object that knows and targets the concrete device.

One thing that I only recently discovered however is how to write a "<br />" without writing "<br />". If we try to use the mentioned overload like this:

writer.RenderBeginTag(HtmlTextWriterTag.Br);
writer.RenderEndTag();

We will get an invalid HTML:

<br>

</br>

The solution is to use the writer.WriteBreak() method. It will output the required form of "<br />" and shield us from using plain text.

You may ask if it really matters. True, it is a very thin line of abstraction here but I like it this way.

kick it on DotNetKicks.com

Tuesday, June 19, 2007 7:22:24 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
 Monday, June 18, 2007

With the release of .NET Framework 2.0, we have gained access to a very powerful feature called Anonymous Methods. I'm sure that almost any .NET developer has used Anonymous Method at least once and most of us use them on a daily basis.

Typically you use Anonymous Methods when you want to declare an event handler inline, without the need of creating a separate, named method (hence the name Anonymous). Other usage areas include delegates of types such As Predicate or Action. Mentioned delegates are most often used in methods found on all types of collection related classes be it Array or List<T>. Typical code for this may look like this:

string[] urls = GetUrls();
string[] urlWithWww;
urlWithWww = Array.FindAll(urls, delegate(string url) 
{ return url.StartsWith("www"); });

Nothing unusual here. The usefulness of Anonymous Methods comes from the fact that they allow us to access variables defined in the scope in which the very method is defined. Here as an example of how this feature is usually used:

string pattern = ".com";
string[] urls = GetUrls();
string[] urlWithWww;
urlWithWww = Array.FindAll(urls, delegate(string url) 
{ return url.Contains(pattern); });

Great feature indeed, but there is one gotcha that we have to be aware. The problem most often appears when we start to work with multiple threads. Given the following code:

foreach (string url in urls)
{
    DoSomethingAsync(delegate() 
    { 
        Debug.WriteLine(url); 
    });
}

We have to know that the url variable that we pass to a Debug.WriteLine method is "shared" among all Anonymous Methods and because of this, we may (and most probably we will) get results that we do not expect: same url printed few times, than a different url, again printed few times. Confusing, isn't it?

Why is that? Brad Adams explains the mechanism behind this strange behavior here (scroll down to the comments). It's worth mentioning that you could get the same strange behavior without working with multiple threads. It is just far more common to get it while theading.

To make things more "predictable", the code above has to be written in a slightly different way:

for (int i = 0; i < urls.Length; i++)
{
    string url = urls[i];
    DoSomething(delegate() 
    { 
        Debug.WriteLine(url); 
    });
}

Now every Anonymous Method gets its own copy of url and everything works as expected.

kick it on DotNetKicks.com

Monday, June 18, 2007 6:39:58 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 

While working with ASP.NET, from time to time, I need to change some parameter that is common to all controls of on a page. An example of such operation might be setting ReadOnly property for all TextBox controls etc.

Below is a sample method code I use to get a flattened hierarchy of controls on a page:

public static Control[] FlattenHierachy(Control root)
{
    List<Control> list = new List<Control>();
    list.Add(root);
    if (root.HasControls())
    {
        foreach (Control control in root.Controls)
        {
            list.AddRange(FlattenHierachy(control));
        }
    }
    return list.ToArray();
}

As you can see, it is pretty simple. The method recursively traverses control hierarchy and collects each control it finds on its way to a collection which is finally returned to the caller in a form of an array.

As mentioned above we can use this method to set the ReadOnly property of all TextBox-es on the page. To do this, a code similar to the one below can be used:

private void MakeTextBoxesReadOnly()
{
    Control[] allControls = FlattenHierachy(Page);
    foreach (Control control in allControls)
    {
        TextBox textBox = control as TextBox;
        if (textBox != null)
        {
            textBox.ReadOnly = true;
        }
    }
}

Using a combination of the above outlined methods it is easy to implement a kind of ReadOnlyMode page filter. Just identify what controls need to be ReadOnly and how to make them so (RadioButton for example doesn't have a ReadOnly property). When you know how and what you want to make ReadOnly, just override Page's OnPreRender method by adding a call a MakeTextBoxesReadOnly method (or whatever method you create).

Of course all of this is possible thanks to the great ASP.NET control model which is one of the things that I really like about ASP.NET.

kick it on DotNetKicks.com

Monday, June 18, 2007 11:07:38 AM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [3]  | 
 Saturday, June 16, 2007

Today, while working with WebRequest (HttpWebRequest) class and its BeginGetResponse method I have discovered a strange behavior. It turns out that you cannot always relay on the IAsyncResult's AsyncWaitHandler's WaitOne method as I will try to show below.

The following is a more or less a standard way to work with an asynchronous web requests (code is simplified, all constructs such as using and try/catch and timeout handling have been omitted for simplicity reason):

class RequestState
{
    public RequestState(CompleteDelegate callback, WebRequest request)
    {
        Callback = callback;
        Request = request;
    }
    public CompleteDelegate Callback;
    public WebRequest Request;
}
private static WaitHandle MakeAsyncRequest(CompleteDelegate callback)
{
    WebRequest request = WebRequest.Create("http://vaultofthoughts.net");
    RequestState state = new RequestState(callback, request);
    IAsyncResult result = request.BeginGetResponse(GetResponseComplete, state);
    return result.AsyncWaitHandle;
}
private static void GetResponseComplete(IAsyncResult result)
{
    RequestState state = (RequestState)result.AsyncState;
    WebResponse response = state.Request.EndGetResponse(result);
    state.Callback();
}

Now we can invoke MakeAsyncRequest method from anywhere in our code passing a delegate that will be called upon request completion. We get a WaitHandle as a return value so we can synchronize threads in case multiple calls were made.

Where is the problem? Look at the following code:

private void MakeCalls()
{
    WaitHandle[] waitHandles = new WaitHandle[2];
    waitHandles[0] = MakeAsyncRequest(RequestComplete);
    waitHandles[1] = MakeAsyncRequest(RequestComplete);
    // Wait until both requests complete
    WaitHandle.WaitAll(waitHandles);   
}
private void RequestComplete()
{
    //....
}

The problem is that there is no guarantee that RequestComplete method will be called 2 times before code continues beyond the WaitHandle.WaitAll call. Why is that?

At first I thought it was a bug in how .NET threads work, but a while I have come to the understanding that it is the way it should be. The WaitHandles returned from the MakeAsyncRequest method are signaled as soon as the request completes. After request completes the GetResponseComplete method is called. At this time, WaitHandle is signaled. Only at the end of the GetResponseComplete method, the callback is called (it could even be called as the first action and it wouldn't make much difference).

So how to solve the issue? The solution is to return new instance of ManualResetEvent instead of IAsyncResult.AsyncWaitHandle. We also have to pass an instance of this object with rest of the state to GetResponseComplete method so we can signal it at the end, after the callback method is called.

A complete solution looks as follows:

class RequestState
{
    public RequestState(CompleteDelegate callback, 
WebRequest request, ManualResetEvent waitHandle) { Callback = callback; Request = request; WaitHandle = waitHandle; } public CompleteDelegate Callback; public WebRequest Request; public ManualResetEvent WaitHandle; } private static WaitHandle MakeAsyncRequest(CompleteDelegate callback) { WebRequest request = WebRequest.Create("http://vaultofthoughts.net"); ManualResetEvent waitHandle = new ManualResetEvent(false); RequestState state = new RequestState(callback, request, waitHandle); IAsyncResult result = request.BeginGetResponse(GetResponseComplete, state); return waitHandle; } private static void GetResponseComplete(IAsyncResult result) { RequestState state = (RequestState)result.AsyncState; WebResponse response = state.Request.EndGetResponse(result); state.Callback(); state.WaitHandle.Set(); }

I have marked the changed parts in the code above. Notice that we don't have to change the code that is using our method.

kick it on DotNetKicks.com

Saturday, June 16, 2007 6:58:09 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
 Friday, June 15, 2007

Today I was working with System.Uri class a bit and I must say that it is very useful. Just imagine checking if a given URL is absolute or getting the host name from URL or even getting the query part. All of this is implemented in this one class by means of properties like IsAbsoluteUri, Host, Query etc. There is however one problem...

While playing with System.Uri I encountered a situation where while trying to create an Uri object I got the following exception:

System.UriFormatException was unhandled
  Message="Invalid URI: The format of the URI could not be determined."
  Source="System"
  StackTrace:
       at System.Uri.CreateThis(String uri, Boolean dontEscape, UriKind uriKind)
       at System.Uri..ctor(String uriString)

Of course there is nothing wrong with it. Not every string represents an Uri. So, remembering about the pattern found in classes such as Boolean or Int32 I looked for a TryParse method. As it came out, System.Uri doesn't have a TryParse method but there is TryCreate method instead. After changing the code to use TryCreate method and running the application it came out that I still have a problem somewhere.

At first I thought that the problem was the TryCreate method! In all cases where the normal constructor failed for me, the TryCreate method not only returned true, but also constructed a System.Uri object!

The following code demonstrates the issue:

string url = "asdasda";
Uri uri;
if (!Uri.TryCreate(url, UriKind.RelativeOrAbsolute, out uri))
{
}
else
{
    uri = new Uri(url);
}

The above code should run smoothly, but it will throw the mentioned System.UriFormatException. The reason for this is that when using the constructor, we should also use the overload that allows us to pass the UriKind as an argument!

Friday, June 15, 2007 8:11:15 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
 Tuesday, June 12, 2007

Today I've got a question if it is possible to make ASP.NET not to render the div tag around it's special hidden fields (i.e.: "__EVENTTARGET"). I have never thought about it before, so I didn't know the answer. I had to investigate. After a brief overview of the state of things, I have come to believe that there is no easy way to do achieve this. To confirm my suspicions I used the Reflector.

I have found that it is indeed possible to make ASP.NET not render the div tag if RenderDivAroundHiddenInputs property of HtmlTextWriter class returns false or if LegacyRendering is enabled. You can enable the later by setting xhtmlConformance mode to Legacy in Web.config file. Unfortunately the RenderDivAroundHiddenInputs property of HtmlTextWriter class always returns true and you cannot change it because it is internal. Additional investigation has shown that there is a class that overrides that property to return false. The class was: XhtmlTextWriter.

How to make ASP.NET use XhtmlTextWriter instead of normal HtmlTextWriter? I was unable to find a way to configure ASP.NET to do it. Setting xhtmlConformance mode to strict doesn't help. Google also is not very helpful. The only way seams to be either override Render method of a Page class like this:

protected override void Render(HtmlTextWriter writer)
{
    base.Render(new XhtmlTextWriter(writer));
}

Or better yet to override the CreateHtmlTextWriter like this:

protected override HtmlTextWriter CreateHtmlTextWriter(System.IO.TextWriter tw)
{
    return new XhtmlTextWriter(base.CreateHtmlTextWriter(tw));
}

This however requires you to use a kind of BasePage class for each page in your project (which is good, but not everyone likes it). Another concern I have is the fact that there is very little information on XhtmlTextWriter class, and the one that is available seams to suggest that the class is meant rather for mobile devices.

There is one more way you can try to solve the problem. You can use Response.Filter to do the job, but I would not recommend it unless you really, REALLY need to get rid of the div. Creating such a filter can really hurt performance. If you decide you REALLY need to, Mads Kristensen has an example of how to make a filter. He is using Response.Filter to move ViewState to the bottom of the page.

kick it on DotNetKicks.com

Tuesday, June 12, 2007 8:53:08 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [4]  |