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

Peter's Gekko

public Blog MyNotepad : Imho { }

January 2004 - Posts

  • DotNed met

    Yesterday evening 35 people attended the meeting of the Dutch DotNED user group. The weather made it a bit of a gamble to go, to me it is a 180 km drive. But that's part of living up North. Anyway, I made it (almost) in time, just 3 minutes late.

    The weather also takes it's toll on our health. Sander “Devtips” Gerz had some kind of flu but nevertheless presented a very clear story on Nunit. Both the why and the how of unit testing were covered. You can find his presentation in the form of an article on his site. In Dutch but recommended. The slides and sample code will be on the DotNed site. Many of the attendees had been using unit testing. All agreed that starting with unit testing (first write the test and then start coding) was no problem, but keeping up with it in the course of the project was harder.

    The second presentation was on tEdit.net. This is a datagrid component meant to create quick and dirty pages to update database data. The speaker, Ries Vriend, gave a flashy show how to build an editable datagrid in a couple of minutes. Including lookup combo-boxes and the like. You program the component by editing an xml configuration file. It was a show which no doubt will impress a system administrator who needs a quick solution, but it did not convince me as a developer. My main objection is that the component is very quick but also quite dirty. Imagine a datagrid having a connection string property ? Which can be set from the web.config, but nevertheless.. Almost sounds mono-lithical. But this just an opinion (read my blog title), if you have to do some quick and dirty work, check out the website. It is crammed with information. Speaking on opinions and Dutch : I thought the Tedit component has a typical Dutch flavor : "to hell with theory, just make it work". But that's not really my cup of tea.

    Best part of  a user group meeting is talking with fellow developers. Again Delphi (for .net) was a favorite topic. A couple of people had had hands-on experience with Delphi for .net. Some of them doing crazy things. Like dropping vcl.net components, like the Raize components, on winforms. Which, after some fiddling, worked. Looks like the release of Delphi.net is a giant leap from what I got demo-ed last december. I'm still waiting for the trial.

    Driving home was a different story. In Friesland I ran into a real blizzard but Ygdrassil got me through. It was quite an adventure.

    Peter

  • Selecting a Stylesheet at runtime

    You can adjust the appearance of your web form with a CSS (cascading style sheet). In the format menu of the VS.NET web form designer is document styles. Here you select a css file or you can build a style on the spot. The (link to the) style will be embedded in the header of the webform. Take this example :

    <HTML>
        <HEAD>
            <title>BaseForm1</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 href="../StyleSheetMOC.css" type="text/css" rel="stylesheet">
       
    </HEAD>
        <body MS_POSITIONING="GridLayout">
            <form id="Form1" method="post" runat="server">

    To give all the forms in your app the same appearance it would make sense to set the stylesheet in the base webform class of your app. The actual webforms inherit from this baseform and should inherit the stylesheet as well. Alas, this does not work. When inheriting from a webform you do not inherit the HTML in the header. And what is worse, it is next to impossible to influence the content of the header of a page being rendered.

    The good thing is that the link to the stylesheet does not have to be in the header. Googling around I found several solutions. One of them was to start the response with the link. Which worked until the page contained a validator control. The other one was to finish the response with a link. This worked and I posted the first version of this post.

    In a response on that Ryan Greg pointed to the importance of the place in the document where the link should be injected. To influence the injection place I used the Controls.AddAt() method in a second version to insert a literal control containing the link. The first parameter of this method is the desired location of the control in the the tree of the page. Passing a 0 inserts the link as first line of the response. That line is reserved for the doctype. If your page has a validator control, the script of that control will fail to load. Passing in a 1 inserts the link as first markup in the body.

    But there is a big drawback to using the Controls.AddAt()  method. It might (will allways ?) ruin the viewstate of the page, making the baseform pretty unusable. As an alternative I used the RegisterClientScriptBlock method in my third attempt. This method will insert any script, or a link to a style sheet, in the top of the rendered page before the rendered controls. Which is a nice location.

    The link to the style sheet is in the web.config and read from the AppSettings. This location is the location as seen by the browser, something like

    <add key="StyleSheet" value ="http://yourhost/su/moc/StyleSheetMOC.css"></add>

    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad (e);
        RegisterClientScriptBlock("MyCSS", string.Format("<link rel='stylesheet' type='text/css' href='{0}'></link>"));
    }

    As a result every page which inherits from the baseform contains a link to the stylesheet, its controls can successfully use the styles defined, and the viewstate of the pages keeps running as well.

    Blog on, Peter

  • How to drive VS.NET crazy

    VS.NET has a tight integration with SQL server. From the server explorer you can browse your databases, view or update any data in them and even do a lot of design stuff. You can see some examples in this dnj article. The only thing I haven't found in there is the administration of sql user accounts. But there is a price to be paid, I'm not exactly sure what is going on but some things are leaking. Having altered some tables and having had some app-crashes while debugging my machine slows down. Restarting VS solves that. Closing down VS form such a state is a long wait.

    I found out there is a faster way to slow down VS. Take this scenario. For an app I had created a couple of components. The components open the db connection when created, close it when disposing and house a couple of dataAdapters. The pages of my app will use the component, to make them easy to use I added a couple of component properties to the app's base web form. Something like this

    public class BaseForm : System.Web.UI.Page
    {
        private IprojektData pd;
        public IprojektData Projekt
        {
            get
                {
                    if (pd == null)
                        pd = new ProjektData.DataComponent();
                return pd;
            }
        }
     

    The properties have a "lazy" creator, the actual component is not created until it is actually needed. And when the component is not used on the page it will not be created at all.

    The pitfall is making the properties public. When you design a page based on this base class the component properties will show up in the property window. The property value is computed and the component will be created. Leading to a lot of (failing) database activity in the web-form designer. Not needed and this really can cripple your machine very fast. The solution is pretty straightforward, just set the browsable attribute on the properties to prevent the properties showing in the property window. Like this

    [Browsable(false)]

    public IprojektData Projekt
    {
        get
            {
                if (pd == null)
                    pd = new ProjektData.DataComponent();
            return pd;
        }
    }
     

    Now the property won't show up in the window, the componenet is only created at run-time and VS will keep running.

    Blog on,Peter

  • Get connected, but don't stay connected (A connection pooling error has occured)

    Perhaps just some open doors being kicked in agian, but :

    Thanks to the ado.net connection pool, connecting to a database is asp.net is fast. A sqlConnection.Open() gets you to the database in a snap and a sqlConnection.Close() will return the connection to the pool. This is all default behaviour, no code or configuration required. But the feature has a downside when your app does not behave well. If your app keeps a connection open after handling a request you can get into trouble. For instance : Requesting the same page again (and trying to reopen a connection which wasn't closed in the former request) can produce a A connection pooling error has occured error message when your page uses several connections.

    This is what works well in my apps

    • Open the connection in the page_load event.
    • Close the connection in the page_unload

    If your app accesses its data in a componenet (which it should..)

    • Create the component in the page load
    • Dispose the componenet in the page_unload
    • Open the connection in the constructor of the component
    • Close the coneection in the componenets Dispose method

    This is pretty simple and works very well. The connections will be open a very short time span, only in the prcess of creating a response. When your webserver has no requests to process no connections are open. To check if my apps behave well I do the following:

    • My working machine is not very powerfull, it has a limited disk and has to run VS, IE, outlook, IIS localhost, asp.net  and sql server all at the same time. When the app is behaving well this is not a problem. When the app does not close its connections the machine is brought to its knees very fast.
    • Use the windows performance monitor (perfmon.exe) to monitor the count of open connections. When the app is not well behaved you will see the count of open connections grow and grow.

    Blog on, Peter

  • DotNED meets again

    This is a message to Dutch .net developers not subscribed to the dotned newsletter. This should be an empty collection. The Dutch .NET user group DotNED (-erland) will meet again January 29th. With a talk on NUnit by Sander “Devtips” Gerz and a demo of tEdit.net.

    See you there, Peter.

  • Templates going haywire (There is already a component named ....)

    Sometimes the template editor in VS messes things up. After clicking “edit template” a horror like this might show up:

    This is fixable :  When you drop a control, like a textbox or label, on the page VS will create a declaration for the control in the code file behind the page. In a control which works with templates, like a datagrid or a datalist, the controls in the template are not added to the code. (In my dnj article on the datagrid I described how to get to the template's controls from code nevertheless...) What happened in the screenshot is that VS.NET did create declarations for all the controls in the code behind source file. Deleting (commenting out) the declarations from the source will get the template editor working again.

    I don't really like the template editor that much. When a template is opened VS creates a class based on this page containing the template and the html source of the template. Probably comparable to the things asp.net does in IIS when a full page is requested. In the process of editing a template VS keeps doing things in the background, so much that it can cripple any machine. Editing templates is not the “experience“ of editing a normal page. At this moment I'm exploring user controls as an alternative, but still have some hurdles to take ...

    blog on, Peter

     

  • Once more on Crystal (Access to report file denied)

    I still do like Crystal reports but getting them to work on a production machine can be pretty frustrating. Responses to earlier posts showed me that I'm not the only one. So here's another.

    You can print a Crystal report on a webpage by exporting it as a PDF or a Word doc. The browser will catch this in a viewer from where you do the real printing. There is a sample on the Crystal website which I followed quite sheepishly. It worked on my machine but the production machine showed a quite interesting error

    C:\DOCUME~1\S01NT0~1\ASPNET\LOCALS~1\Temp\temp_b8805d74-11f7-4721-b614-88b564c0b8a4.rpt: Access to report file denied. Another program may be using it.

    There is indeed an access problem, but not with the report file. Browsing the web I found the solution on the Crystal site. This led me to do some refactoring on the example which resulted in a helper method I would like to share with you:

    protected void exportReport(CrystalDecisions.CrystalReports.Engine.ReportClass selectedReport, CrystalDecisions.Shared.ExportFormatType eft)
    {

    string contentType ="";
    // Make sure asp.net has create and delete permissions in the directory
    string tempFileName = System.Configuration.ConfigurationSettings.AppSettings["TempDir"] + Session.SessionID.ToString() + ".";

    switch (eft)
    {
    case CrystalDecisions.Shared.ExportFormatType.PortableDocFormat :
    tempFileName += "pdf";
    contentType = "application/pdf";
    break;

    case CrystalDecisions.Shared.ExportFormatType.WordForWindows :
    tempFileName+= "doc";
    contentType = "application/msword";
    break;

    }

    CrystalDecisions.Shared.DiskFileDestinationOptions dfo = new CrystalDecisions.Shared.DiskFileDestinationOptions();
    dfo.DiskFileName = tempFileName;

    CrystalDecisions.Shared.ExportOptions eo = selectedReport.ExportOptions;
    eo.DestinationOptions = dfo;
    eo.ExportDestinationType = CrystalDecisions.Shared.ExportDestinationType.DiskFile;
    eo.ExportFormatType = eft;

    selectedReport.Export();
    Response.ClearContent();
    Response.ClearHeaders();
    Response.ContentType = contentType;

    Response.WriteFile(tempFileName);
    Response.Flush();
    Response.Close();

    System.IO.File.Delete(tempFileName);

    }

    You pass the method the report and the desired format in the parameters. The code is pretty straightforward. The essential thing is that you have to create a temporary file for the result. To create this file your app needs some rights. To make sure the app will have the rights we added an entry in the web.config and the code will read this using the AppSettings property. System management can now assign a scratch dir

    Part of web.config

    <appSettings>
    <add key="TempDir" value
    ="c:\temp\">add>

    And this does work.

    Blog on, Peter

    <appSettings>
    <add key="TempDir" value
    ="c:\temp\">add>

    And this does work.

    Blog on, Peter

  • (Viewstate) Size (really) matters 34ft5#4

    Last november I blogged in detail on reducing the viewstate size of a page with a dtagrid or a datalist. This week I saw the app concerned in its production environment. It was a cripple duck, now it is a swift. Yep, size does matter.

    blog on, Peter

  • The difference between the internet and the intranet according to .net security

    This weekend I watched another Software legends CD show. These mini CD's were handed out on the PDC and on a DotNed meeting. They all contain an interview and/or a presentation. Chris Sells's one starts with an interview by Don Box on pre-asmx services over the web. Followed by a full presentation by Chris on Winforms in the webbrowser. It is not a very recent one so no talk on ClickOnce and a great part of the presentation is on code access security in .NET. Quite interesting and brought very well. The title of this post is a highlight of this.

    When downloading code the .NET platforms checks the source of the code. Like the local machine, the intranet and the internet. Every source has its own permission sets. The interesting point is how .net distinguishes the inter- from the intra- net. The only criterium is whethet there is a . in the domain-name. So this is the intranet http://localhost// and http://MyServer/. But http://127.0.0.1/ , which is a loopback to your local machine, is considered the internet to .net security. Because there is a dot in the domain.

     

  • New public Whidbey build ?

    As I understand things a new Whidbey build will be made avaialble on the MS Developer Days. These are scheduled somewhere around March in the states but over here, in the Netherlands, they will be coming january 22. Also here a copy of Whidbey is promised in the goodies pack  Will this be the PDC build (which is a lovely tool) ? The agenda of the Dutch devdays does consist for 90% out of PDC highlights. Or will we be the first to get a new build (which is even more exciting) ?

    blog on, Peter

  • Devmail.net.

    For an app I needed a componenet to get mail from a pop mail server. After some browsing I took a shot at devMail.net. It looks pretty comprehensible, quite powerfull and has very fair licensing. To try the componenet I built a small winform application with the same functionality as my provider's webmail. I need that to skim my spam mailbox. The main problem with the provider's  (xs4all) webmail is that it is completely brain-dead. It's a collection of php pages which forget all selections on every roundtrip. Very annoying to work with.

    My winform / devmail.net mail client was so easy to build and works so well that I just have to share this with you. It does a couple of things

    • Get a list of email headers and load these in a checkedlistbox
    • Forward the selected messages to another email address
    • Delete all selected messages from the mailbox

    All devmail stuff is in one assembly. Add it to your references, to your using clauses and you're off.

    Setting up an in- and outbox:

    POP3 Inbox = new POP3();
    SMTP Outbox = new SMTP();

    private void Form1_Load(object sender, System.EventArgs e)
    {
    Inbox.Host = "pop.xs4all.nl";
    Inbox.Username = "pobboxname";
    Inbox.Password = "mypwd";

    Outbox.Host = "smtp.xs4all.nl";
    Outbox.Username = Inbox.Username;
    Outbox.Password = Inbox.Password;
    Outbox.AuthenticationMode = SMTPAuthenticationMode.Login;
    }

    Getting the headers is a snap

    private void buttonGetHeaders_Click(object sender, System.EventArgs e)
    {
    if (Inbox.Connect())
    {
    checkedListBox1.Items.Clear();
    foreach(MailMessage msg in Inbox)
    {
    checkedListBox1.Items.Add(string.Format("From {0} : {1}", msg.From, msg.Subject));
    }
    }
    }

    To forward selected messages

    private void buttonForward_Click(object sender, System.EventArgs e)
    {
    foreach(int i in checkedListBox1.CheckedIndices)
    {
    MailMessage msg = Inbox[i];
    msg.To.Clear();
    msg.To.Add(textBoxFwd.Text);
    if (! Outbox.SendMessage(msg))
    MessageBox.Show(Outbox.LastError);
    }
    }

    And to delete selected messages

    private void buttonDelete_Click(object sender, System.EventArgs e)
    {
    foreach(int i in checkedListBox1.CheckedIndices)
    Inbox.DeleteMessage(i , false);
    }

    That's all. Fill in the configuration to your own likes. Included are loads of samples, including a windows service which polls a mailbox at regular intervals. All in simple to-the-point coding. Lovely.

    I do like the product. But.. does anybody have real-life experience with the product ? How does it behave in the wild ?

    blog on,

    Peter

  • Get your Crystal report working on your customers server (Cannot find KeycodeV2.dll, or invalid keycode)

    Actually I do like Crystal Reports. It may not be perfect but the way it works with datasets, its grouping a selecting options and the web report viewer are very workable. Deploying Crystal Report to a web server is another story.

    When you test your app on your localhost all seems to be working well but when the app is installed on the webserver it produces the notorious Cannot find KeycodeV2.dll, or invalid keycode error message. The Crystal site has loads on support on that which tells you to update some registry settings. There is a big chance that you will not find these settings. What to do next is hidden a lot better in the docs.

    The crystal viewer uses a couple of dll's which are installed on your development machine. They are part of CR for VS.NET but not of the .NET framework. If there is no vs.net installed on the webserver these files will be missing on the server. A deployment project in VS.NET will not see the dependencies and will not include them in the setup. What worked for me (destilled out of the loads of CR docs) was creating a setup project with a couple of merge modules

    • Crystal_Database_Access2003.msm
    • Crystal_Database_Access2003_enu.msm
    • Crystal_Managed2003.msm
    • Crystal_regwiz2003.msm
    • VC_User_CRT71_RTL_X86_---.msm (used for reports based on ADO.NET)
    • VC_User_STL71_RTL_X86_---.msm (used for reports based on ADO.NET)

    The regwiz module has an License key property, here you enter the Crystal license key found in the help about of VS.NET. It will read something like AAP50-GS00000-U7000RN.

    Installing this dummy app will enable CR in all your webservers applications. On one server the setup was a webapp, on another server we had to create a Windows forms setup before the server would see CR.

    Blog on, Peter

  • An aspx page is not well formed

    Last year I posted some things on xslt. I bumped into xslt by accident. When you open an aspx file in IE, without IIS sitting inbetween, you get an xslt error messages. By default IE tries to apply an XSLT transform. Without asking. This lead to a quite interesting “discussion” in which I learned more about XSLT. Last week Alex Thissen gave the simplest and best answer. A raw aspx page is not a well formed XML document. It does not have a single root. So any transform will fail. See Alex's comment for all details. Recommended. Alex is a well known speaker in the Netherlands, he spoke on the DotNed meeting and the SDGN meeting. Well, if it ain't Dutch....

    blog on, Peter

    <%@ Page Language="vb" Codebehind="games.aspx.vb" Inherits="wwwmymode.games" %> <%@ Page Language="vb" Codebehind="games.aspx.vb" Inherits="wwwmymode.games" %> <%@ Page Language="vb" Codebehind="games.aspx.vb" Inherits="wwwmymode.games" %>

  • Clear(Type) view on 2004

    A little late but a happy new year to everybody !

    To start this year two tips on “screen-ergonomics”.

    1. Turn down the contrast (and intesinty) on your monitor. Especially LCD monitors produce a very bright image. Which does tire your eyes very much without you noticing it. My opticien (specs shop) advised me to give your eyes the time to adjust to the image instead of turning up the monitor's contrast. Over the last two weeks I have turned it lower and lower, step by step. And it really does feel different at the end of the day.
    2. Switch on Cleartype. You'll find it under display properties | Appearance | Effects | Use the following method to smooth edges of screen fonsts. It really does make a difference (on an LCD). Default is is switched of... I found this tip in my spam box. Windows and .NET magazine again.

    Blog on,

    Peter

More Posts

Our Sponsors

Free Tech Publications

This Blog

Syndication

News