.Net ramblings
# Sunday, 05 March 2006
The Microsoft Origami Project and back to hand-writing
Screenshot of origami hand-held (probably)For anyone who hasn't heard the buzz about Microsoft's Origami Project, take a look at this vido file to get a glimpse of what it is probably about.  the video is a year old but i reckon it's a fairly accurate preview of the real thing.  the thing that really struck me about the video was that people were writing hand-written notes to each other, in emails, messages etc.  What a bizarre idea.  Yeah we've had PDA's without keyboards for a long time, but they only ever had a very small user base, because of the need to learn a new form of writing that the palmtop could understand. traditional touch screen hand-writing technology is woefully slow to right messages of any length on.   if the Origami device becomes mainstream, which i think it probably will, then it is quite a departure from the way we interact with computers since they were invented. 

personally i do so much typing and so little hand-writing that i tend to think about pen + paper as an old thing i left behind many years ago.  But... when you stop to think about it, emails and 'typed' communications lose a huge amount of personality compared with traditional hand-writing.  You can't identify the writer of an email based on the style of writing, like you can with a hand-written letter from someone you know well.  emails are usually so limited in expression that we have created a whole new culture of emoticons to bridge the gap, but it's hard not to come across as cheesy and immature when you write things like :-)  :O)   :^) etc...

Screenshot of origami hand-held (probably)We've all got very good at typing, because computers understand fixed characters much better than squiggles of writing.  Typed content is also more efficient in terms of storage size, and search capabilitiy.  You still can't meaningfully scan a JPEG of a hand-written letter and be sure to get all the words out of it.  But it looks like that is the way Microsoft are headed.  It is really a massive shift if this takes off, because the modern computer experience is built around typed content.  The internet would be nothing if we had to wade through volumes of illedgible hand writing before we found the information we wanted.  Obviously this is looking at the extremes, and we'll always have typed content with us, but to me it seems like this is the first mainstream introduction of mixed text content arriving on our desktops, from the pen and the keyboard. 

In the grand scheme of things, i actually think typed content will be a blip on the radar of the way we record text information.  For thousands of years we've been writing things down, and i can't think of any good idea for why that should all be thrown out the window, except technology limitations.  It looks like Microsoft are challenging those limitations.

Sunday, 05 March 2006 12:44:07 (GMT Standard Time, UTC+00:00)  #    Comments [0]  General

# Friday, 03 March 2006
Compiling Asp.Net 2.0 to a single assembly
I wanted to install my web application assembly into the GAC, but this is made more complicated by the multitude of assemblies produced by VS when i publish the web site.  On the newsgroups, i found some talk of a tool called Merge_Aspnet.exe but i couldn't find it anywhere.  Eventually i found it as a download on MSDN, it is bundled as part of the Web Deployment Projects.  You install it, and then right-click your project in VS and you should see a new menu item "Add Web Deployment Project".  I am baffled as to why they didn't just add a new project type in the list of projects under "Deployment".  There is a link to "Search online templates" so i think it should really be available there.  but it looks like MS did a hack just to add in a new item to the project context menu.  but it works... so i'll stop complaining. 


Friday, 03 March 2006 15:43:20 (GMT Standard Time, UTC+00:00)  #    Comments [0]  .Net General | Asp.Net

# Saturday, 18 February 2006
HowTo: Get Write Access to an ApplicationData folder in ASP.NET
In a web application i'm working on, i needed to get write access to a folder, and preferably not the temp folder because the data should be kept reasonably safe from being deleted accidentally.  If it was a windows-forms application this would be easy, i would just use Application.UserAppDataPath.  So i thought for asp.net, i could use Environment.SpecialFolder.ApplicationData but this maps to the folder for the current user logged on to Windows, not the process running the web site, or the authenticated web site user.  So i just skip up 2 parent directories from that, and use the current Principal.WindowsIdentity to find the actual process running ASP.NET, and then deduce the correct folder, which by default will have write permissions for Asp.Net.

Here is the code:
string Username = Path.GetFileName(System.Security.Principal.WindowsIdentity.GetCurrent().Name).Replace(" ", "");
string UserAppFolder = String.Format(@"{0}\{1}\Application Data", Directory.GetParent(Directory.GetParent(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)).FullName).FullName, Username);

By the way, the use of Path.GetFileName is entirely intentional, it solves the case where the current user is "NT Authority\Network Service" by yielding "Network Service", which is what we are interested in.  

This will hopefully come in handy for my 'zero configuration' idea for the application.  Next time you need a write folder, it may be a good idea to use this instead of making users specify write permissions for a custom folder. 

Saturday, 18 February 2006 19:11:26 (GMT Standard Time, UTC+00:00)  #    Comments [2]  Asp.Net

# Friday, 17 February 2006
FtpWebRequest with ProgressBar [C# Ftp]
Screenshot of upload operationhi,
i was delighted to see .Net 2.0 has an excellent class for working with FTP.  looking back i can't believe it wasn't part of 1.1. 

i noticed there was no built-in support for reporting the progress of an FTP operation to a user interface.  I needed this functionality in an app i'm working on so i built a class and i'm posting it here in case anyone is interested.

The class FtpProgress inherits from BackgroundWorker, so you just drag an FtpProgress component onto your form, hook up events for Completed and ProgressChanged, and your laughing.  There is a mini class called FtpSettings which stores all the connect info etc to pass in as a paramter to the RunWorkerAsync() method.

I have a variable called 'ChunkSize' which determines the size of each buffer written to the FtpWebRequest output stream.  It is set to 4k by default, and you can increase this if you want for very fast networks but i don't think it will make much difference.  I think the overhead is negligible.

Download the source code and demo application [30 k].

It only does upload, so if you want download functionality, you can do the mirror-image of the upload code, i.e. instead of writing buffers to the output stream, read it from the input stream, or however that would work :) 

here is all the code you need to start an Upload, and report progress:
private void btnUpload_Click(object sender, EventArgs e)
{
// create a new FtpSettings class to store all the paramaters for the FtpProgress thread
FtpSettings f = new FtpSettings();
f.Host = this.txtHost.Text;
f.Username = this.txtUsername.Text;
f.Password = this.txtPassword.Text;
f.TargetFolder = this.txtDir.Text;
f.SourceFile = this.txtUploadFile.Text;
f.Passive = this.chkPassive.Checked;
f.Port = Int32.Parse(this.txtPort.Text);
this.ftpProgress1.RunWorkerAsync(f);
}

private void ftpProgress1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.toolStripStatusLabel1.Text = e.UserState.ToString(); // the message will be something like: 45 Kb / 102.12 Mb
this.toolStripProgressBar1.Value = Math.Min(this.toolStripProgressBar1.Maximum, e.ProgressPercentage);
}

Friday, 17 February 2006 18:09:05 (GMT Standard Time, UTC+00:00)  #    Comments [29]  .Net General | .Net Windows Forms

# 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