Cool .NET Tips and Tricks #11
By Dr. Dexter Dotnetsky
Printer - Friendly Version
Dr. Dotnetsky

Ahoy, there me Hearties! It's Dr. Dotnetsky, back from a nice vacation. Remember "vacations"? You don't work, often you go off to fun places, and you enjoy yourself. The idea is, you're supposed to come back to work recharged and your productivity is higher, and your blood pressure lower, and all those good things. Now Dr. Dotnetsky knows of some people who just don't "get it" about this here vacation thing: they stay at home, they check their email from work 16 times a day, they try to give orders to co-workers and subordinates (usually via email, even though they are not at work and haven't the slightest idea of what may actually be going on), you can't get rid of them no-how, and they are just absolutely miserable. Geez!  Get a life, OK? Even Democrats take vacations!

Now let's see, where was I... Oh yes! Remember Windows XP and how I showed you that you can have multiple web sites on it just like Windows Server? Well, guess what! I've found a trick that can get you past the 10 connection limit on IIS 5.1 too!

In your \Inetpub\Adminscripts folder are a bunch of cool vbs admin scripts for IIS. If you issue the following command at a DOS prompt:

cscript adsutil.vbs set w3svc/MaxConnections 40

you will increase the Windows XP Professional connection limit from 10 to 40. I've seen several hacks describing this and some say that anything less than 40 will work. An easy way to test this is to fire up Homer or App Center Test, and set up a 2 minute test with say 39 separate threads on the page of your choice. It should be a page that ties up a thread for a while.

If you look at your report and it doesn't show any refused connections, then you know it worked. Note that this is supposed to be an IIS Metabase, not a Registry setting. So, you could probably try the MS MetaEdit Metabase editor tool to look at this.

Easy Javascript Encryption / Decryption of Text

While on vacation, I was playing around with a way to easily encrypt and decrypt text with Javascript. The simplest method is to simply XOR (Exclusive Or) each character against a known value from say 1 to 255. When you do this, you can pass the encrypted character back into the same method and get back the original character. However, this doesn't provide you with an encryption key. So I came up with what I think is a better method. We take a hash code of the key that you choose and modulus it against 255 so we get a value in the ASCII range, then we use that as the predicate value for the XOR. In addition, I Hex it so the characters will all be "safe". So the phrase, "This is some sample text" XOR-ed against the hash of a key "dotnetsky" would look like so: "bc80819bc8819bc89b87858dc89b898598848dc89c8d909cc6".

You can try it out here, and the source code is of course available by View Source on the page. You could use this, among other things, to encrypt your messages in a web-based chat service by sharing the key with your chat partner.

F1 is your friend - and ours too!

I don't mean to sound rude, but we sure get a lot of really inane posts here at the old forums of people asking questions and then waiting around for email notification that somebody has posted an answer when all they really had to do is is highlight the term or phrase in their code editor and hit the F1 key... We had one guy say that he didn't even install the help system (which comes free with the product!) for VS.NET! Dr. Dotnetsky loves a challenging question, and will bend over backwards to find a suitable answer (in the rare instance that I don't already know it, hehe) but you know the old Chinese proverb that if you "give a man a fish you feed him for a day, if you teach him to fish you feed him for a lifetime"? Please don't make posts asking us to write code for you. We'll help you understand the concept, point you in the right direction, and a lot more. But we're not gonna be running around here holding a roll of fresh toilet paper waiting for ya to ask us to .... 'Nuff said!

XMLSerializer XSD class Generation with Properties

One of the issues in using XSD to generate C# classes from the Schema (XSD) of a DataSet is that you can't customize it to create properties instead of fields. Daniel Cazzulino (and some others) have discovered that you can take control of this on your own by using the poorly documented but public methods in XmlSchemaImporter and XmlCodeExporter , both from the System.Xml.Serialization namespace.

Here's some untested but pretty much feature-complete code I threw together from Daniel's blog to illustrate how to do this:

   MemoryStream myStream = new MemoryStream();
     System.Xml.XmlTextWriter MyXmlTextWriter = 
      new System.Xml.XmlTextWriter(myStream, System.Text.Encoding.Unicode);
   // Write the schema into the writer and close.
   thisDataSet.WriteXmlSchema(MyXmlTextWriter );

// Load the schema to process.
XmlSchema xsd = XmlSchema.Read(myStream, null );

// Collection of schemas for the XmlSchemaImporter
XmlSchemas xsds = new XmlSchemas();
xsds.Add( xsd );
XmlSchemaImporter imp = new XmlSchemaImporter( xsds );

// System.CodeDom namespace for the XmlCodeExporter to put classes in
CodeNamespace ns = new CodeNamespace( "Generated" );
XmlCodeExporter exp = new XmlCodeExporter( ns );

// Iterate schema items (top-level elements only) and generate code for each
foreach ( XmlSchemaObject item in xsd.Items )
  if ( item is XmlSchemaElement )
    // Import the mapping first
    XmlTypeMapping map = imp.ImportTypeMapping(
      new XmlQualifiedName( ( ( XmlSchemaElement ) item ).Name, 
      xsd.TargetNamespace ) );
    // Export the code finally
    exp.ExportTypeMapping( map );

// Code generator to build code with.
ICodeGenerator generator = new CSharpCodeProvider().CreateGenerator();

// Generate untouched version
using ( StreamWriter sw = new StreamWriter( @"C:\Temp\Generated.Full.cs", false ) )
// do the same thing as above after running it through the FieldsToProperties Method below---
// convert the fields to properties
    ns, sw, new CodeGeneratorOptions() );

The CodeNamespace variable ns contains a full CodeDom hierarchy with all the types 
that were generated. Therefore, we can easily customize their definitions by adding attributes, custom methods, etc. */
// FieldsToProperties method static void FieldsToProperties(CodeNamespace ns) { // Copy the colletion to an array for safety. We will be // changing this collection. CodeTypeDeclaration[] types = new CodeTypeDeclaration[ns.Types.Count]; ns.Types.CopyTo( types, 0 ); // Turn fields into properties foreach ( CodeTypeDeclaration type in types ) { // Copy the collection to an array for safety. We will be // changing this collection. CodeTypeMember[] members = new CodeTypeMember[type.Members.Count]; type.Members.CopyTo(members, 0); foreach ( CodeTypeMember member in members ) { // Process fields only. if ( member is CodeMemberField ) { CodeMemberProperty prop = new CodeMemberProperty(); prop.Name = member.Name; // Rename field member.Name = String.Concat( "_", member.Name.ToLower() ); prop.Attributes = member.Attributes; prop.Type = ( ( CodeMemberField )member ).Type; prop.HasGet = true; prop.HasSet = true; // Add get/set statements pointing to field. prop.GetStatements.Add( new CodeMethodReturnStatement( new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), member.Name ) ) ); prop.SetStatements.Add( new CodeAssignStatement( new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), member.Name ), new CodeArgumentReferenceExpression( "value" ) ) ); // Copy attributes from field to the property. prop.CustomAttributes.AddRange(member.CustomAttributes); member.CustomAttributes.Clear(); // Make field private member.Attributes = MemberAttributes.Private; // Finally add the property to the type type.Members.Add( prop ); } } } }

And that's it for me this time, Kidzies! Have a happy and productive VACATION:

  1. [n]   the act of making something legally void
  2. [n]   leisure time away from work devoted to rest or pleasure
  3. [v]   spend or take a vacation


Dr. Dexter Dotnetsky is the alter-ego of the forums, where he often pitches in to help answer particularly difficult questions and make snide comments. Dr. Dotnetsky holds no certifications, and does not have a resume. Always the consummate gentleman, Dr. Dotnetsky can be reached at  Dr. Dotnetsky's motto: "If we were all meant to get along, there would be no people who wait for all the groceries to be rung up before starting to look for their damn checkbook."