CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Peter's Gekko

public Blog MyNotepad : Imho { }

November 2005 - Posts

  • ASP.NET validators messing up the layout of your web form

    The validator controls on ASP.NET are a quite handy way to validate user input. They perform a check twice. In the browser some snippets of script block a postback to the server as long as the user input does not fulfill the requirements. They thus prevent unnecessary roundtrips. When the data does reach the server it is validated again. All of this works quite nice. But when it comes to the layout validators can have some unexpected behavior. Take this fragment of a web form.

    The upper two textboxes have two validators: input is required and should fall within a certain range. This is what the page will look like in the browser when the second validator fails:

    The first validator does not show up as text but as you might see it does show up as a blanks. Forcing the second validation text to the right  resulting in a text wrap. By default the validator controls always emit html. When the input is invalid it emits the message in red else it emits a string of non blank spaces. This happens also when validation makes no sense, for instance because the associated control is read-only.

    ASP.NET wouldn't be asp.net if you could not change this behavior. The validator controls have a Display property. It's default value is static, resulting in the spaces demonstrated. When you set it to Dynamic it only outputs something when the validation condition is not met. A third value is None, in which case it will never emit anything.

  • A one developer shop, trends, hypes and common sense: WhoAmI, WhereAmI and WhyAmI

    WhoAmI: I'm Peter van Ooijen, a Codebetter blogger who is writing his 400th blogpost. Statistics lie, especially in blogs, but I want to grab this occasions for some reflections. Almost 20 years ago I started working for myself as a self-employed developer and consultant. Over the years I've been working with and for other people but I'm still a one person shop.

    WhereAmI: Geographically speaking in the north-eastern corner of the Netherlands. Way back when I started it was quite important to be located as near to your customers as possible, these days the internet has changed that. Me and my family can choose a place to live which satisfies other demands as well. Where I am in the evolution of software development is less clear. In my university days you could only officially study informatics as a special direction in mathematics. Being a biologist I worked like many others with computers and software on a study-it-yourself base. Learned to program Simula, which was one of the first true object oriented languages but wasn't labeled as such as the acronym OOP hadn't even been invented yet. We wrestled our way through not hindered by any theoretical backup. Learning databases went even worse; I started with dBase III and my first "real" database was MS Access 1.0. Over the years I've been following hypes and trends, picked up anything which appealed and dropped anything which didn't live up to its promises.

    WhyAmI bothering you with all this ? The things which have changed the most over the years are imho development methodologies. Way back you were handed a couple of kilo's of paperwork which described a software system in every detail. It was easy to drown in the waterfall of semi information. Working with the "design" a couple of months revealed that it had three descriptions of the main menu, in two of them an essential option was missing and the business rule involved is nowhere specified at all due to a lack of time. In my view methodologies are mainly a communication tool. Being a one person shop I directly talk with the end user and do the coding; there is no designer (or architect in modern speak) who can distort anything in between. A couple of years ago saw the emergence of eXtreme Programming. In my view this was essentially breaking up the problem in manageable piece which are understood by all parties involved. As a one person shop you do need limited size chunks to get anything working at all. As a one person shop you are confronted with the end-users, there is no PM to keep the two apart. At heart XP meant going back to common sense. Imho it's first incarnation didn't get much further than that. These day's Agile and TDD are the buzzwords. They provide a good idea how to develop software togheter with your customer. But when "being Agile" becomes something like a certification process I'll stand back and see what my fellow Codebetter blogger have to say about the implementation. For now I'll pick the pieces I can use and keep relying on common sense.

    Why am I (still) blogging ? As you have read to this point that is part of the answer. Working on your own you need a sounding board. It's good to have a platform to publish ideas and findings. Knowing that anything bad will be recognized and corrected in public. (This is actually my 400+ post. Recently I was following such a  misleading trail I've withdrawn some posts concerned). This 400th post marks the return of my blog's former subtitle : Growing (up) in publicc.

  • Digital photography ? It's still the glass which makes the camera

    Everything is going digital over the last couple of years. Which revolutionizes the way we work with information. But digital is not a substitute for everything. Take digital photography. The number of mega-pixels of the camera (in your phone) is rising by the month. But when I see the loads and loads of visual creations published on the web it makes me scratch my head. So many pictures are of a quality which makes it hard to see what you're actually looking at. Despite the 1M+pixels shapes are vague and colors pale.

    When it comes to taking a picture you are working with light. When catching light you need a lens to project the image on the sensor. The larger the diameter of the lens, the more light is projected on the sensor. Lens diameter is expressed in its aperture. This is the ratio between lens surface and focal length; a smaller number will catch more light. The specs of most digital cameras focus on megapixels and zoom factor, the aperture is usually named last or even omitted. And when you take a look at cameras you'll see that most of them have a pretty large maximum aperture (= small lens), especially when you compare them with the "old" analog devices. The lenses of phone or pda cameras are just (too) tiny.

    Not all cameras are like that. For a couple of months now I am a happy user of a Sony DSC-F828.

    Which it a giant piece of glass with some electronics attached to it. Not a SLR but it beats most of them when it comes to aperture size and all of them when it comes to price. A very good review is on the DPreview site.

    Yes it's a Sony. I have a love- hate relationship with this brand. Their hardware is just absolutely great; this camera has loads of smart features. But Sony software can be quite a disaster. Connecting the camera with an USB cable works fine out of the box but after installing the supplied USB driver all USB connections are messed up. Which reminded me of some trouble with drivers for the buttons of a Sony notebook. Which work fantastic under XP but completely crippled a Server 2003 setup. Their recent DRM rootkit fiasco was not much of a surprise to me either.

    But their hardware is great and keeps reminding me of the fact that there is more to information than just the bare digits. I leave it to your own imagination to transpose this little rant to other aspects of Information Technology :)

  • Using SQL reporting services in an asp.net application with some notes on report parameters

    In the Crystal days adding reports to an asp.net application could give you quite a hard time. Having  dropped crystal in favor of sql reporting services (so far) just annoying little stuff keeps me busy. In this post I'll demonstrate how to add RS reports to an asp.net application and concentrate on fixing the annoyances.

    To the application reports are available as an URL on the report server. You add reports to an asp.net application by hyper-linking to them. Displaying the reports requires authentication and authorization, anonymous access does not work. By default no-one has browsing rights. In the report manger, which is another URL to the report server, you set the browsing rights under the security tab.

    Provided the user has the necessary rights the browser will show the report with a viewer toolbar. In the toolbar is the option to export or print the report. Make sure you have installed service pack 2 of reporting services or else the print button will be missing. For the print to work RS will (try to) install a little client side ActiveX control which provides a print preview and a clean print.

    A report can have parameters, these are defined in the report's design. You can pass parameter values at runtime provided that the report has the prompt property of its parameters set. If this property is not set you get a nasty reporting services error. There are two way to pass parameters, either in the parameters pane of the report toolbar or in the URL. When you're linking to a report from an application passing the parameters in the URL is  the most likely thing to do. This snippet builds an URL. It does include two parameter values.

    string reportserver = System.Configuration.ConfigurationSettings.AppSettings["ReportServer"] + "{0}&rs:Parameters=false&rs:Command=Render&rs:ClearSession=true";
    string reportUrl = String.Format("UrenVerdeling&idGebruiker={0}&sort={1}",CurrentUser.ID, sortOn);
    Response.Redirect(string.Format(reportServer, reportUrl));
     

    To hide the parameter pane in the browser bar you are supposed to pass rs:Parameters=false in the Url. But to hide the pane also the prompt string, asking for a parameter value, should be empty. The prompt string is set in the report designer (in VS)

    Now there is a little quirk. In the report definition itself there are two settings for the prompt. A logical one which determines whether to prompt and a string what text to prompt. The report designer lumps these two; an empty string will set the prompt flag to false. Which will result in the exception mentioned. In the report manager you set these two properties independently. To be able to set the parameter from the URL and hide the parameter pane you have to check the prompt checkbox and empty the prompt string textbox.

    You don't have to pass in every report parameter. As you see in the report manager there is also a Null column.

    When the Null checkbox is checked a parameter can be omitted. Its value will be according to the expression in the Default Value textbox. The VS report designer has several options for that, non-queried, from-query or none. This is again an oversimplification of the underlying parameter properties. To get a default value of NULL for the parameter you have to check the has default and  Null checkboxes as well as empty the Default Value textbox. Also this can only be done right in the report manager.

    Now I have a great flexibility and can still keep the URL as simple as possible.

    System.Text.StringBuilder sb = new System.Text.StringBuilder("UrenverdelingTotaal");
    sb.Append("&CursusJaar=" + CurrentUser.CursusJaarOmschrijving);
    sb.Append("&Sortering=" + DropDownListSortering.SelectedIndex.ToString());
    sb.Append("&idGebruiker=" + CurrentUser.ID.ToString());
    sb.Append("&SelOnderwijs=" + (CheckBoxOnderwijs.Checked ? "1" : "-1"));
    sb.Append("&SelOpleiding=" + (CheckBoxOpleiding.Checked ? "1" : "-1"));
    sb.Append("&SelSchool=" + (CheckBoxSchool.Checked ? "1" : "-1"));
    if (DropDownListSchool.SelectedIndex > 0)
       sb.Append("&Afdeling=" + DropDownListSchool.SelectedValue.Trim());
    if (DropDownListOpleiding.SelectedIndex > 0)
       sb.Append("&Opleiding=" + DropDownListOpleiding.SelectedValue.Trim());
    if (DropDownListAfkorting.SelectedIndex > 0)
        sb.Append("&Afkorting=" + DropDownListAfkorting.SelectedValue.Trim());
    if (DropDownListNaam.SelectedIndex > 0)
        sb.Append("&Naam=" + DropDownListNaam.SelectedValue.Trim());
    if (DropDownListKostenplaats.SelectedIndex > 0)
        sb.Append("&KostenPlaats=" + DropDownListKostenplaats.SelectedValue.Trim());
    if (DropDownListTelcode.SelectedIndex > 0)
        sb.Append("&TelCode=" + DropDownListTelcode.SelectedValue.Trim());
    if (DropdownlistJaargang.SelectedIndex > 0)
        sb.Append("&Jaargang=" + DropdownlistJaargang.SelectedValue.Trim());
    if (DropDownListPeriode.SelectedIndex > 0)
       sb.Append("&Periode=" + DropDownListPeriode.SelectedValue.Trim());
    if (DropDownListOnderdeel.SelectedIndex > 0)
       sb.Append("&Onderdeel=" + DropDownListOnderdeel.SelectedValue.Trim());
    if (TextBoxOpmerking.Text != "")
       sb.Append(string.Format("&Opmerking={0}%", TextBoxOpmerking.Text.Trim()));


    Response.Redirect(string.Format(reportServer, sb.ToString()), true);
     

    I had found the answer to the prompt problem here in a blogpost whose comments had turned it into just the kind of wiki (loads of comments where the commenters start discussing solutions) some of my old Crystal Reports post have turned into. The solution found  was also applicable to default parameter values. Getting reporting to work (right) is such grateful blog-fodder :)

  • Launch event in the Netherlands

    1350 people attended the Dutch launch party. One of the best things was the location

    The old Van Nelle factory was designed in 1923 but still looks quite modern these days. The most remarkable thing are its glass walls. This idea of transparency was a recurring theme in the keynote. Microsoft exposing its new technologies in CTP's.

    Beside the usual presentations on team system and the like we had a database quiz. With a quizmaster who didn't have a clue what the questions were about but managed to give that a funny twist. Quite amusing.

    The keynote itself  was not too bad. They had dragged in a socio-biologist to comment on the nature of the (presumed) slightly autistic developer. Steve Balmer made a labeling target for ADHD. Parts of his keynote were presented on a video screen

    Somehow the talk could not keep everybody's attention. After all these years of public beta's and CTP's the goods are no real news. We've all seen it and worked with it. And now we can finally start officially using it. No more explaining to do on the status of the product. Time to party. Which we did.

  • Connection pooling ? Just trust the framework, don't be a wise ass

    Connection pooling ? Just trust the framework, don't be a wise ass

    Just before the weekend I thought I was having a serious problem with the connections my app had with the sql server. To get some metrics I grabbed perfmon and did see real trouble. It looked like connection pooling was not behaving like it promised. After a first rather stupid attempt I gave it another shot. A very constructive comment by Joshua Flanagan, who also had some doubts on connectionpooling led me to starting from scratch. I completely reset the server and ran the same tests again. All problems are gone..................

    Yes I've been chasing ghosts in a rat hole. Spoiled my weekend. The framework's connection pooling does live up to its promises. As long as the server is OK. You do have a license to spill .. And now I need a drink.

    Posted Nov 08 2005, 05:47 AM by pvanooijen with 7 comment(s)
    Filed under:
  • A page baseclass in VS 2005 to manipulate the HTML header

    A web page in in VS 2005 is assembled from several source files. Two of them are visible in VS: the markup and the partial class containing custom event handlers and other code you have written. At first sight the main difference with VS 2003 is that the code file looks so much cleaner in 2005. All the declaration and initialization code, generated by VS, is now in a hidden file with the other part of the partial class. At run time the main difference with 2003 is that each page gets compiled into a separate assembly instead of the whole site being compiled into one. As a result your site might be slow in the beginning. To circumvent that you can pre-compile your site. There is a nice article on (pre-) compilation here.

    In this post I want to take a deeper look at several pages sharing functionality. There are two scenarios: using master pages or a base page class. Recently I wrestled with the latter in VS 2003, here I will take a deeper look at it to show which of my wishes have been granted.

    In 2003 I tried to manipulate the HTML header of my pages. Which is almost impossible to do as the page contain just static HTML

    <HTML>
     <HEAD>
        <title>UrenverdelingTotaal</title>
        <meta content="Microsoft Visual Studio .NET 7.1" name="GENERATOR">
        <meta content="C#" name="CODE_LANGUAGE">
        <meta content="JavaScript" name="vs_defaultClientScript">
        <meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema">
     </HEAD>
    To

    To manipulate the header you need something server side. In the feedback to my troubles many a developer suggested to create some server side controls in the header. The only way to do that in VS 2003 is by fiddling with the markup itself

    <HTML>
     <HEAD>
        <title>WebForm1</title>
        <meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">
        <meta name="CODE_LANGUAGE" Content="C#">
        <meta name="vs_defaultClientScript" content="JavaScript">
        <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
        <link id="myStyle" runat="server" type="text/css" rel="stylesheet" />
     </HEAD>

    This does work but completely bypasses the major benefit of a base class as you have to fiddle with the markup in every page.

    In VS 2005 this has been more than solved. The header itself is now a server side control.

    <head runat="server">
       <title>Untitled Page</title>
    </head>


    Now you can manipulate the contents of the header from code:

    I'm going to use this to set the stylesheet and the favicon for all my pages in a base class. Add a new class to your web site. VS will advise you to store the class in the special. APP_CODE folder. All code in this folder will be compiled in yet another assembly. This assembly is referenced by all pages in the site.

    The header is now a server side control, part of the page control tree. I can add other controls to its control collection.

        public class MyBasePage : System.Web.UI.Page
        {

            protected override void OnLoad(EventArgs e)
            {

                base.OnLoad(e);
                HtmlLink link1 = new HtmlLink();
                link1.Href = "StyleSheet.css";
                link1.Attributes["text"] = "text/css";
                link1.Attributes["rel"] = "stylesheet";
                Header.Controls.Add(link1);

                HtmlLink link2 = new HtmlLink();
                link2.Href = "MyIcon.ico";
                link2.Attributes["rel"] = "shortcut icon";
                Header.Controls.Add(link2);
            }
        }
     

    New in 2.0 is the HtmlLink class which will render the links I need in my pages.

    In the code file my pages now inherit from the base class

        public partial class _Default : MyBasePage
     

    And this is resulting HTML of my pages. (Breaks and spaces added to improve readability.

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <html xmlns="http://www.w3.org/1999/xhtml" >
     <head>
       <title>Untitled Page</title>
       <link href="StyleSheet.css" text="text/css" rel="stylesheet" />
       <link href="MyIcon.ico" rel="shortcut icon" />
    </head>
    <body>
    

    Exactly what I want.

    So the final VS 2005 is a big step forward. But there have been many changes over the beta versions of VS 2005. Beta 1 had another organization of code and markup files, as a result it was impossible to use any other base class than System.Web.UI.Page. Thank goodness they changed that. In some of the later CTP's the Header class had more members. Like the LinkedStyleSheets property. In Dino Esposito's book Introducing ASP.NET 2.0 there is a nice example using that. Alas this property did not make it in the release. But the good thing about the HtmlLink class is that it's more generic, it can also be used to link to something like a favicon as well.

    But I'm still looking for a way to set the favicon programmatically in 2003

    Posted Nov 02 2005, 04:15 AM by pvanooijen with no comments
    Filed under:
More Posts