Got more questions? Find advice on: SQL | XML | Regular Expressions | Windows
in Search
Welcome to AspAdvice Sign in | Join | Help

C# Nuggets

  • Code Smells in C#

    A lot of my development is done with Code Smells. Whether I'm working on my own code or refactoring someone elses code, if I see some code and it smells funny, then I investigate further.

    Recently I've come to realize there's a code smell which we can blame Microsoft (Anders) for! 

    C# Code Regions. 

    Back in the early days of .Net (ie 2000-2003), I used to moderately region my code. But since reading Martin Fowler's seminal Refactoring book where the concept of Code Smells was introduced, I found that I didn't need C# Regions.

    So why are regions a Code Smell?

    There are two types of regioning I've seen in code. Regions that group methods, properties, member variables, constructors etc together, and those which collapse a block of code. I'll deal with each separately.

    Using Regions to group members.

    In many companies, its commonplace (and even enforced practice) to group similar class members together and place a region block around them. I've even seen this as a coding doctrine inside Microsoft. The problem is that Visual Studio already has a facility to do this automatically. And it's been around in VS since it was called VJ++ and before that in VC. It's called the Class View window, accessed with the shift-ctrl-C shortcut. So why anyone would care about building a class "DOM" into their code using Regions, rather than rely on the Class View window I have no idea. Perhaps they're using Notepad?

    Using Regions to hide blocks within a method.

    This is when it gets really nasty. I've seen multi-hundred line long methods containing regions, and subregions and sub-subregions. I've seen switch() statements wrapped in a region, then each individual case have a region, then subregions inside of the region inside of the case. Switch statements are already a Code Smell, but having region after region after region is a sure-fire way of telling you the method is too long.

     
    So, please, can we all resolve to stop using Regions?

    Interestingly, there are many features that Java has started copying from C# - but regions were not one of those. Perhaps in C# v4 Microsoft can right the wrong and deprecate regions?

    Sponsor
  • Caching and SOAP

    If you're making a SOAP request (in this case with the SOAP toolkit), and you get: 

    "WSDLReader:Loading of the WSDL file failed HRESULT=0x80070057: The parameter is incorrect."

    during the MSSoapInit() call, check that you haven't added a cache-control:no-cache custom header to IIS, or that HttpExpires isn't set to zero days.
     

    Sponsor
  • Silverlight Sudoku with LINQ

    A couple of months ago I came across a very clever Sudoku solver written by Peter Norvig. Peter had written the solver using Python. The solver was special as it solved by constraint propagation using list comprehensions and generator expressions making it extremely fast and very memory frugal. It turns out that the new LINQ feature of C# v3 is basically list comprehensions and generator expressions by another name.

    Brendan Eich, the creator of JavaScript had ported the original Python implementation to JavaScript and I thought it would be a good idea to try to port it to C# v3. You can check out the code here.

     
    I always had a vague plan to wrap the solver in a Silverlight front-end for added WOW factor, but it never really materialized. Fast forward two months and David Anson posts a Silverlight-based Sudoku game on his blog. This gave me the perfect excuse to integrate the LINQ-based solver into his codebase. I extended David's code to respond to the Escape key and complete the board with the first solution found. You can play with it online here, or download the code here. Have fun!

     

     To solve a game, give the Silverlight board the input focus and hit the escape key.

     

    Sponsor
  • Silverlight crashing

    So I'm sat here watching the Mix07 keynote, 45 minutes after Ray Ozzie first got to the stage. I download the Silverlight Beta for Mac and install it.

    Firefox has crashed 4 times while trying to view the Silverlight demos on microsoft.com/silverlight. This is getting really frustrating trying to review the new features.
     

    Sponsor
  • Silverlight

    As has been blogged all over the place, WPF/E has been renamed Silverlight (Note: lower case 'L').

    Some people say there's more to come at MIX07. Well, I think I've discovered what the secret is. It's hidden inside of the Silverlight promo video. Silverlight is written in Java! Don't believe me? Take a look at a frame grab from the promo video, clearly showing Silverlight's use of SAX, the javax namespace and use of Java API's like vector.addElement.

    Sponsor
  • The trouble with dynamic languages

    Javascript is a dynamic language. And that's a problem. On the one hand it allows you virtually unlimited ability to play with data structures and mold them to your own design. On the other, it presents the virtually insurmountable problem of testability.

    You see, a dynamic language delays the checks which are performed by a static language during compilation until runtime. So you have no idea whether your code is correct until it is executed. The usual answer to this is to write unit tests. But the people who say this tend to gloss over the difficulty of getting 100% unit test coverage. 70% coverage is usually considered a very high test rate. And then there's the difficulty of getting the coverage metrics themselves. At the time of writing, there is only one Javascript/browser code coverage tool around. Hopefully all the hype surrounding AJAX will encourage more of these tools to be written.

    One tool that is available now is JavascriptLint. Lint was the tool you may have used many years ago to statically analyze your C source code for common programming errors not picked up by the compiler. So JavascriptLint does the same but for Javascript. It's based on SpiderMonkey, the C-based Javascript engine in Firefox. So you can be sure it's rock solid with zero false positives. It's a fantastic tool to help AJAX programming as it seamlessly integrates into your favorite IDE as an external tool. Some of the errors it picks up on are:

    Some of these are only available with the tool in Option Explicit mode. Even if it doesn't spot outright bugs in your code, the checks for type coercion and missing semicolons are performance bugs in your code.

    The benefits of JavascriptLint are so conclusive it gets run over my code several times per day.

     

    Sponsor
  • What language was ASP.Net originally written in?

    In this video, Peter Hallam, one of the original C# designers talks about a new C# v3 feature, but also says that WinForms was the original consumer of the C# language.

    This totally contradicts my understanding. I thought that ASP.Net (XSP) was the original team using C# and that WinForms (WFC as it was) was only ported to C# from Java over the winter of 1999/2000 by Chris Anderson.

    Am I wrong?

     

    Sponsor
  • Client-side validation in Firefox

    Recently, I was faced with a problem whereby client-side validation of controls failed to work in Firefox. Only server-side validation was working. Client side validation was working fine in IE.

    This was puzzling as everything I read said that ASP.Net v2 supported client-side validation in Firefox. No amount of Googling helped to identify the problem, so I had to track it down from scratch - and the results were quite interesting. If you have

    <xhtmlConformance mode="Legacy"/>

    set in your web.config, then client-side validation is disabled in firefox.

    To see why, we have to jump down into the validation framework that ASP.Net sends to the web browser. The actual Javascript validation function looks like:

    function ValidatorValidate(val) {

          val.isvalid = true;

          if (val.enabled != false) {

                if (typeof(val.evaluationfunction) == "function") {

                      val.isvalid = val.evaluationfunction(val);

                }

          }

          ValidatorUpdateDisplay(val);

    }

    Using Venkman, I was able to see that val.evaluationfunction wasn't a function at all, therefore the page wasn't getting validated because of this. A bit more searching found that this evaluationfunction is an expando attribute. In ASP.Net v1, this expando is an IE-only HTML expando, defined directly in the HTML markup. In ASP.Net v2, this is a Javascript expando attribute, defined on the DOM via Javascript, and therefore compatible with both IE and Firefox.

    For example, the RequiredFieldValidator calls RegisterExpandoAttribute. You can call this method yourself like:

    Page.ClientScript.RegisterExpandoAttribute(TextBox1.ClientID, "value", TextBox1.Text);

     This produces a block of Javascript just before the closing </form> tag like:

    <script type="text/javascript">

    <!--

    var TextBox1 = document.all ? document.all["TextBox1"] : document.getElementById("TextBox1");

    TextBox1.value = "";

    // -->

    </script>

    where "value" has become the new expando attribute. In the case of the RequiredFieldValidator, the expando name is" evaluationfunction" and it is added to the <span> representing the control at runtime.

    It turned out that this block of Javascript wasn't being sent to Firefox in my situation, and I didn't know why. Instead, the evaluationfunction expando attribute was being rendered directly on the <span> element in HTML.

    So after good deal of decompilation using Reflector, and debugging using Reflection Invokeing of private methods, I discovered the problem was that RegisterExpandoAttribute checks the XHTML Rendering Mode prior to generating the Javascript and if that rendering mode is set to Legacy, then the expando is rendered directly onto the <span> element and no Javascript code is rendered. The result of this is to prevent Firefox from performing client-side validation when Legacy XHTML mode is set.

    I have no idea why the ASP.Net team chose to do this for validation. Perhaps the Legacy XHTML setting should have been called "ASPNetv1Conformance" because that's actually what it does. The docs for Legacy mode state:

    "Reverts a number of rendering changes made for conformance to the v1.1 rendering behavior."

     

    Sponsor
  • QuirksMode

    If only all control developers had it so easy:

    "Note that the Wizard control does not support special Microsoft Internet Explorer rendering for non-standard or quirks mode."

    Why was it deemed OK for the wizard control to get away with it, when nothing else does? 

     

    Sponsor
  • From the odder than odd dept

    Can anyone tell me why the commented out line fails to compile, whereas the next line succeeds? Sure, it's a runtime vs compiletime thing, but why does C# prevent me from casting from a string to (T), whereas the very next line it lets me cast from an object to (T).

     

    using System;

    class X {

          static void Main() {

                Console.WriteLine(Foo<string>());

          }

          static T Foo<T>() {

                if (typeof(T) == typeof(string)) {

    //                return (T)"Hello World";

                      return (T)Convert.ChangeType("Hello World", typeof(T));

                } else {

                      return default(T);

                }

          }

    }

     

    test.cs(10,11): error CS0030: Cannot convert type 'string' to 'T' 

    Sponsor
  • Tabs or Spaces - which is best?

    I format all my code with tabs. I know some people disagree, but the only valid argument the space-worshippers put forward is one of preserving ASCII formatting within comment blocks. I say who cares about comment blocks.

    It turns out that the default mode for tabs or space auto-formatting changed between VS.Net 2003 and VS.Net 2005. The default is now spaces. The problem with doing this is that at a stroke, Microsoft have made the whole Internet less efficient.

    That's a wild claim you cry! How so! Well, the default for the HTML editor is also to use spaces. And the auto formatting in the HTML editor will indent your code using spaces. The default indentation is to use 4 spaces. Therefore, when ASP.Net sends bytes to the user-agent, it will be sending 4 bytes where a single tab character represented by a single byte would suffice. On a page I was editing (roughly 40K when rendered to the client), I changed mode from space to tab and reformatted the document (ctrl-a k f) and saved 8K. A 20% saving in download size is not to be sniffed at.

     

    Sponsor
  • Visual Web Developer on a MacBook

    After getting increasingly frustrated with a 5-year old operating system (Windows XP) I decided to buy a MacBook. But what's an ASP.Net developer to do when they rely on Visual Studio? Why - run it on a Mac.

    I present, Visual Web Developer on a Mac:

    VWD on MacOS

    Here are the exact steps to do this. First you need the brilliant Parallels Desktop for Mac Virtual Machine with Windows installed. The trick is to use RDP to display only the Visual Web Developer window within the Mac environment using the open source rdesktop and seamlessRDP.

    With the developer tools installed from Apple's install CD, I did the following from a terminal:

    $ cvs -d:pserver:anonymous@rdesktop.cvs.sourceforge.net:/cvsroot/rdesktop login
    $ cvs -z3 -d:pserver:anonymous@rdesktop.cvs.sourceforge.net:/cvsroot/rdesktop co -P rdesktop
    $ cd rdesktop
    $ ./bootstrap
    $ sudo -s
    # ./configure
    # make
    # make install
    # exit

    Create a shell script containing:
    #!/bin/sh
    /usr/local/bin/rdesktop -A -a 16 -s "c:\seamlessrdp\seamlessrdpshell.exe C:\Program Files\
    Microsoft Visual Studio 8\Common7\IDE\VWDExpress.exe" 192.168.7.195

    replacing the IP address above with the IP address of your Windows VM. Name the shell script "seamless".
    Make it executable:
    $ chmod 755 seamless


    On the Windows VM, grab seamlessrdp.zip from http://www.cendio.com/seamlessrdp and extract into c:\seamlessrdp
    Make sure you've opened up the Remote desktop port in the Windows Firewall and allowed users to connect via remote desktop in the System control panel applet.

    Log off from Windows. You won't get the single-window experience if you're not logged off. Also, it's a good idea to turn the screen saver off.

    Then from the Mac, run:

    $ open-x11 seamless

    And hey-presto! Visual Web Developer running inside of MacOS!

    Props to http://fastfin.net/seamless/ for some of the help with this.
     
    Sponsor
  • Candy Machine interfaces

    A system with a "candy machine interface" is one where the user interface is so poor it guides you into the wrong action. The term was coined in the seminal book "Writing Solid Code" by Steve Maguire many years ago.

    A similar meme is the pit of success, coined by Rico Mariani to describe an API which has a "gravitational pull" towards the correct approach.

    Unfortunately, the new DPAPI (ProtectedData) support in .Net v2 is a candy machine interface and more importantly, a pit of failure. First let me describe what the DPAPI does. It was introduced in Windows 2000 and allows you to store "secrets" on a computer. These secrets can only be decrypted by the user that stored the secret in the first place - in other words, it uses the NT user's credentials to encrypt and decrypt data.

    The API is very simple: The ProtectedData static class has two methods, Protect and Unprotect. You can find out how to use them from Keith Brown's book The .Net Developer's guide to Windows Security. What could go wrong? Well, several weeks after I used these methods I suddenly began receiving errors like:
    • Key not valid for use in specified state.
    • ContextSwitchDeadlock was detected
    The second of these errors occured while I was in the IDE. It turns out that .Net v2 has a "Managed Debug Assistant" (MDA) which watches Single Threaded Appartments (STAs) and if they do not respond to a Windows messagepump within 60 seconds, then it issues an alert inside of the IDE.
    The first of these errors is the message from the CryptographicException which occurs 60 seconds after the call to ProtectedData.Unprotect().

    A bit more searching around and I discover that the DPAPI loses the ability to decrypt data when a user changes their password (which I had done several days previously). Due to not rebooting until Windows Update forced my computer to reboot overnight, I'd not seen this error occur. Which is why a perfectly working bit of code one evening failed to work when I arrived at the office the next morning.

    So what have we learnt? That the DPAPI wrapper in .Net is stupid enough to spend 60 seconds trying to decrypt a secret and then causes an exception to be thrown if the user has changed their password. This is totally unexpected behaviour - a candy machine interface.
    Sponsor
  • XHTML Compliance

    ASP.Net v2 was touted as being XHTML through and through.

    I'd like to take this opportunity to take Microsoft to task for not making the Trace output XHTML compliant.

    [Please ignore the fact that trace output is tacked onto the end of a request making it non-compliant anyway - I have a requirement to use the trace output in an XHTML way (via a bit of reflectiony-pokery).]

    Issues:
    1) There's a <nobr> without a closing tag
    2) There's a <hr> without a / at the end and with unquoted attributes
    3) There are <table>s inside of <span>s !!!

    Grade: D - Must Try Harder
    Sponsor
  • Microsoft's new standards compliance

    Just to show how much [sic] Microsoft know about HTML and standards, here's a snippet of HTML from their Messenger Live beta download page:

    Notice what is contained within the anchor hyperlink. It's a wonderful table cell. Totally in keeping with the HTML spec....not. (it also happens not to work on Firefox)

    <tr>
                     <center> <a href='http://g.msn.com/1csbeta/Mess80_EN'> <td background="http://ads.msn.com/ads/pronws/ideas/en/us/but_or_static_left.gif" width="32"> </td>

                        <td align=center style="BACKGROUND-COLOR: #ff3300" background="http://ads.msn.com/ads/pronws/ideas/en/us/but_or_static_mid.gif" width="*" style="FONT-WEIGHT:bold;FONT-SIZE:13pt;COLOR:white;FONT-FAMILY:verdana;TEXT-ALIGN:center">
                        Download</td>
                        <td background="http://ads.msn.com/ads/pronws/ideas/en/us/but_or_static_right.gif" width="32"> </td></a>
                    </tr>
    Sponsor
More Posts Next page »