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

C# Nuggets

  • 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
  • Yet more gripes!

    The gripes series continues. This is an occaisional series on the problems I've found with ASP.Net v2. Here are the first and second installment if you've not read them already.

    • The strongly type tableadapter has a Connection property which allows you to override the default of getting the connection string from the web.config. However, this is marked "internal" - which means it can only be called from Code Behind. It can't be called if (like me) you place your code beside the HTML in the .aspx
    • Documentation for meta:resourceKey is lacking.
    • Why does the VS.Net image library only come as .bmp and .png. The .png has alpha transparency, which as we all know, has been neglected in IE up until IE7. It would have been so easy to ship .gif versions too.
    • When using onclientclick on a <asp:button>, you have to set UseSubmitBehavior to false to allow you to cancel the postback. This isn't documented (or intuitive)
    • Right click on a link in the documentation browser and select "Open in new window". It doesn't - it opens it in a new tab.
    • Why does a DataList not allow the ItemStyle to use DataBinding expressions? What if I want to style each item according to something from the database? You get the following error: System.Web.UI.WebControls.TableItemStyle does not have a DataBinding event.
    • Why isn't VaryByHeader supported on on an OutputCache declaration in a UserControl? I want to cache my menu and I also want it to be localized. The way to vary the cache based on accept-language is by using VaryByHeader, but this not supported on a UserControl.
    • LinkButtons and other controls which cause postback don't participate in client-side validation. The original post on this topic was 2001. And it's still not fixed! http://discuss.develop.com/archives/wa.exe?A2=ind0105E&L=DOTNET&P=R5784&I=-3
    • Membership.GeneratePassword() is poorly documented and incorrectly implemented. The second parameter is documented as: "The number of punctuation characters in the generated password". However, it is actually the minimum number of punctuation characters. In addition, if you look at the Reflector dissasembly, then the function will return an undefined value if the generated password fails Cross Site Scripting validation. It's impossible to do this with C#, so I suspect GeneratePassword was written with C++.

    Sponsor
  • How times change

    Quote: "Sun wants to see a variety of programming languages targeting the Java platform"
    - Gilad Bracha, Sun distinguished engineer and co-author of the Java Language Spec.

    http://blogs.sun.com/roller/resources/gbracha/JAOO2005.pdf



    Sponsor
  • GridView Sorting

    TipOTD: Don't call gridview.Sort() inside of the gridview_Sorting() event. Infinite recursion ensues, followed by something like:

    Faulting application aspnet_wp.exe, version 2.0.50727.42, stamp 4333aece, faulting module kernel32.dll, version 5.1.2600.2180, stamp 411096b4, debug? 0, fault address 0x0001eb33.

    or the equivalent for w3wp. It took several hours of windbg crash dumping and test case reductions to realize this :-(
    Sponsor
  • More Gripes

    Following on from my last post on ASP.Net, here are some more:

    • When you define a FormView control without a header or footer template, you still incur the cost of the header and footer in ViewState. Yes - the FormView dev created table rows for the header and footer, added them to the Controls collection and set them to invisible prior to the SaveViewState phase - meaning you get an extra 48 bytes (according to trace.axd) of overhead for no reason.
    • Page_Load, Page_Unload etc ignore ConditionalAttribute applied to them. (Or rather the ASP.Net event hookup framework ignores ConditionalAttribute)
    • Why doesn't the GridView have a TotalRowCount property? By default GridView uses a dataset and knows how to page. Indeed, a FormView has something similar to enable  you to get the Total row count. But a GridView doesn't.
    • Using the rowstyle wrap attribute like <asp:gridview><rowstyle wrap="false"/></asp:gridview> does not work in IE. You have to set every column individually.
    • The onClientClick event is broken - the databinding expression has to be at the start of the string. eg: have a look at what gets rendered for the following: <asp:button runat="server" Text=" <%#Container.DataItem %>" onclientclick='    <%#Container.DataItem %>)'/>. Notice how the text/value is fine, but the onclientclick/onclick is a mess. Then when you try to put quotes inside of the event (for example a Javascript Confirm() ), ASP.Net just doesn't allow this scenario. eg onclientclick='<%# "confirm('" + Container.DataItem + "')" %>'. The only workaround I could think of was to set an expando attribute to the databound expression, then refer to that attribute from Javascript on the client side...
    I'd like to re-iterate that I really like ASP.Net, especially v2. I just can't wait for that Q3 2006 service pack.
    Sponsor
  • ASP.Net v2 Gripes

    I finally got around to building commercial apps with ASP.Net v2 and a surprising number of issues has arisen. Where better to list the issues than here!

    1. The ActiveDirectoryMembershipProvider hard-codes the schema. Therefore if your organisation has a different schema you're out of luck. BTW,  Java/tomcat makes this dead simple.
    2. Why does the sql query editor delete the SQL query if it's invalid? I have to keep it on the clipboard while I'm creating a query just incase VS decides to delete it.
    3. Why is the SQL Query parse error dialog small and fixed size?
    4. Why am I still unable to reference .exe projects from within the IDE. Arghhh
    5. The IDE doesn't perform intellisense on templated controls unless they are enclosed in <html><body> elements. How am I meant to create non-HTML content without intellisense *grin*.
    6. Why does the Compilation Error page use cursor:hand as a style for the expandable hyperlinks? This is non-standard. Back in the previews the expandability for Firefox was completely broken - I remember contributing to the ladybug entry for this. I'm amazed the person who fixed the expandability issue didn't use the proper CSS! It was a two second change but still wasn't done.
    7. URL mapping/rewriting only works for pages without QueryStrings. Unfortunately, QueryStrings are the Number 1 use case for doing URL mapping. Go figure.
    8. The help for Cross-page postback shows how you can "easily" obtain the value of a control on a previous page. However, controls by default are protected and therefore completely inaccessible from the other page. Now, you can change the accessibility of a control if your design style uses code-behind. If not, be prepared for further heartache. For example, while accessing the PreviousPage property, I sometimes get:
      Unable to cast object of type 'ASP.cops_aspx' to type 'ASP.cops_aspx'
    9. Why is the DataGrid Edit Columns dialog fixed size? If I have 100 columns in the table, then I only get a teeny tiny window to play with.
    10. A DateTimeValidation control would be handy (ie anything which DateTime.TryParse says is valid)
    11. The <ControlParameter> elements for the Data Binding should have an option to Trim whitespace from the incoming parameter.
    12. A drop-down calendar has been conceptually missing from ASP.Net since 2000. There really should have been one in this release.
    Having said all that, I'm still a big fan of ASP.Net - I think it's a wonderful environment.

    Also, don't assume I think ASP.Net v2 has too many bugs. I reserve that accolade for WinForms v2 & the WinForms designer.

    Sponsor
  • Google redefines XML

    Google Base has decided to redefine XML (specifically XML namespaces)
    xmlns:[prefix]="http://base.google.com/cns/1.0"
    Google Base providers have the option of creating their own prefixes. The "g:" prefix is reserved for the Google Base XML module and should not be used.
    In what sense is an XML namespace prefix ever reserved? It just doesn't make sense.


    In other nitpicking, why does Google Base allow a dateTime datatype, yet doesn't specify a timezone?
    Date and time for an event, in format YYYY-MM-DDThh:mm:ss
    At first guess it would seem the Google Base team don't understand XML. However, a lot of Google Base comes very close to what Adam Bosworth has been talking about for the past 18 months - and he certainly does understand XML (he founded the webdata team at Microsoft).
    Sponsor
  • Beta2 here we come!

    Following my rant about LINQ and VS.Net Beta2 back on the 14th September, I'm pleased to report Microsoft finally delivered my copy of VS.Net Beta2.

    I'm dumbstruck. Not only does it take them 6 weeks to send a DVD through the post, but it has taken so long the DVD is already obsolete.
    Sponsor