What .NET issue have you run into that wasted hours and hours of your time, was nearly impossible to debug, and could have been easily avoided if you had known just one quirk of the framework?
I've spent many nights wondering why System.Xml.Xslt.XsltLoadException is an internal class, when XsltCompiledTransform.Load() throws it in the event that the XSLT you supply it is malformed or contains a syntax error.
For ASP.net, if you ever happen to override the Render event for a page, but the page uses Response.Write in the HTML itself... well, get ready to spend some hours trying to figure out why it never shows up in the right place...
Returning a DataTable over a WCF service without naming the DataTable. The default constructor, DataTable dt = new DataTable();
will leave the DataTable unnamed and unnamed DataTables are not serializable. Instead of receiving a serialization error, testing my service gave only a "Connection forcibly closed by host" exception.
It was a while ago but I wasted a lot of time trying to properly bind nested objects to a web form.
I think I eventually found a way to get it working using the CslaDataSource, but that required using the CSLA.NET framework.
Took me several hours to figure out this exception: "A generic error occurred in GDI+" when saving a bitmap - turns out that if you load a bitmap from a stream, then dispose of the stream, then you'll get this error when you call bitmap.Save(). Dispose of the stream after saving, if you can.
The XmlDocument
class in System.Xml
.
If there is a DOCTYPE declaration on the first line of an HTML document, the XmlDocument tries to get the definition. This is an undocumented "feature" if I remember correctly which is useless for HTML. It doesn't seem to do the same for XML namespace URLs however.
This caused problems for me when generating several HTML reports that had to parse an existing HTML document. On my company's slow network, the DOCTYPE lookup was painfully slow. It was so slow I added a loading dialog just so that the user would know how long they had left.
When the app. was run without an internet connection, the DOCTYPE lookup would throw an exception which was not documented in the MSDN documentation.
The final solution was to read the file in as test, check if there was a doctype and remove it, then load the file as XML. This made the app. so fast that the loading dialog I wrote became useless. It would flash on the screen for 1-2 seconds at most then the process was finished.
This was one of the biggest time sinkholes I ever experienced because it was also one of my first enterprise programming projects so the solutions I developed to get around the slow DOCTYPE lookup took time to learn and write, then I ultimately found out that my solution was totally pointless...
Rolling my own HTMLEncoder :P Really sucked when I found out it was available out-of-the-box in System.Web.
FtpWebClient has a known issue with allegedly "non-standard" secure FTP server responses (you know, the kind used by a lot of huge banks). And by known, I mean 'complained about and reported as a bug over 2 years ago and never fixed'. As best I remember, it seems that if the secure FTP server replies with anything other than "\" after authentication (to indicate the current directory), like, for example, replying with "\userdefaultdirectoryname" instead, then FtpWebClient closes the connection and throws an exception - and there is nothing the programmer can do to change this behavior.
The lesson learned here was: now, any time I start to use a new (to me) class or capability of .NET (or any other language), I first google about it along with the keywords "bug OR issue OR problem OR exception OR failure OR hang..." to see if there are any lurking gotchas!
In C# 2.0, the All
member of the FlagsAttribute
-style DragDropEffects
enum, contrary to what the name of the member implies, does not include the DragDropEffects.Link
member.
At the time, I had assumed that DragDropEffects.All was equal to:
Copy | Link | Move | Scroll
But it is actually defined as:
Copy | Move | Scroll
(despite the existance of the Link
member.)
It does look like this has been addressed in C# 3.5. But in C# 2.0, the fact that the All
member did not contain the Link
bit was not at all clear from the documentation (quite possibly a bug).
I blogged about this issue at the time that I had originally encountered it (late 2006).
Ternary Operator in C# doesn't know how to handle Nullable types. For example following won't work:
int? myIntValue =
dataReader.IsDBNull("ColumnName") ? null :
dataReader.GetInt32("ColumnName");
Even though following is legal and works:
int? myIntValue;
if(dataReader.IsDBNull("ColumnName"))
{
myIntValue = null;
}
else
{
myIntValue = dataReader.GetInt32("ColumnName");
}
The correct way is to cast the result, i.e :
int? myIntValue =
dataReader.IsDBNull("ColumnName") ? (int?)null :
(int?)dataReader.GetInt32("ColumnName");
(Note: This annoyance existed in C# 2.0. For more of Nullable Type annoyances see: http://sab39.netreach.com/Blog/Blog/12/vobId__172/pm__18/)
In .NET 1.0, web service objects (client-side) had a timeout property that didn't work as you would expect (the timeout covered the length of time the object would wait between receiving packets, not the length of time it would wait for the call to return), so you had to roll your own grisly, timer-based hack to abort a web service call manually after a set period of time if you didn't want your app to lock up for 2 minutes when the server was unavailable.
This problem was fixed in .NET 2.0, but I didn't realize it, and I kept migrating the grisly hack from project to project for a couple years, long after it was no longer necessary. Bonus: it didn't even work anymore with .NET 2.0.
I had to spend more time than I wanted implementing my own inplace tooltip for use in lists because the .NET one doesn't support having the font changed (and pre-2.0, didn't support being inherited either, or the transparent extended window style).
var adEntry = new DirectoryEntry("LDAP://...");
adEntry.DoSomething(); // Throws meaningless COMException! Sometimes a different one!
adEntry = new DirectoryEntry("ldap://...");
adEntry.DoSomething(); // Works.
This is not a quirk of the framework, but:
Cross-thread operations in C# 1.0. There are so many weird bugs because I didn't know better :)
The C# 2.0 compiler saved my day by finding these at compile-time.
Configuration files, particularly with shared class library projects, seem more difficult to get implemented than they should be.
I just discovered the asp:Menu control after trying all sorts of more complicated ways to do it.
One issue that was a great time sink for me was DateTime with regard to daylight savings time. For example, if I create a date:
DateTime someDateTime = new DateTime(2008, 1, 1);
If I am in EST it will be the equivalent of whether I was in day light savings time or not for that moment in time rather than what my current day light savings time is. In other words, if I'm in day light savings time now and the date time I'm representing with the object is not within that time frame it will respect the timezone of that period in time.
This is particularly an issue when you are trying to do date time math (such as converting to UTC, etc) and find the time spans between two points in time -- it may very well be off by an hour.
I've just wasted two days getting some WPF templating to work as I wanted. See my question over there. In the end I worked around this by modifying the parent and buying two WPF books to burn off my frustration.
I had to design a series of ASP.NET pages which displayed a varying number of DataGrid controls created dynamically at run-time (back in .NET 1.1). When designing my app, I assumed I could allow the programmer to drop a single DataGrid control on the page to use as a template on which he could set the appearance, colors and CSS properties. I planned to reuse this grid as a template at run-time when creating other grids dynamically and delete the template at the end of my request.
My assumption was that I could do this:
for i = 1 to nGrids
grids[i] = new Grid(templateGrid) // assuming copy constructor semantics
delete templateGrid
or
for i = 1 to nGrids
grids[i] = templateGrid.Clone()
delete templateGrid
Copying one variable to another is an elementary operation. After all it was one of the very first things I learned in programming.
No such luck!! Not in ASP.NET 1.1 at least. As luck would have it, I had emailed my grand design document to my team of eager freshmen without checking first!
It sounds stupid and simple, but a lot of string operations like String.Split, String.Concat, etc. I was writing an EDI parser and was manually creating all of these basic string functions that already all existed. Now, I tend to google a lot more. It's saves a ton of time.
Starting in .Net 2, when an application was compiled with the debug configuration, it would hold on to a small piece of memory every time you instantiated a class which had an event defined in it. Even if you didn't raise the event. It would hold onto this memory, and never release it. After running the ASP.Net application for a couple hours it would throw a OutOfMemoryException, restart the web service, and continue chewing through memory again. took many many hours of debugging, and a memory profiling to figure out where the problem was.
Building dynamically generated UIs in ASP.NET. I kept banging my head against the wall until I learned to fully grok the page lifecycle.
Running "Build Solution" on a solution with dozens of projects...
Waiting for the WinForms visual designer to respond...
... both have, when combined, taken up days of my life...
ASP.NET:
Automatic ID generation + JQuery
Outputting clientside to cater for ASP.NET's automatic ID generation with form elements for use with JQuery, when all that was really required was to subclass the form controls (TextBox, Button etc.) and force the IDs.
Unless you have a really heavily nested setup or lots of spaghetti from drag and dropped created webforms, forcing your own IDs is the solution.
- Configuring MSBuild and/or TFSBuild script for a complex solution
- Creating robust installer with WiX
- Managing database change scripts
Messing around with ASP.NET validators/ValidatorCalloutExtender with dynamic content. Yes, there is a ValidatorEnable() javascript property, but when you use the ValidatorCalloutExtenders you run into some issues. The correct solution is...
...
...
Anyone?
Bueller?