TechFest Houston Slides and Source Code


Published Monday, September 28, 2009 | Comments (1)

TechFest Houston was a blast, and if you came out to my presentation on Simpliyfing Web Part Development or dropped by the Cogent booth, then I would like to say thank you! The presentation slides and demo source code can be downloaded below.

Simplifying Web Part Development.zip (2.35 mb)

.NET on the iPhone?


Published Friday, September 18, 2009 | Comments (0)

Ty Anderson just shot me a link to MonoTouch (http://monotouch.net/), a product that allows you to develop IPhone software using Microsoft's .NET Framework.  You'll still need a Mac, the Apple iPhone SDK, and to be a member of the Apple iPhone Developer Program, but it's still pretty cool that it lets you use your current knowledge set to develop applications.  At least in theory.  Not sure how that works out in reality, but I'd be interested to see and hear if anyone has/is giving it a shot.

Disable XML Comment Warnings for a File


Published Friday, September 04, 2009 | Comments (0)

I'm a big fan of enabling XML comments when you're working on a project (either alone or as a team) because it helps you quickly identify what has and what has not been documented.  When you have XML comments enabled, the compiler will show warnings for any public and protected classes / class members that do not have XML comments.  To enable XML comments you just check the XML documentation file option in the build tab of the project properties page. 

One of the issues that you run into, however, is that there can be a number of code generated files in your projects, and you have no control over that code.  But, if that file is no re-generated often, then you can insert a bit of code to suppress XML comment warnings from that file:

// Disable all XML Comment warnings in this file //
#pragma warning disable 1591

The next time you compile, XML comment warnings from the file will not be display.  If you're wondering, the 1591 is the specific warning number for XML comments.  If you remove the XML comment warning number from the pragma statement, then all warnings from the file are suppressed, not just XML comment warnings.  no warnings will come from the file.  You can also tack on additional warning codes to suppress additional types of warnings, if desired.  How do you figure out what the numbers are?  I find one of the easiest ways to go about it is to read the output window (NOT the Error List window).  When a warning is generated, it normally looks something like the following:

[filename]: warning CS1591: Missing XML comment for publicly visible type or member 'VSeWSS.TargetListAttribute'

Notice there is a number right after the warning (in this case its CS1591)?  Just drop the alpha prefix and you've got your warning number.  Since this is in the output window, you may have to scroll through the text a bit to actually find the warning, but it should be in there somewhere.

Fixing the 'Name ActiveX Control' Message on SharePoint Sites


Published Friday, September 04, 2009 | Comments (0)

SharePoint sites normally have a 'Name ActiveX Control' used to communicate you're online presence back to the Office system.  If you've ever seen a site where it shows you who is 'online' and who is 'offline' then know that this is the mechanism that marks someone as being 'online'.  That is all fine and well for internal application, but it kinda sucks for public facing sites because users are asked to install some weird ActiveX control that they know nothing about.  I find it particularly odd that it's included on the default publishing site.  Whatever.  Fixing it should be relatively easy because there is a knowledge base article outlining what to do:

Knowledge Base Article 931509

Unfortunately, that only gives you part of the solution.  It basically tells you to comment out two function headers in the init.js file.  If you follow the instructions in the Knowledge Base article exactly, you'll see a little JavaScript error notification when you refresh the page.  Probably because, now, let me guess . you commented out a function header without commenting out the rest of the function?  Also note that one of the functions you commented out gets called later, which is a bit of a syntactical no-no in just about every language of which I can think.

So, if you want to avoid the 'Name ActiveX Control' message on your SharePoint site AND have it work correctly (novel idea), you need to entirely comment out both functions, and comment out any references to those functions anywhere else in the JavaScript file.

Recursive Anonymous Methods


Published Tuesday, September 01, 2009 | Comments (0)

I was having a lively discussion with a friend the other day on the finer points of anonymous methods and lambda expressions. Yes, at Cogent Company this is actually what we do for fun.  I had basically said that an anonymous method was just like any other method, to which he rattled off a laundry list of the differences.  One of those differences caught my attention:  you cannot create a recursive anonymous method.  At first glance it seems to make perfect sense - how can you call a method with no name.?  But when you think about it from a CLR perspective, how could you not be able to?  An anonymous method is basically like any other method, and if any other method can be called recursively then so can an anonymous method.

So, here's the code for a recursive anonymous method that solves factorials:

using System;
using System.Reflection;

namespace RecursiveAnonymous
{
 
class Program
  {
   
delegate int FactorialDelegate(int i);

   
static void Main(string[] args)
   
{
      FactorialDelegate factMethod
= x =>
       
{
         
return x <= 1 ? 1 : x * (int)MethodBase.GetCurrentMethod()
           
.Invoke(null, new object[] { x - 1 });
       
};
     
for (int i = 0; i < 10; i++)
     
{
        Console.WriteLine
(factMethod.Invoke(i));
     
}
      Console.Read
();
   
}
  }
//class
} //namespace

The real trick is to use MethodBase.GetCurrentMethod(), which gets a reference to the MethodBase of the currently executing method (essentially the MethodInfo).  From there you can call the .Invoke method and pass in the appropriate parameters, allowing the anonymous method to execute again (recursively).  Hooray for reflection.

I have no idea why anyone would want to do this, aside from settling bets or showing off, but it's nice to know that you can.  As for my buddy, he says I cheated.  To which I can only reply, damn straight! :)

Bookmark this post: Dot Net Kicks
By Damon Armstrong | Permalink | Comments (0) | Comment on this Post
Filed Under: .NET Development

Disabling an ASP.NET Button when Clicked


Published Friday, December 21, 2007 | Comments (0)

I was answering a question in the ASP.NET forums on Simple-Talk.com (click here you want to check it out) about how to avoid the issue of users submitting multiple page requests when they click on buttons.  My first inclination was hey, just disable the button after they click it and everything will be just fine.  So I fired up Visual Studio and threw the following code into a page:

<asp:Button runat="server" Text="My Button" OnClientClick="this.disabled=true;" />


And naturally it failed miserably.  Why?  Because nothing works on the first try -- unless fate is trying to store up some catastrophe points to use on you later.  And apparently if you disable a button in the onclick it doesn't post back for reasons that I haven't dug into very far.  Not to be outwitted by HTML, Javascript, .NET, or whatever else you can blame for your problems, I tried a myriad of random ideas until I hit upon this -- instead of disabling the button when you click it, set the onclick event to fire a function that returns false.  So it looks something like this:

<asp:Button runat="server" Text="My Button" OnClientClick="this.onclick=new Function('return false;');" />


This approach effectively disables the button, but doesn't gray it out.  So there you go.  If you want a gray button then this isn't the blog for you, but it does keep people from clicking on it the button more than once.  Naturally, this means that some sticklers out there will whine because the button stays disabled if the request times out or the viewer stops the request manually.  Part of me says leave it disabled as vengeful tribute to the multitudes who quintuple-clicked your button and created a horde of duplicate records for you to delete.  Then there's the other part of me that likes the JavaScript setTimeout function and a bit of a challenge:

<script type="text/javascript"
   
function disableButton(button, resetDelay)
   
{
        button.oldonclick
= button.onclick;
       
button.onclick=noClick; //new Function("return false;";
       
setTimeout("enableButton('"+ button.id + "');" resetDelay);                                    
   
}
   
function noClick()
   
{
        alert
("Chill - You already submitted this page once. "+
               
"Submitting it twice isn't going to make the "
               
"server go faster.  Quit hitting the "+
               
"freakin' button!";
       
return false;
   
}
   
function enableButton(buttonId)
   
{
        var button
= document.getElementById(buttonId);
       
if(button!=null)
       
{
            button.onclick
= button.oldonclick;
       
}
    }
script>


The disableButton function copies the "standard" onclick method into a fake property of the button for safe keeping, sets the new onclick to the noClick function (which displays a nice message to the user if they DO try to click), then sets up a delayed function call (read--asynchronous method) that executes after a delay that you set when calling the disableButton method (a value of 1000 for the resetDelay = 1 second, so multiply accordingly for your needs).  Here's an example of what it looks like in a button:

<asp:Button runat="server" Text="My Button" OnClientClick="disableButton(this,30000)" />


When you click this button, it gets disabled for 30 seconds.  And if a user clicks on that button in the interim, they even get a little feedback on what's going on.  Just remember, don't blame me when you get fired for pasting the script into your project and forgetting to change the message.

Bookmark this post: Dot Net Kicks
By Damon Armstrong | Permalink | Comments (0) | Comment on this Post
Filed Under: .NET Development

Simple Code Performance Testing


Published Friday, August 24, 2007 | Comments (0)

After posting Performance: Caching vs. Reading from an In-Memory XML Document, there have been some questions about how I actually do the performance testing.  My approach to performance testing is really simple... I just write some code, run that code in a big for loop, and time how long it takes to run through all of those iterations.  Nothing too complicated.  Calculating the speed of the operation becomes a simple matter of (iterations / time).  I've packaged this testing routine into a class I call the PerformanceTimer class, which simplifies things even more.  The code for the class follows, and an example of how to use the class to test a routine follows even further down.


using System;

namespace Rebel.Performance
{
    
/// 


    ///   Delegate to a testing method
    /// 

    public delegate void TestingMethodDelegate(int iterations);

    
/// 
    ///   Executes a testing method and stores execution duration
    /// 

    
public class PerformanceTimer
    {
        
/// 
        ///   Property backer for the ExecutionSpan property
        /// 

        
private TimeSpan _propExecutionSpan;
        
        
/// 
        ///   Property backer for the Iterations property
        /// 

        
private int _propIterations;

        
/// 
        ///   Duration of testing method execution
        /// 

        
public TimeSpan ExecutionSpan
        {
            get { 
return _propExecutionSpan}
            
private set { _propExecutionSpan value}
        }

        
/// 
        ///   Number of iterations for the test
        /// 

        
public int Iterations
        {
            get { 
return _propIterations}
            
private set { _propIterations value}
        }

        
/// 
        ///   Executes testing method and determines execution duration
        /// 

        /// Delegate to the testing method
        
public void Run(int iterationsTestingMethodDelegate testingMethod)
        
{
            Iterations 
iterations;
            
long startTimeendTime;
            
startTime DateTime.Now.Ticks;
            
testingMethod.Invoke(Iterations);
            
endTime DateTime.Now.Ticks;
            
ExecutionSpan = new TimeSpan(endTime startTime);
        
}

        
/// 
        ///   Number of iterations per second
        /// 

        
public double IterationsPerSecond
        {
            get
            {
                
return (Iterations ExecutionSpan.TotalSeconds);
            
}
        }

        
/// 
        ///   Number of iterations per millisecond
        /// 

        
public double IterationsPerMillisecond
        {
            get
            {
                
return (Iterations ExecutionSpan.TotalMilliseconds);
            
}
        }

    } 
//class

//namespace


So that's the class, but how do you use it?  Here's a simple test application that uses the PerformanceTimer class to check the speed of concatenation operations.  You've always heard that using a StringBuilder to build a string is faster than repeatedly concatenating a string directly?  Here's a chance to actually prove it.   


using System;
using System.Text;
using Rebel.Performance;

namespace Rebel.PerformanceTest
{
    
/// 
    ///   Console Application
    /// 

    
class Program
    {

        
static void Main(string[] args)
        
{
            PerformanceTimer timer 
= new PerformanceTimer();
            
int iterations 100000;

            
//Run TestA
            
timer.Run(iterationsnew TestingMethodDelegate(TestMethodA));
            
Console.WriteLine(timer.IterationsPerMillisecond);
            
            
//Run TestB
            
timer.Run(iterationsnew TestingMethodDelegate(TestMethodB));
            
Console.WriteLine(timer.IterationsPerMillisecond);

            
Console.ReadLine();

        
}
        
        
/// 
        ///   Concatenation using a StringBuilder
        /// 

        
static void TestMethodA(int iterations)
        
{
            StringBuilder s 
= new StringBuilder();
            
for (int 0iterationsi++)
            
{
                s.Append
("A");
            
}
        }

        
/// 
        ///   Direct concatenation
        /// 

        
static void TestMethodB(int iterations)
        
{
            
string "";
            
for (int 0iterationsi++)
            
{
                s 
+"A";
            
}
        }

    } 
//class

//namespace
WARNING: You will want to use as large of an iteration count as possible when testing.  This performance testing approach does the "best" it can when calculating exact start and end times, so some fluctuations are bound to occur when capturing the start and end times.  When they do, the fluctuations throw off the calculations.  Larger iteration counts spread out the effect of the fluctuations and minimize the error.  Think of it this way:  if you are off by 1 in 10, then you have a 10% error.  If you are off by 1 in 10000, you have a 0.01% error.


On my machine, the StringBuilder operates at 14629 iterations / second and the direct concatenation approach runs at 13 iterations / second.  Pretty significant difference. 

Bookmark this post: Dot Net Kicks
By Damon Armstrong | Permalink | Comments (0) | Comment on this Post
Filed Under: .NET Development

Saving the Telerik RadSplitter/RadPane State


Published Friday, December 22, 2006 | Comments (0)

Telerik makes UI controls for ASP.NET (and they are getting in Windows Forms controls too apparently) and they've done a great job.   But, everything has it's little quirks.  I was working with the RadSplitter, a control that allows you to make collapsable / resizable panels on your webpage, when I ran across a little problem: persisting the state to a cookie.

The cool thing about the RadSplitter is that you can resize / collapse a pane on the Client-Side, and the control will use JavaScript to update hidden fields on the page so it sends the new size and collapse state back to the server.  We wanted to store that state in a cookie so when users closed the browser and returned, the resizable sections would retain their last size and collapse state.

Here's the issue:  let's say you have a pane that, by default, is 200px wide.  You resize that pane on the client side to 350px, then collapse it (hide it).  When you post the page back to the server, the pane reports its width as 0px.  So, how do you save the width of an updated pane when it's in a collapsed state?

The answer lies in the ExpandedWidth property, which is an internal value to the control that is not publicly exposed.  When a pane is collapsed, the ExpandedWidth property holds the width to which the pane should expand when expanded.  ExpandedWidht is 0px when the pane is fully expanded.

So, how do you get this value?  All of the state information about a RadPane comes back in as a JavaScript Object Notation (JSON) string in a hidden field, which we can intercept and parse to acquire the ExpandedWidth property (or whatever other property you want to find).  Here's the code to save and load pane state for a RadPane in a RadSplitter:

///


/// Regular expression used to parse JSON object info comming back from the Telerik splitter control. Telerik did not expose
/// the expandedWidth property (which stores the width of the pane when it is collapsed) so you have to acquire it using a workaround
///

private static Regex SplitterRegex = new System.Text.RegularExpressions.Regex("(?:\"collapsed\":(?[^,\\}]*))(?:.*)(?:\"expandedSize\":(?[^,\\}]*))", RegexOptions.IgnoreCase);


///
/// Saves splitter settings to the setting cookie
///

private void SaveSplitterSettings()
{
    if (splitter != null)
    {
        string splitterStateString = Page.Request.Form[paneLeft.ClientID];
        if(!string.IsNullOrEmpty(splitterStateString))
        {
            Match match = SplitterRegex.Match(splitterStateString);
            if (match.Success)
            {
                try
                {
                    bool collapsed = bool.Parse(match.Groups[1].Value);
                    string width;
                    if (collapsed)
                    {
                        width = match.Groups[2].Value +
"px";
                    }
                    else
                    {
                        width = paneLeft.Width.ToString();
                    }
                    HttpCookie settingCookie = new HttpCookie("iswSplitterSettings");
                    settingCookie.Values.Add(
"LW", width);
                    settingCookie.Values.Add(
"LS", collapsed ? "1" : "0");
                    Page.Response.Cookies.Add(settingCookie);
                }
                catch
                {
                    //Do nothing
                }
            }
        }
    }
}


///
/// Loads splitter settings from the setting cookie
///

private void LoadSplitterSettings()
{
    HttpCookie settingCookie = Page.Request.Cookies["iswSplitterSettings"];
    if (settingCookie != null)
    {
        try
        {
            paneLeft.Width =
new Unit(settingCookie.Values["LW"].ToString());
            paneLeft.InitiallyCollapsed = (
bool)(settingCookie.Values["LS"] == "1");
        }
        catch
        {
            //Do nothing - allow the control to sort itself out
        }
    }
}

Bookmark this post: Dot Net Kicks
By Damon Armstrong | Permalink | Comments (0) | Comment on this Post
Filed Under: .NET Development

Don't let management architect a solution...


Published Monday, December 04, 2006 | Comments (0)

I've seen many cases where business people and technical people collide.  Part of building an effective business requires understanding and respecting the various departments in an organization and their individual areas of expertise.  But too often, cross-departmental decisions are driven by the wrong people.  The results are less than spectacular, though not unexpected considering the situation.  Here's a link to a story about just such a situation:

No, We Need a Neural Network

Kudos to the man for two things.  First, trying to turn management away from a bad decision at every step along the way.  Second, for making a killing off the company when they failed to heed his warning.

To be fair, however, I should note that business people are not the only ones who engage in activities outside their expertise.  I've seen technical people try to make business and marketing decisions with similar results. 

Accessing the Web.Config at Design Time for ASP.NET 2.0 Controls


Published Friday, October 20, 2006 | Comments (0)

One of the things that has always bothered me about the ASP.NET validation controls is that it sometimes takes two or three of them to validate a particular field. Say, for example, that you have a password field you want to validate. Normally it's required, has a minimum and maximum length, and needs to be compared against a confirmation field. It takes about three controls to make that happen:

<asp:RequiredFieldValidator runat="server"
   
ID="reqPassword" ControlToValidate="txtPassword" Text="*"
   
ErrorMessage="Password is required" />
<asp:RegularExpressionValidator runat="server"
   
ID="regexPassword" ControlToValidate="txtPassword" Text="*"
    ErrorMessage
="Password length must be at least 6 characters" />
<asp:CompareValidator runat="server" ID="comparePassword"
    ControlToValidate
="txtPassword"
    ControlToCompare
="txtPasswordConfirm" Text="*"
    ErrorMessage
="Confirm password" />

I’m currently in the process of building my own validation control that allows you to put one control on the page, then add as many “Validation Rules” to the control as you wish. So my validation control looks something more like this:

<rd:ValidationRuleSet runat="server" id="vrs1"   
  ControlToValidate
="TextBox1" >
     <
rd:RequiredRule Text="*" Message="Password is Required" />
    
<rd:RegexRule Text="*" Regex=".{6,}"
       
Message="Password length must be at least 6 characters" />
    
<rd:CompareRule Text="*" DataType="String"
       
Message="Confirm Password" 
CompareOperator="Equal"
        ControlToCompare
="txtPasswordConfirm" />
rd:ValidationRuleSet>

This approach also makes it easy to programmatically add rules to the control without having to worry about dynamically adding controls to the page, which is important because the end goal is to make it easy to store validation rules and error messages in a database where they can be easily maintained. But I digress…

I’ve got the basic validation rules down: required, compare, regular expression, data range, etc. But I also wanted to give developers the ability to create custom rules for their projects by extending a base validation rule class (and then write a lot of JavaScript for the Client-Side support). Offering design-time support for a collection of items (in this case rules) is fairly easy. All you have to do is create a class that inherits from System.ComponentModel.Design.CollectionEditor and override the Type[] CreateNewItemTypes() method. From the CreateNewItemTypes() method, you just return an array of the various types you want to allow developers to add to your collection through the collection editor. The issue that I was running into was how to offer design time support for a custom rule? Especially since custom rules would probably only be used on a project-by-project basis.

I decided the best thing to do is allow developers to define their custom rules in the web.config, allowing for rule definitions on a project-by-project basis. Which leads me to the issue of how do you access the web.config at design time? At run time it’s fairly easy to find the web.config because you have a lot of nice methods for locating files using the Server object or the Page.ResolveUrl method. Design-time is a bit less obvious. And I wasn’t (and am still not) very familiar with design-time code. So I set out to find a way to do it.

Google did its job and landed me at Josh Flanagan’s blog entry titled Accessing web.config at Design Time in .NET 2.0. It’s got all the code you need if you want to access the web.config from a System.Web.UI.Design.ControlDesigner (Thanks Josh!). Unfortunately, I was needing a way to access it from a CollectionEditor. But the examples proved very useful, so after digging around the object available to me using Intellisense, I came up with the following solution inside the CreateNewItemTypes method of a class that derives from CollectionEditor:

protected override Type[] CreateNewItemTypes()
{
    ValidationConfiguration validationConfig = null;

    if (Context != null && Context.Container != null &&
      Context.Container.Components != null
)
   
{
        IWebApplication webApp = null;
        int componentIndex = 0;

        while (webApp == null && componentIndex <
          Context.Container.Components.Count)
       
{
           
webApp = Context.Container.Components
              [componentIndex].Site.GetService
              (
typeof(IWebApplication)) as IWebApplication;

           
componentIndex++;
       
}

       
if (webApp != null)
       
{
           
IProjectItem item = webApp.GetProjectItemFromUrl
              ("~/web.config"
);

            if
(item != null
)
           
{
               
System.Xml.XmlDocument doc = 
                  new System.Xml.XmlDocument
();

                
doc.Load(item.PhysicalPath);

                ValidationConfigurationSectionHandler handler = 
                 
new ValidationConfigurationSectionHandler();

                validationConfig = handler.Create(null, null
                    doc.SelectSingleNode
                      ("configuration/rebelDeveloper/validation")) 
                        as ValidationConfiguration
;
            

        
}
    
}

    if (validationConfig == null)
    
{
        
validationConfig = new ValidationConfiguration();
    
}

    
validationConfig.AddPrimaryType(typeof(MinLengthRule), 
        typeof(MaxLengthRule), typeof(RegexRule), typeof(CompareRule),
        typeof(RangeRule), typeof(RequiredRule
));

    
return validationConfig.CreateSupportedTypeArray();

}

The general idea is that you are looking for an IWebApplication service, and you get it by calling the Site.GetService method on an IComponent object. In Josh’s examples, there is a property called Component in the ControlDesigner class that offers the method. In the CollectionEditor class you have to dig a bit deeper, and you ultimately get a collection of components. Since I don’t really know much about design time stuff, I figured I would just loop through all of them looking for a IWebApplication service (though it does seem to always come back from the first component in the collection. I figure that at design time, it’s okay to be a bit inefficient and redundant.

So now I’ve got configurable design-time rules.

Bookmark this post: Dot Net Kicks
By Damon Armstrong | Permalink | Comments (0) | Comment on this Post
Filed Under: .NET Development