views:

527

answers:

4

HttpServerUtility contains a public function called UrlEncode. It is not a shared function. HttpServerUtility does not have any public constructors.

Doing this fails:

Dim encodeMe As String = "a string to be encoded!"
HttpServerUtility.UrlEncode(encodeMe) 'Bombs out

This works, and is how Microsoft says to do it:

Dim instance As HttpServerUtility
Dim encodeMe As String = "a string to be encoded!"

instance.UrlEncode(encodeMe ) 'Works!

How did they accomplish this? You can't instantiate an instance of it using a constructor, yet you can't access UrlEncode by just referencing HttpServerUtility.UrlEncode.

EDIT: While I thoroughly enjoyed everyone getting into a big OO debate, I believe the problem is faulty MSDN documentation. The line "Dim instance As HttpServerUtility" should read "Dim instance As HttpServerUtility = Context.Server" The code which I included (which is from the MSDN documentation) does not actually work, and instead throws a null reference exception - just as you'd expect. Thank you, Jason!

A: 

It has a static private constructor which allows it to be used. Check out the following link: Static Constructors

If you want to see what they did download reflector and open it up.

EDIT: To flush out the answer to make people happy. While the static constructor which is private allows the code to be written like it is in the question you do still need an instance for it to function correctly.

Joshua Cauble
yes, but the point is that you do not have to actually create the instance to get it working, even though it is an instance member, not a shared one.
naivists
For the love of Donald Knuth no. This answer is wrong and should not have any upvotes. Just because there is a static constructor doesn't allow you to invoke methods on unassigned instances and not run into a runtime exception. The level of confusion in this thread is astounding.
Jason
What Jason said. You can invoke this method on a null reference. That normally dies with a NullReferenceException.
Seva Alekseyev
As Jason stated, this answer is wrong
Alfred Myers
+1 to Jason... @Joshua - declaration of a variable absolutely does NOT create an instance of the type
AdamRalph
@Joshua - your edit is also incorrect. the static constructor does not allow code to be written as it does in the question. both versions of the code in the question do not work
AdamRalph
+16  A: 

Are you sure this works?

Dim instance As HttpServerUtility
Dim encodeMe As String = "a string to be encoded!"
instance.UrlEncode(encodeMe) 'Works!

This will give you a NullReferenceException at runtime (and the compiler will give you a warning that instance is not being assigned to). Seriously, Microsoft didn't do anything here. The above code is disastrously wrong and will die at runtime.

And you can't do this

Dim encodeMe As String = "a string to be encoded!"
HttpServerUtility.UrlEncode(encodeMe) 'Bombs out

because UrlEncode is not defined as a Shared method in HttpServerUtility.

You need a non-null instance of HttpServerUtility. The right way to use HttpServerUtility is like this:

Dim instance As HttpServerUtility = HttpContext.Server
Dim s As String = "Hello, World!"
Dim result As String = instance.UrlEncode(s)

Another option is to just use HttpUtility for which there is a Shared method HttpUtility.UrlEncode:

Dim s As String = "Hello, World!"
Dim result As String = HttpUtility.UrlEncode(s)
Jason
@divo: Then it's wrong on MSDN (not the first time). It will crash at runtime.
Jason
HttpUtility.UrlEncode(encodeMe) will save much time and pain over this debate
Matthew Whited
@Jason: I looked in the MSDN’s description of the method and didn’t find anything that’s wrong – though the doc *is* bad.
Konrad Rudolph
@Jason I believe you're right - the doc is bad and should read HttpServerUtility instance = HttpContext.Server;
impostal22
I just looked at the documentation. I think the confusion stems from the snippet labeled "Visual Basic (Usage)" (http://msdn.microsoft.com/en-us/library/zttxte6w.aspx). That is how all the documentation for VB.NET is written in MSDN. It's telling you that if you have a variable named `instance` of type `HttpServerUtility` and a variable named `s` of type string then you can invoke the method `HttpServerUtility.UrlEncode` via `instance.UrlEncode(s)`. For another example of exactly this type of documentation look at `StreamReader.Read` (http://msdn.microsoft.com/en-us/library/ath1fht8.aspx).
Jason
+2  A: 

Use HttpUtility.UrlEncode() instead of HttpServerUtility.UrlEncode(). The version on HttpServerUtility is an instance method and not a shared/static method. This has nothing to do with a static constructor (a static constructor would be called the first time a static method from the class is called)

Matthew Whited
+4  A: 

First of all, neither of the code examples you have given will work.

The first example will not work because UrlEncode is an instance method, therefore you cannot call it on the type, i.e. HttpServerUtility.UrlEncode(encodeMe).

The second example will not work because the variable has not been assigned.

This has nothing to do with static constructors and the answers posted stating as such are misleading.

The HttpServerUtility type is designed to be initialised only internally by the System.Web assembly. You cannot create your own instances of it. You can access an instance of it in a web application by using HttpContext.Server (which returns an instance of an HttpServerUtility).

AdamRalph