AspPathGuru: A little T4 love for ASP.NET WebForms
Last month, I wrote a number of posts on using T4 templates to get strong typing in ASP.NET MVC applications. The result is the T4MVC template available on CodePlex. This template has been pretty popular with many MVC users, and I received a huge amount of feedback on improving it. Most of it has been integrated into the CodePlex version (see the extensive History section in the TT file!).
While T4MVC is only useful to MVC applications, someone suggested that ASP.NET WebForms applications could also benefit from some strong typing, so I put together a little T4 template that does some of that.
Unlike T4MVC which tries to cover a whole range of MVC scenarios (relating to Controllers, Actions and Views), this template just does one thing: it generates strongly typed constants that points to the path to all aspx/ascx/master files. Since it only deals with path, I called it AspPathGuru.tt.
To use it, just drop AspPathGuru.tt (attached to this post) to the root of your Web Application.
You’ll then be able to change code that looks like:
Control uc = LoadControl("~/UserControls/MyUserControl.ascx");
to
Control uc = LoadControl(Paths.UserControls.MyUserControl_ascx);
The benefits are clear:
- You get intellisense while typing the constant, helping you make sure you get it right.
- If you ever move, rename or delete the user control, you will get a compile time error instead of a runtime error, hence catching the issue much earlier.
Some limitations you should be aware of:
- It only supports Web Applications, not Web Sites. This is because T4 templates don’t get processed in Web Sites (at least I couldn’t get them to, maybe there is a way).
- You need to save the .tt file for the generation to occur. So whenever you add or rename aspx/ascx file that you’d like to point to using the generated constant, you should save it. In T4MVC, I implemented a workaround that causes the template to run whenever you build, and we could do this for AspPathGuru as well, but I wanted to keep it nice and simple to stat with.
- It’s probably obvious, but the generated constants are only usable is places where you can write code, like the LoadControl call above. So don’t try to use it as the ‘src’ in a <%@ Register %> directive; it will not work!
Anyway, at this point this is just a simple template that covers this one scenario, and is certainly much less ambitious than T4MVC. Generally, I think that there just aren’t as many areas in WebForms that can benefit from code generation compared to MVC, but at least this is one!
Let me know if you find this useful, or if you can think of other areas where a T4 template could benefit WebForms applications.
Comments
Anonymous
July 13, 2009
David, How do I use this with query string (i.e. Default.aspx?Action=1)Anonymous
July 13, 2009
Hien Khieu: the constants are a replacement to hard coded literal strings, and can be used the same way. So you can certainly append extra things to them. But note that the value of the constant in the ~/ virtual path, which is not meant for client consumption. It's only meant for server side usages like LoadControl.Anonymous
July 13, 2009
Thank you very much, David. Your T4 stuff is awesome.Anonymous
July 15, 2009
Haha, I did something like this a while ago. http://www.codeproject.com/KB/aspnet/slink.aspx But I don't really maintain it anymore. Nice work :)Anonymous
July 16, 2009
For those interested in factoring out the paths, I've always taken the following approach (Only works in Web Projects, not Web Applications). Create multiple, static "URL" methods on each page's code-behind. Each method should be a valid "signature" for the page, with strongly-typed arguments. The method should return the proper URL for calling that page with the provided arguments. This puts the "magic path string" as well as the URL concatenation logic into the page itself. Now none of the rest of the application needs to know where the page is, or what its parameters are called.Anonymous
July 31, 2009
Is there a way to create a richer code generation by building a custom T4 host for ASP.NET forms web application? How hard would be to add menu items to WAP project to build MVP kind of classes (view and presenters) from Model classes? I guess we could right click on a model class (business entity and you would be presented with 2 menu items to generate Presenter and View)? Thanks, RadAnonymous
July 31, 2009
Rad: this could certainly be done, but it would be completely different from this template, because it would do 'one time generation' instead of 'support code' (see this post: http://blogs.msdn.com/davidebb/archive/2009/07/17/two-ways-to-use-t4-templates-support-code-vs-one-time-generation.aspx). What you're describing would be analogous to what ASP.NET MVC supports (e.g. Add View).Anonymous
January 31, 2011
This is great. I was going to do this myself, but you've saved me the trouble.