.Net ramblings
# Thursday, 02 February 2006
Using Xml DOM with MetaBase.xml
For some reason i can't get SelectNodes to work with the IIS 6 MetaBase.xml file.  It just doesn't return any matches.  I think the structure may be non-standard or too complex, or else i'm not using it right.  but in any case, I worked around the problem by opening the file with File.OpenText and using Regex to parse out the nodes i'm interested in, namely the IISWebServer nodes.

string MetaBase = "";
using(StreamReader sr = File.OpenText(ConfigurationManager.AppSettings["MetaBasePath"].ToString()))
MetaBase = sr.ReadToEnd();

foreach(Match m in new Regex(@"(?x:)<IIsWebServer[^>]*>.*?</IIsWebServer>", RegexOptions.IgnoreCase).Matches(MetaBase))
{
XmlDocument doc = new XmlDocument();
string IisCode = "", ServerBindings = "", ServerComment = "";
doc.LoadXml(m.Groups[0].Value);
XmlElement node = doc.DocumentElement;
// now you can access the node attributes
...


Thursday, 02 February 2006 13:38:34 (GMT Standard Time, UTC+00:00)  #    Comments [0]  .Net General | .Net Windows Forms | Asp.Net | Windows Server

CheckBoxList: Select All / None client-side script
<script language="javascript" type="text/javascript">
function Select(Select)
{
for (var n=0; n < document.forms[0].length; n++)
if (document.forms[0].elements[n].type=='checkbox')
document.forms[0].elements[n].checked=Select;
return false;
}
</script>


Select <a href="#" onclick="javascript:Select(true)">All</a> | <a href="#" onclick="javascript:Select(false)">None</a>


Thursday, 02 February 2006 13:25:33 (GMT Standard Time, UTC+00:00)  #    Comments [7]  Asp.Net

# Monday, 30 January 2006
Fix: Unable to validate data, MachineKey.GetDecodedData
i kept getting these sporadic error messages on my web applications and i could never figure out why. 
Unable to validate data at
System.Web.Configuration.MachineKey.GetDecodedData(Byte[] buf, Byte[] modifier, Int32 start, Int32 length, Int32& dataLength) at
System.Web.UI.LosFormatter.Deserialize(String input)
searching the net just reveals a troop of similarly frustrated users without solutions.  but today i found the actual reason why, and the work-around.
this excellent post on experts-exchange has the answer.  apparently it happens when users leave a page open for a long time, and then cause a post back.  something to do with the machine key being automatically generated and it changes before the user causes the postback, and it can't validate it then. 
the fix is to set a static machine key. 
There is a kb article with some code to generate a key for you, + instructions.  

Sorted.


Monday, 30 January 2006 22:53:44 (GMT Standard Time, UTC+00:00)  #    Comments [13]  .Net General | Asp.Net

ADOX + Excel: bogus worksheets
a web site i'm working on imports excel documents, and does some processing on them for importing into a database.  I use the code from this post to do the importing, and it works nicely.  I recently came across a problem where i was encountering duplicate records, and it took me ages to figure out why.  Apparently a 'named range' of cells in a worksheet is treated as a Table by ADOX.  so you get more than you bargain for when you iterate through the tables in the resulting DataSet. 
I was able to work around the problem by discarding any tables that do NOT end in the dollar $ character.


Monday, 30 January 2006 15:30:12 (GMT Standard Time, UTC+00:00)  #    Comments [1]  .Net General | Asp.Net | Database

# Wednesday, 25 January 2006
Crystal Reports TextObject ignores newline, carriage return, \r\n
I have a text object in my crystal report, and i set the value programatically for it, using something like this:
(rpt.Section3.ReportObjects["txtDate"] as TextObject).Text = DateTime.Now.ToShortDateString();
this works fine, until you put a string with line breaks inside it, specifically \r\n or the carriage return character.  This is a bug in CR for .Net, you can read the official blurb here.  the work-around code they post is in VB, and it made no sense to me when i read it.
what they actually do is make you change the TextObject into a FormulaField (you have to view the 'Field Explorer' tab next to the toolbox, and drag on a Formula Field).  Then you set 'CanGrow' to true, and then you go back to your code, and do the most arcane work-around i've ever seen.  you set the formula to your text string, but you must surround it in single quote characters, and replace \r\n with some inline managed code as follows: ' + chr(10) + '
when i first read this, i thought they had made a syntax error, but this is the way to do it, and it works.  the new format for setting the formula field is:
rpt.DataDefinition.FormulaFields[0].Text = "'" + YourString.Replace("\r\n", "' + chr(10) + '") + "'";


Wednesday, 25 January 2006 13:52:05 (GMT Standard Time, UTC+00:00)  #    Comments [16]  .Net General | .Net Windows Forms | Asp.Net

# Thursday, 19 January 2006
The best free zip / compression software: 7-zip
i gave up using winzip a long time ago because it is way too 'naggy' in terms of making you register. 
windows 2000/XP has its own built-in 'send to > compressed folder' option when you right-click a file or rolder.  but the windows zip software is pretty rubbishy.  it takes forever to set or remove passwords on archives, or to simply delete a small file from an archive can take 20 seconds. 

by far the best zip software i have used is called 7-zip and you can download it for free at http://www.7-zip.org
it is lightning fast, and although the custom zip format '7z' does not appear to be anything great, especially because its not compatible with other zip software, set the program to use normal 'zip' by default and it works great. 


Thursday, 19 January 2006 11:57:28 (GMT Standard Time, UTC+00:00)  #    Comments [0]  General

# Friday, 13 January 2006
Localization: Setting text direction for a web page
This is the first time i have been asked to add localization support for a content management system.  One of the supported languages is Arabic, which is usually written right-to-left.  to achieve this, you could obviously change your CSS or markup with something like <p align="right"> but this is not the way to do it.

there is an attribute in the HTML tag that controls the direction of text (and controls) on the page, called 'dir', which can take values 'ltr' or 'rtl', corresponding to "left-to-right" and "right-to-left" respectively.  The advantage of setting this property is that it instructs the browser to render all direction-related elements of the page accordingly.  for example, in RTL mode, when you type in a text box, the cursor stays flush to the right and the characters spread across to the left as you type.  similarly drop-down-menu's are rendered differently, as are bullet points, and the browser scrollbar.  these changes are shown in the screenshot below:



In this content management system, i set the direction based on the user's language setting, stored in a cookie.  to set the DIR attribute programatically, i suggest the following HTML tag in your Master/Template aspx page:
<html xmlns="http://www.w3.org/1999/xhtml" runat="server" id="htmlTag">
Then you can access it in the code behind, like so:
protected void Page_Load(object sender, EventArgs e)
{
this.htmlTag.Attributes.Add("dir", Util.HtmlDir);
...
and then the method to determine the direction, based on the cookie. note that 'Language' in my code is an enumeration.
/// <summary>
/// Returns rtl or ltr, depending on the current language setting
/// </summary>
public static string HtmlDir
{
get
{
Language lang;
try
{
lang = (Language)Enum.Parse(typeof(Language), HttpContext.Current.Request.Cookies["Language"].Value.ToString());
}
catch
{
// cookie not present, default to english.
lang = Language.English;
}
switch(lang)
{
case Language.Arabic:
return "RTL"; // right to left
default:
return "LTR"; // left to right
}
}
}

public enum Language
{
English,
Arabic,
...
}

for more information on languages and their directions, and related browser issues, see this excellent article from W3C


Friday, 13 January 2006 16:28:16 (GMT Standard Time, UTC+00:00)  #    Comments [2]  Asp.Net

# Thursday, 12 January 2006
Fix: GridView DataFormatString not applied
for some bizarre reason, you have to set HtmlEncode=false on a bound column in a gridview, to get the DataFormatString to work.
i hope this helps somebody else staring at their gridview in disbelief as to why it doesn't work by default!


Thursday, 12 January 2006 16:01:38 (GMT Standard Time, UTC+00:00)  #    Comments [64]  Asp.Net

# Monday, 09 January 2006
Xml Serialization: Properties left out without 'set' accessor
I ran into a frustrating problem today where some properties of my objects weren't getting serialized.  I noticed it was the ones without 'set' accessors.  I didn't want to put set accessors in because the properties should be read-only, but apparently the xml serializer needs the set accessor to de-serialize. 
there is a good discussion on it on this thread.
Luckily we can use the ReadOnlyAttribute setting on the property to prevent it being modified by a programmer at design time.
or you can use the Soap serializer instead of xml, whatever that is.


Monday, 09 January 2006 17:57:34 (GMT Standard Time, UTC+00:00)  #    Comments [0]  .Net General | .Net Windows Forms | Asp.Net

Great Application: Event Monitor (free)
since i installed .net 2.0 on my web server, i sometimes forget that you can't have .net 1.1 and .net 2.0 running in the same application pool, and then IIS kindly stops all the web sites if i make this mistake when configuring a new website. 
so i wanted to get an email about it if i forget, and went looking on d'internet for a decent little app to monitor events and email me if anything goes wrong. 
the best one i found is called Event Monitor, and it is a great little program.  nice enough UI and good filtering ability.

i set it up to monitor for events with id 1062 (the one that happens when i put .net 1.1 and 2.0 in the same app pool by accident..) and now i get an email straight away if it happens.  2 hours of tic-tac freshness in just 2 calories. great huh?!


Monday, 09 January 2006 15:09:43 (GMT Standard Time, UTC+00:00)  #    Comments [0]  Windows Server