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

Howdy, Dr. Dotnetsky here again, with some cool tricks and info to feed yer hungry mind on! Yum!

Removing Advertisements from MSN Messenger 6.0

In order to pay for the service, Microsoft send advertisments in the form of animated images
to all users of their MSN Messenger service. While these do not constitute a security risk or
consume much bandwidth, you may wish to disable them. Microsoft, of course, do not provide an
easy option to do this, but there is a way.



To remove the inline advertisements from MSN Messenger 6.X:

  • If MSN Messenger is running, exit the application.
  • Open Windows Explorer and navigate to your user profile area. This is usually found in:
    x:\Documents and Settings\username
  • From your user profile folder, navigate to:
    Application Data\Microsoft\MSN Messenger
  • You may have to enable viewing of hidden files and folders within Tools -> Folder Options in order to see these directories.
  • Within the MSN Messenger folder, there will be at least one sub-folder the name of which will be a number. The number corresponds to your MSN Messenger sign-on ID, although not been able to establish the exact connection.
  • If you have used more than one sign-on ID, there will be one folder per sign-on used. The following instructions should be repeated for each sign-on folder.
  • Navigate to the sign-on folder.
  • Using notepad or a similar text editor, open up ConfigCache.Xml.
  • Delete the contents of the file between <MsgrConfig> </MsgrConfig> the tags. These tags will be the first and last entries in the file.
  • Save ConfigCache.Xml, and exit the text editor.
    In Windows Explorer, right click upon ConfigCache.Xml and choose the Properties entry from the pop-up menu.
  • In the Attributes section, check the Read Only tick-box. Click OK to close the Properties window.
  • "Tadaa!" --MSN Messenger will no longer display advertisments! Dr. Dotnetsky would not play you wrong, kiddies!

ASP.NET "Low Level" worker request access

Now anyone who reads Dr. Dotnetsky's occasional rants here on the eggheadcafe.com channel knows by now that I think Blogs are for the Birds. However, I did say in a recent babble of mine that there were exceptions, and one that I feel compelled to make mention of is put out by a real thinker, Daniel Cazzulino. Daniel is the guy originally from Deverest fame who, with his buddies, put out some remarkable code at SourceForge called "NMatrix", and he is also the author of the original Wrox book on ASP.NET Server Controls who wrote the stunning "extra" PDF bonus chapter that you have to download separately (which chapter, in the Doctor's humble opinion, is worth more than the entire rest of the book). To paraphrase Daniel's most enlightening discovery:

Sometimes you need low level information about the current request in a web application, such as the IP address of the physical network adapter the request came through (cool in clustered multi-NIC servers), or some other weird stuff you can't find in the higher-level view provided by HttpRequest , HttpResponse and friends.
HttpContext implements IServiceProvider , which means you can ask for services with the following code:

IServiceProvider provider = (IServiceProvider) HttpContext.Current;
// Get the request
HttpRequest util = (HttpRequest) provider.GetService(typeof(HttpRequest));

The one thing you can get that there's absolutely NO other way of getting, is the current HttWorkerRequest:

// Get the worker
HttpWorkerRequest wr = (HttpWorkerRequest) provider.GetService(typeof(HttpWorkerRequest));
// Get the NIC address
string addr = wr.GetLocalAddress();

Another very cool use is to retrieve known header values. Usually, you just get the header from the Request.Header collection by its name:

// Would return "Keep-Alive" if enabled.
string cn = Request.Headers["Connection"];
// Would return "gzip, deflate" for example.
string enc = Request.Headers["Accept-Encoding"];
// but that's prone to errors, and you have to sort of guess the casing, etc. This is the cool way:
// Get the worker
HttpWorkerRequest wr = (HttpWorkerRequest) provider.GetService(typeof(HttpWorkerRequest));
string cn = wr.GetKnownRequestHeader(HttpWorkerRequest.HeaderConnection);
string enc = wr.GetKnownRequestHeader(HttpWorkerRequest.HeaderAcceptEncoding);

Now here is a listing of the Class members, for those who wish to experiment further:

Public Constructors

HttpWorkerRequest Constructor [To be supplied.]

Public Fields

HeaderAccept Specifies the index number for the Accept HTTP header.
HeaderAcceptCharset Specifies the index number for the Accept-Charset HTTP header.
HeaderAcceptEncoding Specifies the index number for the Accept-Encoding HTTP header.
HeaderAcceptLanguage Specifies the index number for the Accept-Language HTTP header.
HeaderAcceptRanges Specifies the index number for the Accept-Ranges HTTP header.
HeaderAge Specifies the index number for the Age HTTP header.
HeaderAllow Specifies the index number for the Allow HTTP header.
HeaderAuthorization Specifies the index number for the Authorization HTTP header.
HeaderCacheControl The index that represents the HTTP Cache-Control HTTP header.
HeaderConnection Specifies the index number for the Connection HTTP header.
HeaderContentEncoding Specifies the index number for the Content-Encoding HTTP header.
HeaderContentLanguage Specifies the index number for the Content-Language HTTP header.
HeaderContentLength Specifies the index number for the Content-Length HTTP header.
HeaderContentLocation Specifies the index number for the Content-Location HTTP header.
HeaderContentMd5 Specifies the index number for the Content-MD5 HTTP header.
HeaderContentRange Specifies the index number for the Content-Range HTTP header.
HeaderContentType Specifies the index number for the Content-Type HTTP header.
HeaderCookie Specifies the index number for the Cookie HTTP header.
HeaderDate Specifies the index number for the Date HTTP header.
HeaderEtag Specifies the index number for the ETag HTTP header.
HeaderExpect Specifies the index number for the Except HTTP header.
HeaderExpires Specifies the index number for the Expires HTTP header.
HeaderFrom Specifies the index number for the From HTTP header.
HeaderHost Specifies the index number for the Host HTTP header.
HeaderIfMatch Specifies the index number for the If-Match HTTP header.
HeaderIfModifiedSince Specifies the index number for the If-Modified-Since HTTP header.
HeaderIfNoneMatch Specifies the index number for the If-None-Match HTTP header.
HeaderIfRange Specifies the index number for the If-Range HTTP header.
HeaderIfUnmodifiedSince Specifies the index number for the If-Unmodified-Since HTTP header.
HeaderKeepAlive Specifies the index number for the Keep-Alive HTTP header.
HeaderLastModified Specifies the index number for the Last-Modified HTTP header.
HeaderLocation Specifies the index number for the Location HTTP header.
HeaderMaxForwards Specifies the index number for the Max-Forwards HTTP header.
HeaderPragma Specifies the index number for the Pragma HTTP header.
HeaderProxyAuthenticate Specifies the index number for the Proxy-Authenticate HTTP header.
HeaderProxyAuthorization Specifies the index number for the Proxy-Authorization HTTP header.
HeaderRange Specifies the index number for the Range HTTP header.
HeaderReferer Specifies the index number for the Referer HTTP header.
HeaderRetryAfter Specifies the index number for the Retry-After HTTP header.
HeaderServer Specifies the index number for the Server HTTP header.
HeaderSetCookie Specifies the index number for the Set-Cookie HTTP header.
HeaderTe Specifies the index number for the TE HTTP header.
HeaderTrailer Specifies the index number for the Trailer HTTP header.
HeaderTransferEncoding Specifies the index number for the Transfer-Encoding HTTP header.
HeaderUpgrade Specifies the index number for the Upgrade HTTP header.
HeaderUserAgent Specifies the index number for the User-Agent HTTP header.
HeaderVary Specifies the index number for the Vary HTTP header.
HeaderVia Specifies the index number for the Via HTTP header.
HeaderWarning Specifies the index number for the Warning HTTP header.
HeaderWwwAuthenticate Specifies the index number for the WWW-Authenticate HTTP header.
RequestHeaderMaximum Specifies the index number for the Maximum HTTP request header.
ResponseHeaderMaximum Specifies the index number for the Maximum HTTP response header.

Public Properties

MachineConfigPath Gets the full physical path to the Machine.config file.
MachineInstallDirectory Gets the physical path to the directory where the ASP.NET binaries are installed.

Public Methods

CloseConnection Terminates the connection with the client.
EndOfRequest Used by the runtime to notify the HttpWorkerRequest that request processing for the current request is complete.
Equals (inherited from Object ) Overloaded. Determines whether two Object instances are equal.
FlushResponse Sends all pending response data to the client.
GetAppPath Returns the virtual path to the currently executing server application.
GetAppPathTranslated Returns the physical path to the currently executing server application.
GetFilePath When overridden in a derived class, returns the physical path to the requested URI.
GetFilePathTranslated Returns the physical file path to the requested URI (and translates it from virtual path to physical path: for example, "/proj1/page.aspx" to "c:\dir\page.aspx")
GetHashCode (inherited from Object ) Serves as a hash function for a particular type, suitable for use in hashing algorithms and data structures like a hash table.
GetHttpVerbName Returns the specified member of the request header.
GetHttpVersion Provides access to the HTTP version of the request (for example, "HTTP/1.1").
GetKnownRequestHeader Returns the standard HTTP request header that corresponds to the specified index.
GetKnownRequestHeaderIndex Returns the index number of the specified HTTP request header.
GetKnownRequestHeaderName Returns the name of the specified HTTP request header.
GetKnownResponseHeaderIndex Returns the index number of the specified HTTP response header.
GetKnownResponseHeaderName Returns the name of the specified HTTP response header.
GetLocalAddress Provides access to the specified member of the request header.
GetLocalPort Provides access to the specified member of the request header.
GetPathInfo Returns additional path information for a resource with a URL extension. That is, for the path/virdir/page.html/tail, the GetPathInfo value is/tail.
GetPreloadedEntityBody Returns the portion of the HTTP request body that has already been read.
GetProtocol When overridden in a derived class, returns the HTTP protocol (HTTP or HTTPS).
GetQueryString Returns the query string specified in the request URL.
GetQueryStringRawBytes When overridden in a derived class, returns the response query string as an array of bytes.
GetRawUrl Returns the URL path contained in the request header with the query string appended.
GetRemoteAddress Provides access to the specified member of the request header.
GetRemoteName When overridden in a derived class, returns the name of the client computer.
GetRemotePort Provides access to the specified member of the request header.
GetServerName When overridden in a derived class, returns the name of the local server.
GetServerVariable Returns a single server variable from a dictionary of server variables associated with the request.
GetStatusDescription Returns a string that describes the name of the specified HTTP status code.
GetType (inherited from Object ) Gets the Type of the current instance.
GetUnknownRequestHeader Returns a nonstandard HTTP request header value.
GetUnknownRequestHeaders Get all nonstandard HTTP header name-value pairs.
GetUriPath Returns the virtual path to the requested URI.
GetUserToken When overridden in a derived class, returns the client's impersonation token.
HasEntityBody Returns a value indicating whether the request contains body data.
HeadersSent Returns a value indicating whether HTTP response headers have been sent to the client for the current request.
IsClientConnected Returns a value indicating whether the client connection is still active.
IsEntireEntityBodyIsPreloaded Returns a value indicating whether all request data is available and no further reads from the client are required.
IsSecure Returns a value indicating whether the connection uses SSL.
MapPath Returns the physical path corresponding to the specified virtual path.
ReadEntityBody Reads request data from the client (when not preloaded).
SendCalculatedContentLength Adds a Content-Length HTTP header to the response.
SendKnownResponseHeader Adds a standard HTTP header to the response.
SendResponseFromFile Overloaded. Adds the contents of a file to the response.
SendResponseFromMemory Overloaded. Adds the contents of a memory block to the response.
SendStatus Specifies the HTTP status code and status description of the response; for example SendStatus(200, "Ok").
SendUnknownResponseHeader Adds a nonstandard HTTP header to the response.
SetEndOfSendNotification Registers for an optional notification when all the response data is sent.
ToString (inherited from Object ) Returns a String that represents the current Object .

Protected Methods

Finalize (inherited from Object ) Overridden. Allows an Object to attempt to free resources and perform other cleanup operations before the Object is reclaimed by garbage collection.

In C# and C++, finalizers are expressed using destructor syntax.

MemberwiseClone (inherited from Object ) Creates a shallow copy of the current Object .

-- As can be seen, there's a whole buncha cool stuff in there that's not exposed at all by the HttpRequest, HttpResponse and related classes. Cool!

Fixing ASP.NET mappings / bindings

We get a lot of requests from people who have discombobulated (that's geek - speak for "I Screwed It Up") their installation of the .NET Framework or Visual Studio .NET or what not, and ASP.NET doesn't work. 99% percent of the time the ASPNET_REGIIS.EXE utility will fix it. What's THAT, you say? Well you can usually find it here:

C:\WINNT\Microsoft.NET\Framework\v1.1.4322

Just be sure to replace the "WINNT" with "Windows" if on XP and the "v1.1.1.4322" with whatever version of the framework you want to "stick" when you run this. (In other words, don't run the guy in the v1.0.3705 folder if you don't want Framework 1.0 and you have a newer version)

There are a bunch of command line switches on this puppy and I'm reproducing them here for easy reference:

Usage:
aspnet_regiis.exe [-i[r] [-enable] | -u[a] | -r | -s[n] <path> | -k[n] <path> | -lv | -lk | -c | -e[a] | -?]
-i - Install this version of ASP.NET and update scriptmaps
at the IIS metabase root and for all scriptmaps below
the root. Existing scriptmaps of lower version are upgraded to this version.
-ir - Install this version of ASP.NET, register only. Do not update scriptmaps in IIS.
-enable - When -enable is specified with -i or -ir, ASP.NET will also be enabled in the IIS security console (IIS 6.0 or later).
-s <path> - Install scriptmaps for this version at the specified path, recursively. Existing scriptmaps of lower version are upgraded to this version. E.g. aspnet_regiis.exe -s W3SVC/1/ROOT/SampleApp1
-sn <path> - Install scriptmaps for this version at the specified path, non-recursively. Existing scriptmaps of lower version are upgraded to this version.
-r - Install scriptmaps for this version at the IIS metabase root and for all scriptmaps below the root. All existing scriptmaps are changed to this version, regardless of current version.
-u - Uninstall this version of ASP.NET. Existing scriptmaps to this version are remapped to highest remaining version of ASP.NET installed on the machine.
-ua - Uninstall all versions of ASP.NET on the machine
-k <path> - Remove all scriptmaps to any version of ASP.NET from the specified path, recursively. E.g. aspnet_regiis.exe -k W3SVC/1/ROOT/SampleApp1
-kn <path> - Remove all scriptmaps to any version ASP.NET from the specified path, non-recursively.
-lv - List all versions of ASP.NET that are installed on the machine, with status and installation path.
Status: Valid[ (Root)]|Invalid
-lk - List all the path of all IIS metabase keys where ASP.NET is scriptmapped, together with the version. Keys that inherit ASP.NET scriptmaps from a parent key will not be displayed.
-c - Install the client side scripts for this version to the aspnet_client subdirectory of each IIS site directory.
-e - Remove the client side scripts for this version from the aspnet_client subdirectory of each IIS site directory.
-ea - Remove the client side scripts for all versions from the aspnet_client subdirectory of each IIS site directory.
-? - Print this help text.

The most common switches you will probably need to use are -i and -c.

Well, I've got more I could write this time around, but frankly, I just hate warm Martinis, so Ciao! The temperature here is dropping faster than Democratic Candidates in Iowa, so I better get a refresher...

Dr. Dexter Dotnetsky is the alter-ego of the Eggheadcafe.com 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 youbetcha@mindless.com.  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."