ASP.NET Server Tags

There are a number of different server tags (<%, <%#, <%$, <%@, <%=) which each mean different things.

This article goes into a little depth talking about each of these tags.

The one I never use, is <%$, which I learned is for displaying expressions, but you can also easily write your own expression provider by extending the expressionbuilder class.  An example of doing so can be found here.

Pretty cool.

Advertisements

VS.Net Go To Implementation

Visual Studio has a nice “Go to definition” shortcut, but with our MVP pattern we are doing a lot of work against interfaces, which means that quite often going to definition actually takes us to a method in an interface.  For example:

Dim e As IEmployee = New Employee(1234)
Call e.GiveRaise(1.05)

If you did “Go to Definition” on “GiveRaise” you would not end up in the Employee class, but rather than IEmployee interface.

This plugin helps fix that problem.

I ended up skipping that part where he sets up the keyboard shortcut in favor of just using right click, but if you want to set that up you might find that the menu item he talks about is missing.  To get that dialog to show up use the keyboard shortcut CTRL+ALT+SHIFT+O.

 

Response.TransmitFile failed 0x8007052e

I was attempting to use Response.TransmitFile to stream a pdf directly to the user but it kept erroring with the following message in the event viewer:

TransmitFile failed. File Name: \somenaspath.pdf,
Impersonation Enabled: 0, Token Valid: 1, HRESULT: 0x8007052e

Turns out, you can’t use TransmitFile on any files that do not exist under the virtual application.  So trying to serve up a PDF from the NAS would never work this way :(.

I fell back to using .WriteFile and didn’t have the same problems.

 

 

ASP.NET Markup Go To Definition and Snippets

I don’t know if this is something new in VS or if it’s because I have the power tools installed, but I just realized that I can pick “Go to Definition” on an asp.net object in my code behind, like a label, or an asp.net checkbox, and instead of taking me to the vb definition of the control, it takes me to the place where the object is defined in the ASPX markup.   

And, in vs2010 if you auto complete with pressing tab 2 times when adding aspx markup items it will auto complete the entire element, not just the little bit you are typing.

 

So for example, if you type “<asp:But” and press tab you get:

 

<asp:Button

 

But if you tab again you get:

 

<asp:Button Text=”text” runat=”server” />

 

There are snippets included that are named things like “textbox” and “button”, so if you type “<bu” or “<hyp” and hit tab 2 times you get:

<asp:Button Text="text" runat="server" />

Or

<asp:HyperLink NavigateUrl="navigateurl" runat="server" />

 

Convert Spaces To Tabs For A Visual Studio Solution or Project

I recently installed some VS.Net power tools, and 1 of the tools is something that tells you when you have a file with mixed tabs and spaces, giving you the chance to convert from one to another.

I decided to stick with Tabs (I know that spaces v. tabs is a religious war for many, but I won’t go into it).  The problem is that this only happens on a file by file basis.  Furthermore, when you change the whitespace, your source controls sees that lots and lots of lines in your file have changed, making it hard to see the 1 or 2 lines that ACTUALLY changed.

I didn’t find a single utility out there for converting spaces to tabs, so after some poking around I’ve come up with a workaround that does the trick, even if it is a bit hackish.

I created a Find/Replace regular expression that will find leading groups of 4 spaces and replace them with tabs.  The problem is: you have to run it recursively.  So if you have a spot in your code with 10 tabs of indentation, you’ll need to run the find/replace 10 times in a row, which each iteration converting 1 of the groups of 4 spaces to a tab.

Each time you run the Find/Replace the count will get smaller and smaller, until finally: 0.

The basic pattern you search for is:

^{(t)*}([ ]^4)

and you replace with:

1t

In this example, the ^4 means that I’m treating 4 spaces as a tab.  Change the number if you want to have 2 spaces = a tab or whatever.

Another thing you can do to make it run faster on a large project is to first try to replace large sections of spaces before replaces 4 spaces at a time.  For example, the following stuff will search for 20 spaces and replace with 5 tabs.

You search for:

^{(t)*}([ ]^20)

and you replace with:

1ttttt

This way, if you have 1 spot in your code with 60 spaces, you won’t have to run the replace 15 times.

 

Rhino Mocks VB.NET Extension Methods and Expect compiler problems

So today I updated my Rhino Mocks library to the newest version and bam, all my tests broke.

The errors were all on lines where I was doing things like:

Expect.Call(viewMock.ViewState).Return(viewState).Repeat.Any()

The error was:

Overload resolution failed because no accessible 'Expect' accepts this number of arguments.  

I found a few others having the same problem

http://groups.google.com/group/RhinoMocks/browse_thread/thread/ebdfc26579f25da1

http://groups.google.com.ag/group/rhinomocks/browse_thread/thread/a85251a7ad2fae70

… but no real mention of why this was happening.

I found pretty quickly that if I fully qualified things, it would work.  For example, this works:

Rhino.Mocks.Expect.Call(viewMock.ViewState).Return(viewState).Repeat.Any()

But I was already importing Rhino.Mocks so why the problem?

 

As it is, the error is that the compiler is trying to call an extension method named “Expect”.  This method extends the class Rhino.Mocks.RhinoMocks and is defined in Rhino.Mocks.RhinoMocksExtensions.  The “Expect” that I actually want is a class defined in Rhino.Mocks that has a static/shared method “Call”.

So why is the extension method of RhinoMocks getting picked up?  I think it’s a combination of 2 different things that are happening here.  The first issue (I think) is that VB.Net does not support a static class.  Extension methods are defined in static classes in C# and in modules in VB.Net.  A module is kinda like a static class, except for a big difference: you don’t have to qualify the methods in a module by using the module name.

In other words if you have this in VB.Net

Module MyMod
    Public Sub DoSomething()
    End Sub
End Module

Class NotReallyStatic
    Public Shared Sub DoThis()
    End Sub
End Class

The way you would call the 2 methods is:

'*** Call DoSomething on the module
DoSomething()

'*** Call DoThis on NotReallyStatic
NotReallyStatic.DoThis()

So because VB treates the Static Class RhinoMockExtensions as a Module all the extension methods become in scope without any qualification, so you end up with a name collision on Expects.

The seconde issue is that the Expects extension method in Rhino Mocks is extending generic classes (e.g. T) where T is any class.  If the extension was happening on any concrete class, I don’t think we’d see this issue, but because it is ANY class, the VB compiler this it could apply anywhere inside any of your classes.  And remember, even if you DO require some concrete class for the extension,

Here’s an example of this.

Let’s say your extension methods are defined like this:

Public Module SomeClassExtensions
     <Runtime.CompilerServices.Extension()> _
     Public Sub ExtensionMethod(Of T As Class)(ByVal o As T, ByVal str As String)
         Console.WriteLine("")
     End Sub

     <Runtime.CompilerServices.Extension()> _
     Public Sub ExtensionMethodString(ByVal o As String, ByVal str As String)
         Console.WriteLine("")
     End Sub
 End Module

Note that the first uses a generic class and then second extends String.

Using these extension methods, basically ANYWHERE in your code (in VB) you could do the following:

'*** works
 Call ExtensionMethod("foo")
 Dim s As String
 s.ExtensionMethodString("foo")

 '*** won't work
 Call ExtensionMethodString("foo")

 '*** also works!
 Call ExtensionMethodString("foo", "bar")

You can see that we are able to call the generic extension method direct as if it were an instance method in whatever class we are currently working because (I think) the compiler is treating Me (or this in C#) as T, and the method is in scope because it is defined in a Module and not a Static Class as it would be in C#. 

We can’t directly call ExtensionMethodString because the class I am currently in does not inherit from String.  But, you’ll see at the end, because of the whole “Module vs Static Class” scope thing, we can still call the ExtensionMethodString directly but we have to pass in a string for the first parameter, which is supposed to be the parameter that tells the compiler what type of class to extend.

So the rule here is, if you have a Class Name (or really anything) and Extension Method Name that have the same name and are in the same namespace, you can run into this problem in VB.Net, and those problems get even worse if you are extending a generic class.

As I mentioned, you can get around this by fully qualifying your calls to Expect.Call, or you could change the way you do your expectations,  but if you are writing out these types of tests and don’t want to have to fully qualify everything, then you can use an import alias like this:

Imports DoExpect = Rhino.Mocks.Expect

Then you just change your “Expect.Call” to “DoExpect.Call” and all should work!

I think this could be fixed in Rhino Mocks quite simply.  I believe all that would need to happen is that RhinoMocksExtensions would just need to move to a different namespace, like Rhino.Mocks.Extensions.  I don’t think this change would even require additional changes to the Rhino Mocks codebase, but I’m not 100% sure on that.