Monday, May 30, 2005

Automating process with Dynamically Compiled C#

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/automating_process_with_dynamically_compiled_c.htm]

I had the opportunity to have another article published in .Net Developer's Journal this month: Automating Your Processes - an NAnt Case Study. The article compares various techniques to automate processes, and then makes a plug for using dynamically compiled C#. This gives the best of both worlds - the flexibility of scripting but the structure and support of a compiled OOP language. The article concludes by applying this to an NAnt build process.

At this time, the article requires a subscription to .Net Developer's Journal to view.

Wednesday, May 25, 2005

Disable Validators on the Client

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/disable_validators_on_the_client.htm]

Sometimes you may want client-side activities to disable a validator. For example, suppose a TextBox is only required if a CheckBox is selected. The TextBox could have a RequiredValidator, but we'd like selecting the CheckBox to enable/disable that validator at the client.

One approach is to use JavaScript functions from the WebUIValidation.js file located at: aspnet_client\system_web\1_1_4322. This stores the script used by ASP.Net's validators and is available to all pages. It includes a script, ValidatorEnable, which takes a control and a boolean and sets the control's Enabled property to the boolean value.

For example, you could have the onclick of a checkbox (id=ChkEnable), call the custom javascript below.

function EnableValidator() {
    var blnEnabled = document.Form1.ChkEnable.checked;
    ValidatorEnable(document.getElementById("RequiredFieldValidator1"),blnEnabled);
}

We still need to persist these changes to the server. We can simply enable/disable the validator in the page load:

this.RequiredFieldValidator1.Enabled = this.ChkEnable.Checked;

In summary, ASP.Net provides easy ways to disable a validator based on client activity. This lets us extend the default validator functionality.

Monday, May 23, 2005

Debugging JavaScript in Visual Studio

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/debugging_javascript_in_visual_studio.htm]

Everyone knows that you can use Visual Studio to debug Class Libraries, such as server-side WebForms. However, you can also use it to debug client-side JavaScript. I've seen some developers who don't realize this because they open up the JS as if it were a class file, add the breakpoint, run the application, and never see the breakpoint hit.

You need to first enable script debugging in your browser (list quoted from MSDN):

  1. In Internet Explorer, click the Tools menu and choose Internet Options.
  2. Click the Advanced tab.
  3. Under the Browsing category, clear the Disable Script Debugging checkbox.

Then any JS file will appear in the Running Documents window. You can open the file from there, add the breakpoint, and step through the script.

Thursday, May 19, 2005

Improving Application Performance by Implementing Paginated Lists

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/improving_application_performance_by_implementing_paginated_lists.htm]

I left CSC and joined Ameripay this week as a Software Engineer. Ameripay is America's leading independent provider of payroll and human resource solutions. While CSC is a great consulting company, I'm excited about the stability (i.e. lack of travel) of e-commerce here. Our dev manager, Chuck Cooper, recently published an article on MSDN: Improving Application Performance by Implementing Paginated Lists.

Most enterprise applications need to page through large sets of data. It's easy to implement this with bad performance. Chuck's article offers high performance ways to handle this, and is a good read.

Wednesday, May 11, 2005

Improving .Net Application Performance and Scalability

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/improving_net_application_performance_and_scalability.htm]

I've been reading a great book, Improving .Net Application Performance and Scalability. While I'm aware of the standard performance issues (minimize calls to the database, reduce postbacks, cache, use client validation, DataReader vs. DataSet, etc...), I've really been impressed with the book so far. It's about a 1000 pages, and is very thorough yet practical.

I admit that I was surprised at the resourcefulness of some of their suggestions, such as how to improve ASP.Net performance by trimming page size:

  • Remove unnecessary white space between tags
  • Avoid long control names (it gets rendered into HTML)
  • Save JavaScript to separate physical files not just for code reuse, but also so that the client can cache it.

They also suggest several tools to help monitor performance:

Monday, May 9, 2005

Using the CLR Profiler

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/using_the_clr_profiler.htm]

In software engineering, our knowledge is limited to what we can test via cause and effect. If we cannot measure the effect of something, it's hard to really know about it. This is one reason why people know relatively less about security and performance than coding "standard" features - it's hard to reliably measure them. However, help is on the way. There exists a free tool, the CLR Profiler, that lets you measure resources in managed code. Resource consumption is linked to performance, so this gives you a tangible way to diagnose some performance-related problems in your .Net App.

Version 2.0 has a great 100 page tutorial. There are other links out there too, such as:

I find this useful to see measurable differences in code snippets. The tutorial shows the difference for using StringBuilder to concatenate strings, but that's just the beginning. For example, the code snippet below opens a file 100 times. If I don't close the reader, I can see the affect of this in the CLR Profiler's "Histogram by Age for Live Objects" chart. In my case, normally the number of objects (less than 34kB) living less than .5 sec was 34KB. If I don't close the reader, it's 800KB.

public static void In_WithClose(string strFileInput)
{
    System.IO.StreamReader sr = null;
    for (int i = 0; i < 100; i++)
    {
        sr = new StreamReader(strFileInput);
        sr.ReadLine();
        if (sr != null)
            sr.Close();
    }
} //end of method

This is a great tool that can be useful for diagnosing memory (and therefore performance) bottlenecks.

Saturday, May 7, 2005

Unit Testing Void Methods

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/unit_testing_void_methods.htm]

I was recently asked the good question "Should you create tests for void methods?". My answer: It depends. Let's look at the following example:

public class Foo1
{
    public Foo1()
    {
        _intCounter = 0;
    }

    private int _intCounter;
    public int Counter
    {
        get
        {
            return _intCounter;
        }
    }

    public void Increment()
    {
        _intCounter++;
    }

}

In this case, the void method Increment() changes the state of the Foo1 object, which can be measured by the Counter property. So, the following would be a decent test:

[Test] public void TestVoidMethod()
{
    Foo1 f = new Foo1();
    Assert.AreEqual(0,f.Counter);
    f.Increment();
    Assert.AreEqual(1,f.Counter);
}

The intent is that we want to always test deterministic logic, such as code that contains conditions, loops, or operators. While this is straight-forward with static functions (plug in x, get y), it can still apply to void methods. The difference is that a void method may be updating another property of an instantiated object instead of a return value.

However note that void methods may lack any logic to test. For example, the method below simply wraps some architecture block that writes out files. There's no logic here to test.

public void WriteFile(string strContent)
{
    ArchitectureBlock.WriteToFile(strContent);
}

Thursday, May 5, 2005

Securing Images From Unauthorized Users

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/securing_images_from_unauthorized_users.htm]

Sometimes we want to secure images so that only authorized users can view them. Private images might include proprietary diagrams or images with personal information (perhaps paychecks). The problem is that the nature of images in Html is simply a URL to an already-accessible file. For example, the source code for the Google logo at www.google.com is essentially . The src attribute is a relative path from the google main page, so you can directly view this image at http://www.google.com/intl/en/images/logo.gif.

For a secure image, we want:

  1. The application can access it
  2. The user cannot.

This can't merely be solved by trying to "hide" the images in some directory, because the page's source is public. They can't hide. However, we can use .Net to solve this by:

  1. Store our images in a file only accessible to the application
  2. Use System.Drawing to dynamically create an image from a file
  3. Response out that image to an ImgPage.aspx page
  4. Make an image in our main page, and set its source property to the ImgPage.aspx page.

This technique of dynamically displaying images in a WebForm is based off of MVP Scott Mitchell's article Create Snazzy Web Charts and Graphics On the Fly with the .NET Framework. The conceptual difference is that instead of dynamically creating an image (such as a chart) and outputting it, we're dynamically creating the image simply by loading in an image file.

The first step is easy. The second step requires some coding. The function below resides in ImgPage.aspx.cs. It assumes that you pass in the image file path in any way you see fit. One way is to get the filename from the querystring. For simplicity this method assumes just "gif" images, but you could get the image extension and set the type as appropriate.

private void Page_Load(object sender, System.EventArgs e)
 {
     string strFile = Request.QueryString["img"].ToString();
     SetImage(strFile);
 }
 
 private void SetImage(string strFile)
 {
     //Set Response type for an image
     Response.ContentType = @"image/gif";
 
     System.Drawing.Bitmap bm = null;
     using (bm)
     {
         bm = (Bitmap)Bitmap.FromFile(strFile);
         bm.Save(Response.OutputStream,ImageFormat.Gif);
     }
 }

First we set the page Response's content type. We then create a BitMap from a file, and save it to the Response OutputStream. Note that ImgPage.aspx is an empty page designed solely to receive this output.

Our main page has an image with the source property set to aspx page and its querystring, such as ImgPage.aspx?img=FilePath.gif. The main page code behind can then do whatever it needs to determine the correct querystring.

<asp:Image id="Image1" runat="server" ImageUrl="ImgPage.aspx">asp:Image>

While I've built a proto-type for this, I admit that I haven't tested it in an enterprise application, but it seems pretty promising.

Wednesday, May 4, 2005

Hosting a WinControl in an ASP.Net Page

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/hosting_a_wincontrol_in_an_aspnet_page.htm]

About a year ago I had the opportunity to write an article for 4GuysFromRolla: Hosting a Windows Control in a Web Form. The article is very straight-forward. It also gets a lot of questions.

The main point is that you can host a Windows UserControl within a web page. There are some highlights from the article, and from what I've learned since then:

  • This requires that the client has the .Net Redistributable installed.
  • Passing data to and from the WinConrol is hard. You can pass data to the control by dynamically recreating the HTML for it (discussed in the article). The best way I know to get data from the control is via an Xml Web Service (not by writing to an Xml File, as I indicated in the article). Writing to a file system could be a security leak, and requires tweaking the security configuration.
  • While the WinControl appears different when embedded in the web page, it can open up a fully-functional win pop-up form. For example, you could add a Timer to the popup form, but it may not work in the WebForm.

The most common problems I get from readers trying to get their WinControl to work:

  • They haven't run the demo, and there's some issue that would be flushed out if they had.
  • It works on their Dev machine, but not someone else's - usually because the other person's machine didn't have the .Net Redistributable installed.
  • They're trying to access some secure resource - if possible I try to avoid this and use web services instead.

I think embedded WinControls are great for toys - for example you want to make a simple online educational game for a school. However, I find that their security and deployment restrictions are cumbersome for an enterprise app.

Monday, May 2, 2005

Using Trace Switches in .Net

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/using_trace_switches_in_net.htm]

.Net has some great tracing features already built in. One of them is trace switches. You can create your own switches for each business process that needs tracing, such as trying to debug a tedious problem in the development environment. You can set switches in your config to various levels, and then call them from code. The trace levels (from MSDN) are:

Trace LevelConfiguration File Value
Off0
Error1
Warning2
Info3
Verbose4

You could set the following switches in your config. If the switch is omitted from the config file (and not instantiated elsewhere), then it is simply ignored.

<configuration>   
    <system.diagnostics
>
        <switches
>
            <add name="Security" value="4"
/>
            <add name="SubmitRequest" value="4"
/>
            <add name="ExternalMessages" value="0"
/>
        switches
>
    system.diagnostics
>

    <system.web
>
        ...
    system.web
>
configuration>

You could then instantiate the switch in code like so:

private System.Diagnostics.TraceSwitch mySwitch = new System.Diagnostics.TraceSwitch("Security","Login and Security");

Finally, you could access the various level by calling the Trace (i.e. "TraceVerbose") from the switch instance. This returns a bool if the level (from the app.config) is at or higher than . For example, TraceError is true if the Level is set to Error, Warning, Info, or Verbose; otherwise, it's false.

TraceSwitches provide an easy way for simple instrumentation of our business processes.