Archive

Archive for June, 2008

[REPOST] – Creating Local Methods with Func

June 6, 2008 Comments off

I wrote briefly about the new Func generic delegate in Part 3 of the Upgrade your C# Skills series. Today, I wanted to explore this in a little more detail.

I’m sure that most of us have created many private methods to outsource code from one method to another. There are times we do this even when the method is only called from a single location. I’m going to use a simple example, but I think you’ll get the point:

foreach (Person person in people)
{DateTime now = DateTime.Now;
int age = now.Year – person.Age;

Console.WriteLine(“{0} {1} was probably born in {2}.”,
person.FirstName,
person.LastName,
age);
}

Kind of a silly example, but fairly straight forward stuff, right? Well, what if we had two loops or other calculations in the same method that needed to know the Year born? Since we believe in code reuse, we would typically throw this into its own private method:

foreach (Person person in people)
{
Console.WriteLine(“{0} {1} was probably born in {2}.”,
person.FirstName,
person.LastName,
CalculateYearBorn(person));
}

privateint CalculateYearBorn(Person person)
{
DateTime now = DateTime.Now;
int age = now.Year – person.Age;
return age;
}

This should be code we can all relate to, and is a fine practice because it accomplishes two very important things. First, it promotes code reuse. Second, it simplifies and cleans up our logic. What unfortunately happens quite frequently is that the outsourced method is only called from one other method, even if it is multiple times. In this scenario, what we really need is a Local Method.

Local Methods

I don’t know if anyone else has coined this phrase before in this context, but it seems appropriate. A quick google search turned up several references to Java and some statistical analysis looking items. Adding the “C#” to the search terms found a couple of references where the term is misapplied to mean a private class method. To be clear, though, what I mean by Local Method is a method defined completely within a non-class parent scope. If you think about it, that’s what Anonymous Delegates are, but unlike an anonymous delegate, we need to be able to assign our method a name. The Func<> Generic Delegate can be used to accomplish this goal.

This approach is going to give us the best of both worlds. First, it is going to allow us to reuse code. Second, it is going to clean up our execution logic by replacing some of it (or maybe even all of it) with a method call. Finally, it is going to help reduce “Class clutter” by eliminating private methods that are only called from one location.

Creating and Using the Local Method

In order to use the local method, we first need to define it as a local variable. This local variable is of type Func<>, which has several different signatures. We are going to use Func<Person, int> to create a method that accepts a Person object as a parameter and returns an int:

Func<Person, int> CalculateYearBorn = new Func<Person,int>(
delegate (Person per)
{
DateTime now = DateTime.Now;
int age = now.Year – per.Age;
return age;
});

Now, to use the local method, we simply call it like we would any other:

foreach (Person person in people)
{
Console.WriteLine(“{0} {1} was probably born in {2}.”,
person.FirstName,
person.LastName,
CalculateYearBorn(person));
}

I think you’ll agree that this is pretty cool and could be very useful. And of course, since this is based on a Generic Delegate, we can use Lambda Expressions to write our code. So even though this is a fairly silly example, let’s go ahead and clean it up a bit:

Func<Person, int> CalculateYearBorn =
new Func<Person, int>(per => { return DateTime.Now.Year – per.Age; });people.ForEach(person => Console.WriteLine(“{0} {1} was probably born in {2}.”,
person.FirstName,
person.LastName,
CalculateYearBorn(person)));

Some Final Notes

I really like this approach, but it naturally does not suit every purpose, so rule one, to paraphrase Sean Connery in The Untouchables, “don’t bring a knife to a gun fight.” In other words, don’t go crazy and use this just because you can. Use it to minimize repeated code within a specific method or to simplify complex code blocks.

There are a couple of additional things you should know. First, you must define the delegate and method details before using them, otherwise the compiler will complain. Second, since this is a local method it has complete access to the other local method variables: this should help reduce the number of parameters you must send in order to accomplish your task. Finally, since the local method is actually a local variable itself, you should be able to change the address dynamically to other delegates. I don’t think I would recommend this last item, but it could prove to be interesting experimentation fodder.

Categories: .NET 3.5

[REPOST] – WordPress 2.5 Blank Page Issue

June 6, 2008 3 comments

You may have experienced an odd occurrence on the site today, and if so I apologize. For some inexplicable reason, the site encountered the dreaded WordPress Blank Page issue. Last I checked, which I think was yesterday afternoon, the site loaded just fine. Today, however, I noticed that the front page would not load. The index.php page produced only a blank return: a completely empty HTML document. Then I confirmed that the Admin page would load correctly.

I checked and even restarted the web server: all was well and restarting did not help, which I expected since all the other sites seemed fine. Next, I deactivated all the plugins, but since that made no difference I reactivated them immediately. I then tried reloading 2.5, but that did not change anything. Finally, I went to the admin page and changed the Theme to the WordPress Default. All of a sudden, the site showed up. I changed back to the regular site theme, and sure enough it would not load. Fortunately, I keep a copy of the Theme on my PC, so I uploaded it again and the site came back.

After going through this, I think I’ve done this once before. Maybe next time I’ll remember the solution without all the gyrations. Of course, it would be nice to not have the problem ever again. I expect to potentially have this sort of problem immediately following an update, but since it has been a couple of weeks since upgrading to 2.5 I really don’t understand the sudden problem.

Categories: This Site

[REPOST] – GMail is Hiring

June 6, 2008 Comments off

Since Jon Skeet recently announced he is joining Google, I thought it was worth mentioning that the GMail Team is hiring. I’ve wondered several times in the past what it would be like to work at Google. I think the truth is that I’m not geeky enough, but I would probably enjoy it while it lasted.

GMail in particular would be of interest to me. I’ve been on the GMail bandwagon since it was in Beta (oh wait… it still is…) OK, I mean since it was really Beta, like fresh and new type beta. I have been purely GMail since 2004 and I have never looked back. I have even succeeded in getting my friends, spouse, parents, and coworkers to convert to GMail as well.

I have a friend who is very SEO savvy, and he shared with me some of the Google interview questions, and all I can remember is that it would have put a Mensa candidate to shame. So since I’m not smart enough to even apply, I’ll just sit on the sidelines and continue be a happy consumer.

Categories: Miscellaneous

[REPOST] – I am a Professional Geek

June 6, 2008 Comments off

I was just reading Payton Byrd’s recent post about the two types of programmers, which references another post about the same topic by Jeff Atwood, and I felt encouraged to respond.

Growing Up ABM

I honestly couldn’t care less about the open-source vs. Microsoft wars. My background is probably atypical, but I as a young programmer I was raised on IBM technologies. As a result, I spent many years as an ABM-er (Anyone But Microsoft). While thinly-veiled by necessity, IBM has embraced this philosophy since the OS/2 debacle. So much so, in fact, that they have donated billions of dollars to Linux, Java, Rational, and Eclipse. To this day there are a great many IBM oriented developers who will do anything to avoid Microsoft solutions, no matter how painful or inconvenient. I know because until 2003 I was one of them.

Being anti-Microsoft meant that I had the opportunity to learn a great many things that I otherwise may not have been motivated to learn: PHP, Linux, Apache, Java, OpenOffice, etc. all fall into that category. I even used a Linux Desktop for almost 2 years just to be as anti-Microsoft as I could. It was during this period that a friend of mine, a TRUE Linux geek from v1, introduced me to VB6. I watched as he created a GUI prototype in minutes that would have taken me days in Swing. When .NET came out, I started seriously paying attention, and by the time VS2003 came out I was hooked.

Technology Agnostic

Today, while I spend most of my time in .NET, it is not unusual for me to spend time in SEU coding RPG on the iSeries or VI coding PHP on a Linux Server. My projects span several different databases with DB2, MySQL, and SqlServer being the most common. I write and maintain Green Screen programs, Windows applications, and Web sites.

The point of all this is to show that I have gone from an ABM Religious Zealot to a true Technology Agnostic. I think that all these people who have “taken sides” got it all wrong. My zealotry is now limited to using the right tool for the right job. I will admit, that these days this usually means Microsoft, but at the same time it could be open source. It could be Linux, it could be IBM, it could be just about anything.
In other words, I just don’t care: I want to get the job done, effectively and with a pleasing result (even if only to me.)

So what am I? I am a Professional Geek

So what struck me about these articles and this general discussion was the question: what am I? In reading about the 20% Alpha Geeks and the 80% Vocational Programmers, I realized that I am really neither. Payton essentially draws the same conclusion, but does so from a much different personal (professional?) viewpoint than I do.

I will definitely say that I am NOT a 20% Alpha Geek. I don’t contribute to Open Source projects or spend my evenings bit twiddling. In fact, I don’t even own a computer. I have often said to people that “I am a professional Geek: I only Geek at work.” After spending most of my working time staring at 2 computer monitors, sitting on my butt in my desk chair, with my fingers glued to the keyboard, the last thing I want to with my free time is spend it on a computer.

But to lump me in with the 80%-ers (by their definition, not mine) would be unfair. I stay ahead of my peers. I read about programming and development incessantly (and occasionally I will read at home). I spend a lot of time learning new technologies and new techniques. I go to trade shows. I participate in User Groups. I write, I teach, and I give presentations. I even give software away. In other words, I am not just “vocational”: I learn, grow, and contribute to our community at large. And I am content with my position, meaning that I recognize I will never be on the level of many of the other developers out there whom I admire, but I still have something to offer so I choose to do so.

50%-ers of the world unite… or don’t…

And so I find myself in neither category, so I’ll just split the middle and say I am a “50%-er”, and I’ll bet most of you are as well. Chime in and rate yourself below – or don’t… it does not matter to me.

Categories: Miscellaneous

[REPOST] – ASP.NET Server Variables, take 2

June 6, 2008 Comments off

The last thing I did yesterday before I went home was write the code for (and post) a simple class for reading HTTP Request Server Variables. I like the idea, because it allows the consumer to use Intellisense and variable names instead of doing a value lookup using a string.

Nick at Coder Journal left a comment (thanks Nick!) suggesting we do this in a more static way to avoid unnecessarily processing all the variables. I had originally wanted to do something like that, but I also want to separate this class from any particular ASP.NET project, so here is my take on a static-only version that does not require access to the HttpContext object:

public static class ServerVariables2
{
public static NameValueCollection VariableCollection { get; private set; }public static void Clear()
{
VariableCollection = null;
}

public static void Initialize(NameValueCollection values)
{
Clear();
VariableCollection = values;
}

private static string ValidateAndAcquire(string VariableName)
{
if (VariableCollection == null)
{
throw new ArgumentNullException(“VariableCollection is not initialized.”);
}
else if (!VariableCollection.AllKeys.Contains(VariableName))
{
throw new ArgumentOutOfRangeException(
String.Format(“Variable {0} not found in VariableCollection.”, VariableName));
}
else
{
return VariableCollection[VariableName];
}
}

public static string ALL_HTTP { get { return ValidateAndAcquire(“ALL_HTTP”); } }
public static string ALL_RAW { get { return ValidateAndAcquire(“ALL_RAW”); } }
public static string APPL_MD_PATH { get { return ValidateAndAcquire(“APPL_MD_PATH”); } }
public static string APPL_PHYSICAL_PATH { get { return ValidateAndAcquire(“APPL_PHYSICAL_PATH”); } }
public static string AUTH_TYPE { get { return ValidateAndAcquire(“AUTH_TYPE”); } }
public static string AUTH_USER { get { return ValidateAndAcquire(“AUTH_USER”); } }
public static string AUTH_PASSWORD { get { return ValidateAndAcquire(“AUTH_PASSWORD”); } }
public static string LOGON_USER { get { return ValidateAndAcquire(“LOGON_USER”); } }
public static string REMOTE_USER { get { return ValidateAndAcquire(“REMOTE_USER”); } }
public static string CERT_COOKIE { get { return ValidateAndAcquire(“CERT_COOKIE”); } }
public static string CERT_FLAGS { get { return ValidateAndAcquire(“CERT_FLAGS”); } }
public static string CERT_ISSUER { get { return ValidateAndAcquire(“CERT_ISSUER”); } }
public static string CERT_KEYSIZE { get { return ValidateAndAcquire(“CERT_KEYSIZE”); } }
public static string CERT_SECRETKEYSIZE { get { return ValidateAndAcquire(“CERT_SECRETKEYSIZE”); } }
public static string CERT_SERIALNUMBER { get { return ValidateAndAcquire(“CERT_SERIALNUMBER”); } }
public static string CERT_SERVER_ISSUER { get { return ValidateAndAcquire(“CERT_SERVER_ISSUER”); } }
public static string CERT_SERVER_SUBJECT { get { return ValidateAndAcquire(“CERT_SERVER_SUBJECT”); } }
public static string CERT_SUBJECT { get { return ValidateAndAcquire(“CERT_SUBJECT”); } }
public static string CONTENT_LENGTH { get { return ValidateAndAcquire(“CONTENT_LENGTH”); } }
public static string CONTENT_TYPE { get { return ValidateAndAcquire(“CONTENT_TYPE”); } }
public static string GATEWAY_INTERFACE { get { return ValidateAndAcquire(“GATEWAY_INTERFACE”); } }
public static string HTTPS { get { return ValidateAndAcquire(“HTTPS”); } }
public static string HTTPS_KEYSIZE { get { return ValidateAndAcquire(“HTTPS_KEYSIZE”); } }
public static string HTTPS_SECRETKEYSIZE { get { return ValidateAndAcquire(“HTTPS_SECRETKEYSIZE”); } }
public static string HTTPS_SERVER_ISSUER { get { return ValidateAndAcquire(“HTTPS_SERVER_ISSUER”); } }
public static string HTTPS_SERVER_SUBJECT { get { return ValidateAndAcquire(“HTTPS_SERVER_SUBJECT”); } }
public static string INSTANCE_ID { get { return ValidateAndAcquire(“INSTANCE_ID”); } }
public static string INSTANCE_META_PATH { get { return ValidateAndAcquire(“INSTANCE_META_PATH”); } }
public static string LOCAL_ADDR { get { return ValidateAndAcquire(“LOCAL_ADDR”); } }
public static string PATH_INFO { get { return ValidateAndAcquire(“PATH_INFO”); } }
public static string PATH_TRANSLATED { get { return ValidateAndAcquire(“PATH_TRANSLATED”); } }
public static string QUERY_STRING { get { return ValidateAndAcquire(“QUERY_STRING”); } }
public static string REMOTE_ADDR { get { return ValidateAndAcquire(“REMOTE_ADDR”); } }
public static string REMOTE_HOST { get { return ValidateAndAcquire(“REMOTE_HOST”); } }
public static string REMOTE_PORT { get { return ValidateAndAcquire(“REMOTE_PORT”); } }
public static string REQUEST_METHOD { get { return ValidateAndAcquire(“REQUEST_METHOD”); } }
public static string SCRIPT_NAME { get { return ValidateAndAcquire(“SCRIPT_NAME”); } }
public static string SERVER_NAME { get { return ValidateAndAcquire(“SERVER_NAME”); } }
public static string SERVER_PORT { get { return ValidateAndAcquire(“SERVER_PORT”); } }
public static string SERVER_PORT_SECURE { get { return ValidateAndAcquire(“SERVER_PORT_SECURE”); } }
public static string SERVER_PROTOCOL { get { return ValidateAndAcquire(“SERVER_PROTOCOL”); } }
public static string SERVER_SOFTWARE { get { return ValidateAndAcquire(“SERVER_SOFTWARE”); } }
public static string URL { get { return ValidateAndAcquire(“URL”); } }
public static string HTTP_CONNECTION { get { return ValidateAndAcquire(“HTTP_CONNECTION”); } }
public static string HTTP_KEEP_ALIVE { get { return ValidateAndAcquire(“HTTP_KEEP_ALIVE”); } }
public static string HTTP_ACCEPT { get { return ValidateAndAcquire(“HTTP_ACCEPT”); } }
public static string HTTP_ACCEPT_CHARSET { get { return ValidateAndAcquire(“HTTP_ACCEPT_CHARSET”); } }
public static string HTTP_ACCEPT_ENCODING { get { return ValidateAndAcquire(“HTTP_ACCEPT_ENCODING”); } }
public static string HTTP_ACCEPT_LANGUAGE { get { return ValidateAndAcquire(“HTTP_ACCEPT_LANGUAGE”); } }
public static string HTTP_COOKIE { get { return ValidateAndAcquire(“HTTP_COOKIE”); } }
public static string HTTP_HOST { get { return ValidateAndAcquire(“HTTP_HOST”); } }
public static string HTTP_REFERER { get { return ValidateAndAcquire(“HTTP_REFERER”); } }
public static string HTTP_USER_AGENT { get { return ValidateAndAcquire(“HTTP_USER_AGENT”); } }

}

I like this approach, and in the small amount of testing I’ve done it works well while incurring less overhead.

While I was testing this, I started toying with the idea of a third version that has a single Get method based off an Enumeration. The more I thought about it, the more sense it made: this way, the user still gets the complete benefit of Intellisense by being able to see the list of possible values via the Enum. At the same time, the code is much shorter and no longer has a bunch of properties with hard coded string values. Making a change, like adding a variable or hiding certain values would only require maintaining the Enumeration. Below is the final version of the code, for both the Enum and the class

public enum ServerVariables
{
ALL_HTTP,
ALL_RAW,
APPL_MD_PATH,
APPL_PHYSICAL_PATH,
AUTH_TYPE,
AUTH_USER,
AUTH_PASSWORD,
LOGON_USER,
REMOTE_USER,
CERT_COOKIE,
CERT_FLAGS,
CERT_ISSUER,
CERT_KEYSIZE,
CERT_SECRETKEYSIZE,
CERT_SERIALNUMBER,
CERT_SERVER_ISSUER,
CERT_SERVER_SUBJECT,
CERT_SUBJECT,
CONTENT_LENGTH,
CONTENT_TYPE,
GATEWAY_INTERFACE,
HTTPS,
HTTPS_KEYSIZE,
HTTPS_SECRETKEYSIZE,
HTTPS_SERVER_ISSUER,
HTTPS_SERVER_SUBJECT,
INSTANCE_ID,
INSTANCE_META_PATH,
LOCAL_ADDR,
PATH_INFO,
PATH_TRANSLATED,
QUERY_STRING,
REMOTE_ADDR,
REMOTE_HOST,
REMOTE_PORT,
REQUEST_METHOD,
SCRIPT_NAME,
SERVER_NAME,
SERVER_PORT,
SERVER_PORT_SECURE,
SERVER_PROTOCOL,
SERVER_SOFTWARE,
URL,
HTTP_CONNECTION,
HTTP_KEEP_ALIVE,
HTTP_ACCEPT,
HTTP_ACCEPT_CHARSET,
HTTP_ACCEPT_ENCODING,
HTTP_ACCEPT_LANGUAGE,
HTTP_COOKIE,
HTTP_HOST,
HTTP_REFERER,
HTTP_USER_AGENT
}public static class RequestServerVariable
{
public static NameValueCollection VariableCollection { get; private set; }

public static void Clear()
{
VariableCollection = null;
}

public static void Initialize(NameValueCollection values)
{
Clear();
VariableCollection = values;
}

public static string ValidateAndAcquire(ServerVariables Variable)
{
string VariableName = Enum.GetName(typeof(ServerVariables), Variable);

if (VariableCollection == null)
{
throw new ArgumentNullException(“VariableCollection is not initialized.”);
}
else if (!VariableCollection.AllKeys.Contains(VariableName))
{
throw new ArgumentOutOfRangeException(
String.Format(“Variable {0} not found in VariableCollection.”, VariableName));
}
else
{
return VariableCollection[VariableName];
}
}
}

This approach still requires an initialization routine, but it wouldn’t surprise me if there was a better way to handle that issue. Let me know what you think.

Categories: .NET

[REPOST] – ASP.NET Server Variables

June 6, 2008 Comments off

I have admitted in the past that I am not an experienced ASP.NET developer, so this may be a “DUH” post, but I thought it was a good idea and wanted to share.

For the ASP.NET MVC application I’ve been working on, I needed to send the user to another domain (on the same server) for some processing, after which they are returned to the original domain. I wanted to be able to verify that the return trip was actually coming from the correct domain and port, so I needed to work with some of the ServerVariables. I hunted around a bit and found the HttpRequest.ServerVariables collection that contains the data I needed as well as a wealth of other information. Working with it though, I felt a little out of date needing to supply the string names of the variables (they are Key values in a System.Collections.Specialized.NameValueCollection object), so I created a simple class so that would let me take advantage of Intellisense and let me work with the values by name.

using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Collections.Specialized;namespace YourNamespace
{
public class ServerVariables
{
public string ALL_HTTP { get; private set; }
public string ALL_RAW { get; private set; }
public string APPL_MD_PATH { get; private set; }
public string APPL_PHYSICAL_PATH { get; private set; }
public string AUTH_TYPE { get; private set; }
public string AUTH_USER { get; private set; }
public string AUTH_PASSWORD { get; private set; }
public string LOGON_USER { get; private set; }
public string REMOTE_USER { get; private set; }
public string CERT_COOKIE { get; private set; }
public string CERT_FLAGS { get; private set; }
public string CERT_ISSUER { get; private set; }
public string CERT_KEYSIZE { get; private set; }
public string CERT_SECRETKEYSIZE { get; private set; }
public string CERT_SERIALNUMBER { get; private set; }
public string CERT_SERVER_ISSUER { get; private set; }
public string CERT_SERVER_SUBJECT { get; private set; }
public string CERT_SUBJECT { get; private set; }
public string CONTENT_LENGTH { get; private set; }
public string CONTENT_TYPE { get; private set; }
public string GATEWAY_INTERFACE { get; private set; }
public string HTTPS { get; private set; }
public string HTTPS_KEYSIZE { get; private set; }
public string HTTPS_SECRETKEYSIZE { get; private set; }
public string HTTPS_SERVER_ISSUER { get; private set; }
public string HTTPS_SERVER_SUBJECT { get; private set; }
public string INSTANCE_ID { get; private set; }
public string INSTANCE_META_PATH { get; private set; }
public string LOCAL_ADDR { get; private set; }
public string PATH_INFO { get; private set; }
public string PATH_TRANSLATED { get; private set; }
public string QUERY_STRING { get; private set; }
public string REMOTE_ADDR { get; private set; }
public string REMOTE_HOST { get; private set; }
public string REMOTE_PORT { get; private set; }
public string REQUEST_METHOD { get; private set; }
public string SCRIPT_NAME { get; private set; }
public string SERVER_NAME { get; private set; }
public string SERVER_PORT { get; private set; }
public string SERVER_PORT_SECURE { get; private set; }
public string SERVER_PROTOCOL { get; private set; }
public string SERVER_SOFTWARE { get; private set; }
public string URL { get; private set; }
public string HTTP_CONNECTION { get; private set; }
public string HTTP_KEEP_ALIVE { get; private set; }
public string HTTP_ACCEPT { get; private set; }
public string HTTP_ACCEPT_CHARSET { get; private set; }
public string HTTP_ACCEPT_ENCODING { get; private set; }
public string HTTP_ACCEPT_LANGUAGE { get; private set; }
public string HTTP_COOKIE { get; private set; }
public string HTTP_HOST { get; private set; }
public string HTTP_REFERER { get; private set; }
public string HTTP_USER_AGENT { get; private set; }

private ServerVariables()
{

}

public static ServerVariables Factory(NameValueCollection vars)
{
ServerVariables sv;
if (vars == null)
{
sv = new ServerVariables();
}
else
{
sv = new ServerVariables()
{
ALL_HTTP = vars["ALL_HTTP"],
ALL_RAW = vars["ALL_RAW"],
APPL_MD_PATH = vars["APPL_MD_PATH"],
APPL_PHYSICAL_PATH = vars["APPL_PHYSICAL_PATH"],
AUTH_TYPE = vars["AUTH_TYPE"],
AUTH_USER = vars["AUTH_USER"],
AUTH_PASSWORD = vars["AUTH_PASSWORD"],
LOGON_USER = vars["LOGON_USER"],
REMOTE_USER = vars["REMOTE_USER"],
CERT_COOKIE = vars["CERT_COOKIE"],
CERT_FLAGS = vars["CERT_FLAGS"],
CERT_ISSUER = vars["CERT_ISSUER"],
CERT_KEYSIZE = vars["CERT_KEYSIZE"],
CERT_SECRETKEYSIZE = vars["CERT_SECRETKEYSIZE"],
CERT_SERIALNUMBER = vars["CERT_SERIALNUMBER"],
CERT_SERVER_ISSUER = vars["CERT_SERVER_ISSUER"],
CERT_SERVER_SUBJECT = vars["CERT_SERVER_SUBJECT"],
CERT_SUBJECT = vars["CERT_SUBJECT"],
CONTENT_LENGTH = vars["CONTENT_LENGTH"],
CONTENT_TYPE = vars["CONTENT_TYPE"],
GATEWAY_INTERFACE = vars["GATEWAY_INTERFACE"],
HTTPS = vars["HTTPS"],
HTTPS_KEYSIZE = vars["HTTPS_KEYSIZE"],
HTTPS_SECRETKEYSIZE = vars["HTTPS_SECRETKEYSIZE"],
HTTPS_SERVER_ISSUER = vars["HTTPS_SERVER_ISSUER"],
HTTPS_SERVER_SUBJECT= vars["HTTPS_SERVER_SUBJECT"],
INSTANCE_ID = vars["INSTANCE_ID"],
INSTANCE_META_PATH = vars["INSTANCE_META_PATH"],
LOCAL_ADDR = vars["LOCAL_ADDR"],
PATH_INFO = vars["PATH_INFO"],
PATH_TRANSLATED = vars["PATH_TRANSLATED"],
QUERY_STRING = vars["QUERY_STRING"],
REMOTE_ADDR = vars["REMOTE_ADDR"],
REMOTE_HOST = vars["REMOTE_HOST"],
REMOTE_PORT = vars["REMOTE_PORT"],
REQUEST_METHOD = vars["REQUEST_METHOD"],
SCRIPT_NAME = vars["SCRIPT_NAME"],
SERVER_NAME = vars["SERVER_NAME"],
SERVER_PORT = vars["SERVER_PORT"],
SERVER_PORT_SECURE = vars["SERVER_PORT_SECURE"],
SERVER_PROTOCOL = vars["SERVER_PROTOCOL"],
SERVER_SOFTWARE = vars["SERVER_SOFTWARE"],
URL = vars["URL"],
HTTP_CONNECTION = vars["HTTP_CONNECTION"],
HTTP_KEEP_ALIVE = vars["HTTP_KEEP_ALIVE"],
HTTP_ACCEPT = vars["HTTP_ACCEPT"],
HTTP_ACCEPT_CHARSET = vars["HTTP_ACCEPT_CHARSET"],
HTTP_ACCEPT_ENCODING= vars["HTTP_ACCEPT_ENCODING"],
HTTP_ACCEPT_LANGUAGE= vars["HTTP_ACCEPT_LANGUAGE"],
HTTP_COOKIE = vars["HTTP_COOKIE"],
HTTP_HOST = vars["HTTP_HOST"],
HTTP_REFERER = vars["HTTP_REFERER"],
HTTP_USER_AGENT = vars["HTTP_USER_AGENT"]
};
}

return sv;
}
}
}

Again, I realize this is not some brilliant idea, but I thought I’d share for anyone else who might want it. To make this work, be sure to include a reference to System.Collections.Specialized.

Categories: .NET

[REPOST] – WordPress 2.5 Upgrade

June 6, 2008 Comments off

This morning I the site upgraded to WordPress 2.5, and I am very impressed! I know it is not .Net, but I think there are plenty of you who might be interested. So here is my list of top 7 cool new WP features:

  1. Permalink editing: you can now preview and edit the Permalink of a blog post. Previously, it was always based on the title, which can be annoying and not always SEO friendly.
  2. Improved Dashboard: a better layout, more relevant information, easier navigation.
  3. “Top Post” information added to the Dashboard.
  4. The WordPress Blog feed has been downsized and moved.
  5. A Plugin feed has been added to the Dashboard.
  6. Integrated Stats (may require Stats plug-in) on the Dashboard.
  7. Improved WYSIWYG editor and interface.

They say that the new interface no longer messes with your code in posts, but we’ll see the next time I post some samples. They also say you are supposed to be able to configure the Dashboard yourself, but I haven’t found that feature yet.

I will say they made a couple of changes I don’t care for, mostly on the “Write Post” screen. They moved most of the advanced features below the post instead of in the right hand sidebar, so even to select a Category I have to scroll down now (which was not previously the case). I’m not sure what the benefit is: the right sidebar is still present, so there is no increased posting space, you simply have fewer options in the sidebar. Actually, it makes the page seem a little lopsided. For most of the features this is not an issue, but selecting a category is pretty important and should have been left where it was.

But I’m nitpicking. Otherwise it looks as though the team at WP has done another fantastic job.

Categories: This Site
Follow

Get every new post delivered to your Inbox.