Monday, December 11, 2006

Extending the shell to get a .Net 3.0 command prompt

Take this text below. Save it as a DotNetCmd3_0.reg file and then double click on it. Now, on any folder, you can right click and see the ".NET Cmd 3.0" command prompt. You can then use ildasm for instance or xamlpad. This reg file basically saves you from selecting the following "Start/All Programs/Microsoft Windows SDK/Cmd Shell" with the mouse every time you need 3.0.

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\Folder\shell\.NET Cmd 3.0\command]
@="C:\\WINDOWS\\system32\\cmd.exe /E:ON /V:ON /T:0E /K \"C:\\Program Files\\Microsoft SDKs\\Windows\\v6.0\\Bin\\SetEnv.Cmd\""




Cheap Talk? Check out Yahoo! Messenger's low PC-to-Phone call rates.

Friday, October 06, 2006

Solving The Double Post Problem On A Button

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Text;

namespace Developmentor
{
    /// <summary>
    /// C. Fouquet: Oct 2006
    /// This button cannot be clicked more than once during a post.
    /// This solves the classic double post problem where a user clicks
    /// a button more than once quickly and therefore posts twice!
    /// The idea is simple. Disable the button IMMEDIATELY after the click and
    /// THEN post. For that, we need to set a short timer to post very quickly after the
    /// button is disabled and give the illusion that the click is immediate.
    /// </summary>
    public class OneClickButton : Button
    {
        public int DelayInMs
        {
            get
            {
                if (ViewState["DelayInMs"] == null) return 20;
                return (int)ViewState["DelayInMs"];
            }
            set
            {
                ViewState["DelayInMs"] = value;
            }
        }

        protected override void Render(HtmlTextWriter writer)
        {
            string DisableMySelf = "document.getElementById('" + this.ClientID + "').disabled = true;";
            string PostIt = Page.ClientScript.GetPostBackEventReference(this, string.Empty);

            string FunctionName = "DelayedClick" + this.ClientID;
            StringBuilder sb = new StringBuilder();
            sb.Append("<script type=text/javascript >"); sb.Append(Environment.NewLine);
            sb.Append("function "); sb.Append(FunctionName); sb.Append("()"); sb.Append(Environment.NewLine);
            sb.Append("{"); sb.Append(Environment.NewLine);         
            sb.Append(PostIt); sb.Append(";"); sb.Append(Environment.NewLine);
            sb.Append("}"); sb.Append(Environment.NewLine);
            sb.Append("</script>"); sb.Append(Environment.NewLine);
            this.Attributes.Add("onclick", DisableMySelf + ";" + "setTimeout('" + FunctionName + "()',"+ DelayInMs.ToString() + ");return false");           
            writer.Write(sb.ToString()); // Write the javascript FIRST to it is available on click!
            base.Render(writer);           
        }             
    }
}


Saturday, August 05, 2006

One-Liners Getters And Setters For ASP.Net Control Properties


It is a little tiring to repeat the same code when persisting properties in the ViewState.
You basically have to do this for each property. Let assume we have a Count and a Text property.

int Count
{
    get
    {
        if(ViewState["Count"] == null) return 0; // Handle the null case
        return (int) ViewState["Count"]; // Need to cast
    }
    set
    {
        ViewState["Count"] = value;
    }
}

string Text
{
    get
    {
        if(ViewState["Text"] == null) return string.Empty; // Handle the null case
        return (string) ViewState["Text"];// Need to cast
    }
    set
    {
        ViewState["Text"] = value;
    }
}

Each time, you have to handle the case where the slot in ViewState is null and decide on a default value. It gets very boring very quickly. Casting the return value gets tiring too.

In my day job (yes, I have one), we have made our own bases classes for UserControls. This allows us to use some goodies we have made over time that is relevant to our application.

It would be cool to somehow "Factorize" this .... so here it is. We use generics to do the same logic every time.

namespace Developmentor
{
    public class UserControl : System.Web.UI.UserControl
    {
        protected void SetProperty<T>(string Name, T value)
        {
            ViewState[Name] = value;
        }

        protected T GetProperty<T>(string Name, T defaultValue)
        {
            if (ViewState[Name] == null)
            {
                return defaultValue;
            }
            return (T)ViewState[Name];
        }
    }
}

Now use it in an ascx like this. Just change the Inherits to point to your new and improved base. We have gained a little. At least we can do all this in one line now. There is still some typing but it is a little more 'Generic' ;-)


<%@ Control Language="C#" ClassName="simpleControl" Inherits="Developmentor.UserControl" %>

<script runat="server">
    
    string TheProperty
    {
        set
        {
            SetProperty<string>("TheProperty", value);
        }
        get
        {
            return GetProperty<string>("TheProperty", "?");
        }
    }
    protected override void Render(HtmlTextWriter writer)
    {
        writer.Write(TheProperty);
    }
</script>

This has been in my mind for a while. If you think that a brain like mine can't come up with this, well, you are right. I saw this in the Atlas framework using Reflector. Somebody at microsoft is thinking. When can we get this in the System.Web.UI.Control class in the framework? .Net 3.0?


Groups are talking. We´re listening. Check out the handy changes to Yahoo! Groups.

Tuesday, August 01, 2006

Where are ASP.Net 2.0 Property Pages Settings stored?

Right here.

These are hidden folders so you can just type the whole path to get to the file.

C:\Documents and Settings\yourusername\Local Settings\Application Data\Microsoft\WebsiteCache\websites.xml

The settings are saves once you close the IDE.

I tried deleting the file and the IDE recreates it. It can be good to go back to a clean slate.





Groups are talking. We´re listening. Check out the handy changes to Yahoo! Groups.

Sunday, July 30, 2006

Adding A .Net Command Prompt to Explorer context menu

In order to get access to ildasm or the csc (C# compiler) you need to run vsvars32.bat. It would be easier to point to a folder in explorer and right click and see a ".Net Cmd 2003" item and just select it. You can then access all the .Net tools for this version of the framework.

I have a reg file I use to set this up. You can create a reg file with this content and double click on it or set the registry key by hand.

There is a 2003 and 2005 version (both can work at the same time)


---- 2003 / Version Begin Of Reg File
Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\Folder\shell\.NET Cmd 2003\command]
@="cmd.exe /K  \"C:\\Program Files\\Microsoft Visual Studio .NET 2003\\Common7\\Tools\\vsvars32.bat\""

-- End Of RegFile


---- 2005 / Version Begin Of Reg File
Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\Folder\shell\.NET Cmd 2005 Beta 2\command]
@="cmd.exe /K  \"C:\\Program Files\\Microsoft Visual Studio 8\\Common7\\Tools\\vsvars32.bat\""

-- End Of RegFile


See the all-new, redesigned Yahoo.com. Check it out.

Thursday, July 13, 2006

On the light side / Superman

I just saw the new Superman movie. Yes, I was a younger man when I saw the first one. I hesitated going to see this new version. Remakes are usually disappointing.

I was very pleased with this version. The themes are wellknown and the music is still the same good old one. Powerful special effects that do not obscure the story. A good moment.

BTW, Superman's cape is made of whool from France. I know you don't care but I had to brag a little


Sneak preview the all-new Yahoo.com. It's not radically different. Just radically better.

A validated check box in ASP.Net

As you probably know, there is no validator for a check box in ASP.Net. People go through hoops to make this work.

We just want to force the user to check the box before submitting. This is for scenarios like "click to accept agreement etc..."

The solutions I have found were not to my complete liking. So here is my solution to this annoying problem. It is very compact and involves very little javascript. It is a cool little trick. Have fun.


<%@ Control Language="C#" %>
<script runat="server">
    protected override void OnPreRender(EventArgs e)
    {
        base.OnPreRender(e);
        _BoxMirror.Style.Add("display", "none"); // Hide the box. It is just there for the
        // validation logic to work.
        // Now hook up the check box to the text box. The text value mirrors the
        // value of the check box in sync.
        _Box.Attributes["onclick"] = "getElementById('" + _BoxMirror.ClientID + "').value=this.checked";
        _BoxMirror.Text = _Box.Checked.ToString().ToLower(); // Sync text box and check box
        // The validator Initial value is set to "false" so the Text Box will validate when
        // its value is different from "false".
    }
   
</script>

<div runat="server" id="_Wrapper" style="background-color:Yellow">
    <asp:TextBox runat="server" ID="_BoxMirror" />
    <asp:CheckBox runat="server" ID="_Box" />
    <asp:RequiredFieldValidator InitialValue="false"
    runat="server" Text="*" ID="_NeedToBeChecked" ControlToValidate="_BoxMirror" />
</div>


Sneak preview the all-new Yahoo.com. It's not radically different. Just radically better.

Saturday, July 01, 2006

AT&T's Big Brother Policy

Sony puts rootkits on their CD, now AT&T violates basic privacy

http://www.sfgate.com/cgi-bin/article.cgi?f=/c/a/2006/06/21/BUG9VJHB9C1.DTL&hw=at&sn=002&sc=870

Should we just throw our TVs, Phones, Computers and live on a deserted island to keep our
basic rights?

I have had bad experiences with AT&T so this is not surprising




An alternative to Page.RegisterClientScriptBlock

When you make a custom control that requires custom javascript you usually have to make sure that
you output the javascript code once and once only. If you don't, the same javascript is downloaded to the browser and waste bandwith. There are also issues with global variables declared multiple times etc..

ASP.Net provides a Page.RegisterClientScriptBlock that allows you to register a piece of code once and the framework will output it once on the page. This works fine and I have been using it a lot.
The issue with this is that you must generate the javascript in code like this.

protected override void OnInit(EventArgs e)
    {
      string strCode = @"
         "<script language='javascript'>"
        +
        "function ChangeImage(ImageRef)"
        +
        "{"
        +
            "ImageRef.src = 'http://www.google.com/images/firefox/fox1.gif'"
        +
        "}"
        +
        "</script>";

      Page.RegisterClientScriptBlock("SomeUniqueKeyOfYourChoosing",strCode);
    }

This works fine but it would be cool if I could still put this code in the ascx and still make sure it is output
once. The advantage is that it is easier to edit ascx inline than editing the C# code to craft the javascript.

I came up with this simple solution. The idea is this. We need to keep track of the fact that we have or have not output the javascript section already. ViewState is out of the question since it is scoped to each control. SessionState is also out of the question. SessionState should be use sparingly and we should stay away from it if we can. We just need to keep track of the javascript for this page only so we can use the Items collection that lives only for the duration of the request. After we output the page, we do not need to keep count so this is a good solution.

We are half way there. We now need to not output the javascript. Here is the trick. We will wrap the script with a <div> tag with runat="server". Inside the <div> is the javascript code! We just need to control the visibility of the div!

Here is the complete control code. It is just an image that changes when you click on it. We call
a javascript ChangeImage() function in javascript when the image is clicked.

Cool <div> isn't it?

<%@ Control Language="C#" ClassName="SimpleControl" %>
<asp:Image runat="server" ID="_Image" />

<script runat="server">
    void Page_Load(object s, EventArgs e)
    {
        _Image.ImageUrl = "http://www.google.com/images/logo_sm.gif";
    }
    string JavascriptKey
    {
        get
        {
            return this.GetType().FullName + "JS";
        }
    }

    void HandleJavascriptCodeStreaming()
    {
        HttpContext ctx = HttpContext.Current;

        bool? JavascriptAlreadyOutput = (bool?) ctx.Items[JavascriptKey];

        JavascriptCode.Visible = !JavascriptAlreadyOutput.HasValue;
        ctx.Items[JavascriptKey] = true;
    }

    protected override void OnPreRender(EventArgs e)
    {
        base.OnPreRender(e);
        _Image.Attributes["onclick"] = "ChangeImage(this)";

        HandleJavascriptCodeStreaming();
    }
    
</script>

<div runat="server" id="JavascriptCode">
    <!-- We use the Div to Control The Visibility of the javascript code -->

    <script language="javascript">

        function ChangeImage(ImageRef)
        {
            ImageRef.src = "http://www.google.com/images/firefox/fox1.gif"
        }
    </script>

</div>

Tuesday, June 27, 2006

Making Dynamic CSS content with ASP.Net

I had the situation where there was a need to modify a css file on the fly.
It is like the poor man's Theme but it is slightly different.
Let's say you want the H1 background color to be configurable by the user. This
can be achieved via the Profile and by some other means.
For the sake of this demo, I will use the Session state. Let's say I have
a stylesheet like this

H1 { background-color:Red; }

in a file called StyleSheet.css in the application root.

What I want to do is to replace the "Red" with "Blue" for instance according to
some value in the Session. The first naive approach is to read the css in memory and
do a string replace. This is very brittle and just a bad hack. Some may get smarter
and use a regular expression.

The approach I am taking here is the following. We already have something in ASP.Net
that does text substitution! Yep, an aspx page does just that with server side
code injection. So, conceptually what we want is this:

H1 { background-color:<%= ColorManager.Color %> ; }

Where ColorManager is some class we write to get the color from the Session.

As you are aware, css does not support this kind of syntax. Can we just fool the
system to do this? If you are in love with the ASP.Net pipeline, you can....

Step 1 :
We rename StyleSheet.css to StyleSheet.aspx and make a 'page' like this

<%@ Page Language="C#" %> H1 { background-color:<%= ColorManager.Color %>; }

Step 2:
We make ColorManager.cs and put it in App_Code. A static class will do.
For now you can just stub this out like this

public static class ColorManager
{
static public string Color
{
get
{
if (HttpContext.Current.Session["H1COLOR"] == null)
return "red";
return (string)HttpContext.Current.Session["H1COLOR"];
}
set
{
HttpContext.Current.Session["H1COLOR"] = value;
}
}
}

Step 3:
We need to add a link to our dynamic stylesheet from a test page.
The perfect spot to put it is in the <HEAD>.

<head runat="server"> <link rel="stylesheet" href="StyleSheet.aspx" type="text/css" /> </head>

The href is pointing to our StyleSheet.aspx. The browser could not care less about the
address here as long as the type is correctly set to "text/css". The browser will
interpret the web response as a css text (which it is).

Here is the kicker, you can still use Themes with this approach. By using Themes, the
framework will add the css from the Theme directory as <link> in the <HEAD runat="server">
after our own dynamic css.

Here is a test page to tie all this together. Each time you click on the button
the H1 color changes and you can even see the dynamic css by clicking on the "See CSS".

So much power in ASP.Net. The question is how we can take advantage of it.

CF

default.aspx:

<%@ Page Language="C#" AutoEventWireup="true" %>
<script runat="server">
protected void Bt1_Click(object sender, EventArgs e)
{
ColorManager.Color = (ColorManager.Color == "red") ? "blue" : "red";
}
</script>
<html xmlns=" http://www.w3.org/1999/xhtml" >
<head runat="server">
<link rel="stylesheet" href="StyleSheet.aspx" type="text/css" />
</head>
<body>
<form id="form1" runat="server">
<H1>Hello World!</H1>
<asp:Button runat="server" ID="Bt1" OnClick="Bt1_Click" Text="Change Color" />
<asp:Hyperlink Text="See CSS" runat="server" ID="ToCSS" NavigateUrl="~/StyleSheet.aspx" />
</form>
</body>
</html>

Thursday, June 15, 2006

A Master Page GotCha...


I was messing around with master pages and found something very strange...

I have a page1.aspx referencing master.master.

I made an override
CreateChildControls()
{
   base.CreateChildControls();
    Controls.InsertAt(0,_MyErrorLink = new HyperLink());
}

I just want to show this debug link on top all the time...

The page comes up but when the page posts, the rendered page is completely blank! No bytes are sent out whatsoever (as Trace="true" proves).

There is no exception raised, it is just blank.

So it seems that the top level of the control hierarchy should always be the master page and monkeying with the sequence in the CreateChildControls is not a good idea.

What I am doing I think is legal since the controls collection is created the same  way everytime.

A bug/limitation I guess. Conclusion, don't do it

CF











__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com

Saturday, May 13, 2006

Another Book / Understanding COM+


I taught ASP.Net in New-York last week. I wanted to bring a book to read in the plane but I wanted a light one (in weight). Have you noticed computer books are just way too thick/heavy?

I browsed through my library and found "Understanding COM+ (1999)" that I actually never read. I was lucky enough to get into Windows programming at the end of the COM days (or it was a misfortune?).

I touched enough of COM to hate it. The infamous 0x8000xxxx errors , E_FAIL (also known as the "oh crap error") and other niceties like the registry being all messed up. Put COM+ on top of this shaky ground and it is even harder.
Not knowing what the fuss was about at the time, combined with reading the wrong #$@#$% book (I can't remember the title), I just did not get it.

After reading "Understanding COM+", my hate turned into "that's a pretty good idea". The .Net ease of programming can now be a real incentive to use some of the services of COM+. Maybe I will change my views and instead of avoiding COM+ at all cost, I may take advantage of it with .Net.

If only I had read that book first. So, yes, it is a 1999 book and it is not a thick book, but the why of things is clearly explained. If you are looking for sample code with QueryInterface all over, you will be disappointed.
If you want to understand what problems COM+ is trying to solve then read this.
I am glad I did.

And BTW, COM is not dead. If you want to host the CLR on some exotic plateform, you have to use a bunch of COM interfaces. But that's another story....








Get amazing travel prices for air and hotel in one click on Yahoo! FareChase

Expert ASP.Net 2.0 (Advanced Application Design) Book

Just finished reading this book. One of the problems in Windows is the numerous different ways you can design your app. The new .Net era brought us some new goodies like managed code and a huge library of classes among various things. Should we then forget the old days of COM+? What about queuing? JITA? etc...
How does this play with ASP.Net, Web Services?

Some of the older technologies are really not dead and can be leveraged in .Net.
All of this is very confusing. This books lays a path through all this legacy and the new stuff. It is not an in depth book on all the subjects covered (nor should it be). It provides a high level view on how all this stuff can interact. It is really good to see this big picture before diving down details.

Cool stuff


Yahoo! Messenger with Voice. PC-to-Phone calls for ridiculously low rates.