Tales from the Evil Empire

Bertrand Le Roy's blog

News


Bertrand Le Roy

BoudinFatal's Gamercard

Tales from the Evil Empire - Blogged

Blogs I read

My other stuff

Archives

July 2009 - Posts

Hiring for new super-secret project

Well, I guess it’s not so super-secret anymore now but these last few months, I’ve been transitioning from ASP.NET Ajax to a new project that aims at helping ASP.NET communities build Open Source applications on ASP.NET. It’s a lot of fun and the good news is that you can join in. We are hiring a senior developer:

https://careers.microsoft.com/JobDetails.aspx?ss=&pg=0&so=&rw=1&jid=4567&jlang=EN

Please mention me (Bertrand Le Roy, bleroy at Microsoft) as the referral if you apply. ;)

Mocking indexer getters with Moq

(c) Bertrand Le Roy This is a follow-up on that other post: Mocking indexer setters with Moq.

So thanks to that post, we now know how to intercept the setting of a particular indexed property (in our example, an application variable) and set a local variable with the value that was set by the tested code.

Now if you want the application to return that same value when queried by the tested code, you also need to mock the indexer getter.

This operation is also not entirely trivial. Here’s how you do it: you do a SetupGet chained with a Returns with a lambda expression as the parameter:

mockHttpContext
.SetupGet(c => c.Application["foo"]) .Returns(() => (object)map);

That last point about using a lambda is pretty important. If you just use map as the parameter for Returns, Moq will hold on to a reference to whatever object map contained at the time the call to Returns is made. This might very well be null, if you started with the code in our previous setter example. If you use a lambda on the other hand, Moq will not hold on to the value of map but to the expression that returns the value of map. The execution is deferred. Now every time the tested code exercises that path, Moq will evaluate the expression, which will return the current value of map.

Also of interest, whereas we had to explicitly have an index parameter for the callback lambda in the case of the setter, Returns needs no such thing, and this example actually has little code that is specific to indexed properties. The trick about the lambda in the Returns in particular applies just as well to mocking getters for non-indexed properties.

Tell me what smells in WebForms as a view engine

Fisherman's Friend Don’t read too much into this, but I’d love to read your feedback on this. I’m compiling a list of stuff that smells in WebForms when used as a view engine in MVC.

Along the lines of:

  • Noisy page directives that are useless for MVC
  • runat=server
  • Page lifecycle

For once, you can let the inside troll take over :)

Mandelbrot set in a twitcode

Kinik just published a pretty amazing #twitcode version of a Mandelbrot set visualization in JavaScript that Jacob Seidelin wrote.

Here’s the code:

for(k=84;k-=1/32;document.write(k%3?i%8:'<br/>'))
for(x=y=0,i=99;--i/y;x=t)t=x*x-y*y+1-k%3,y=1-k/42+y*x*2

And here’s what it renders:

Mandelbrot

http://twitter.com/KiniK/statuses/2575582146

A (less) simple include for ASP.NET

(c) 2003 Bertrand Le Roy In yesterday’s post, I published the code for a simple include method for ASP.NET that I’ve been using in a couple of places, only to realize that it was fine for what I was doing but probably not very useful beyond that.

So I spent some time today broadening its scope. It now supports nested includes (I modified the original post to reflect that change) and also setting properties on the control.

You can still do plain includes:

<% this.Include("contents.ascx"); %>

But now you can also set properties on the included user control using an anonymous object:

<% this.Include("contents.ascx", new {number=2, what="A"}); %>

The code for the helper considerably grew along the way but it’s still reasonable:

using System;
using System.Linq;
using System.Reflection;
using System.Web.UI;

public static class IncludeHelper {
    public static void Include(this TemplateControl host,
string virtualPath) { Include(host, virtualPath, null); } public static void Include(this TemplateControl host,
string virtualPath,
object properties) { var resolvedPath = host.ResolveUrl(virtualPath); var include = host.LoadControl(resolvedPath); if (properties != null) { var includeType = include.GetType(); foreach (var fieldInfo in
properties.GetType().GetProperties()) { var targetInfo = includeType.GetMember(
fieldInfo.Name, MemberTypes.Field |
MemberTypes.Property, BindingFlags.IgnoreCase |
BindingFlags.Instance |
BindingFlags.Public) .FirstOrDefault(); var targetPropertyInfo = targetInfo as PropertyInfo; if (targetPropertyInfo != null) { targetPropertyInfo.SetValue(
include,
fieldInfo.GetValue(properties, null),
null); } else { var targetFieldInfo = targetInfo as FieldInfo; if (targetFieldInfo != null) { targetFieldInfo.SetValue(
include,
fieldInfo.GetValue(properties, null)); } else { throw new ArgumentException( "There is no property of field with " +
"that name on the target control."
, fieldInfo.Name); } } } } using (var writer =
new HtmlTextWriter(host.Page.Response.Output)) { include.RenderControl(writer); } } }

I hope this helps. Again, if you are OK with the regular syntax to include a user controls, you probably shouldn’t use this and stick to what you know. I built this because I’m not entirely satisfied with that syntax and because I have a clear use case where it makes more sense. Make your own opinion and follow it :)

Note: The control is still not going into the control tree, which breaks lots of stuff. I don't really care that much about it but it may be important to you so I thought I'd point it out.

A simple include for ASP.NET

(c) 2005 Bertrand Le Roy In yesterday’s post, I alluded to a simple include extension method that I like to use when I don’t care about designer support. In a comment, Andrew asked if I could share the code for it, so here it is.

I never liked the regular way of including user controls in WebForms and how they require a registration and a declaration, both of which are more verbose than they need to be. A plain #include would work but is a little outdated (and if I’m not mistaken it’s not even available by default in IIS7).

My Include method is quite similar to MVC’s RenderPartial except that it doesn’t deal with view data. It’s a plain and simple include. Just give it the relative path to a user control:

<% this.Include("Header.ascx"); %>

Here’s the code for that extension method:

using System.Web;
using System.Web.UI;

public static class IncludeHelper {
    public static void Include(this TemplateControl host,
string virtualPath) { var resolvedPath = host.ResolveUrl(virtualPath); var include = host.LoadControl(resolvedPath); using (var writer =
new HtmlTextWriter(host.Page.Response.Output)) { include.RenderControl(writer); } } }

It just resolves the path, loads the control and renders it in place.

To use that method, just drop the code as a cs file into App_code if you’re using a web site, or just add it to your project otherwise.

I played with the idea of enabling an anonymous object parameter to set properties on the user control, but I guess if you’re going to do that, the benefits of the helper get dimmer and going with the regular WebForms user control registration and tags is probably just easier (you’ll get IntelliSense on the properties for example).

Disclaimer/update: No, this does not run the control through the page lifecycle (although it could by adding it to the page’s control tree and removing it after rendering it). No, if you use master pages you probably don’t need it. No, you can’t set properties.

This is just the simplest include I could build, and it does only that: including contents. If it seems useless to you, it probably is. I published it mainly because I was asked to. :)

Update: I wrote a more complex version that can set properties on the included controls:
http://weblogs.asp.net/bleroy/archive/2009/07/10/a-less-simple-include-for-asp-net.aspx

Are Master Pages too complex?

MasterLockMaster Pages are a wonderful concept that as developers we highly value. It’s the sort of pattern that just looks like the right thing to do (to our twisted, concept hungry developer minds) and that even makes you wonder why we haven’t done it that way since the beginning of time (1990). For the record, master pages were invented by David Ebbo, who is behind a lot of the smartest things in ASP.NET.

Just in case you have no idea, what are Master Pages? Before master pages, sharing layout between pages was done using includes (or user controls). For example, your typical hello world page might have looked like this:

<%@ Page Language="C#" %>
<%@ Register TagPrefix="include" TagName="header"
Src="~/HelloHeader.ascx" %> <%@ Register TagPrefix="include" TagName="footer"
Src="~/HelloFooter.ascx" %> <!DOCTYPE html> <html> <head> <title>Hello world with includes</title> </head> <body> <div> <include:header runat="server" />
Hello world! <include:footer runat="server" /> </div>
</body> </html>

Notice that the page does contain markup that is not specific to the page (boilerplate markup mainly that you could put into includes as well, but only at the cost of breaking beginnings and ends of semantic blocks into separate includes).

As a side note, I’ve always thought the user control syntax above was overly verbose when all you want is a plain include. It has the one advantage of enabling the Visual Studio designer but having a separate registration and declaration seems overkill. The #include directive still exists but I personally prefer to use a simple helper extension method to Page that brings the code down to this (MVC gives you Html.RenderPartial, which is roughly equivalent):

<%@ Page Language="C#" %>
<!DOCTYPE html>
<html>
<head>
    <title>Hello world with includes</title>
<meta name="keywords" content="hello world" /> </
head> <body> <div>
<% this.Include("HelloHeader.ascx"); %> Hello world!
<% this.Include("HelloFooter.ascx"); %> </div>
</body> </html>

With master pages, you can get rid of all common markup and really limit what you put into the page to just what varies from page to page. for example, the above hello world page might be written like this:

<%@ Page Language="C#" MasterPageFile="~/MasterPage.master"
Title="Hello world!" %> <asp:Content ContentPlaceHolderID="head" Runat="Server"> <meta name="keywords" content="hello world" /> </asp:Content> <asp:Content ContentPlaceHolderID="content" Runat="Server"> Hello from the content page! </asp:Content>

That is clean, but pretty puzzling the first time you see it. To understand where the markup comes from, you need to track that @Page directive and understand that you need to look into the corresponding master page file:

<%@ Master Language="C#" %>
<!DOCTYPE html>
<html>
<head runat="server">
    <title>Master page</title>
    <asp:ContentPlaceHolder id="head" runat="server">
    </asp:ContentPlaceHolder>
</head>
<body>
    <h1>Hello from a master page</h1>
    <div>
        <asp:ContentPlaceHolder id="content" runat="server">
        </asp:ContentPlaceHolder>
    </div>
    Footer says hi.
</body>
</html>

You need to understand that those content place holder ids correspond to other controls that are in the master page and that the framework will make the match.

Master pages also come with the price of mangled ids, but that’s an implementation detail (one could imagine an implementation that wouldn’t suffer from that problem). The price we pay for master pages also comes in the form of a weird control tree: master pages are really implemented as user controls that get included by the page, a concept that is the inverse of the model they seem to promote; in other words, the implementation is the reverse of the concept, in a way. There are also complications about putting contents in the head section (head must be runat=server, script tags are tricky, setting the title, etc.).

So are master pages worth the price? It depends on who your audience is and on how your pages are built.

By audience, I mean the person who is going to write the views. If it’s just you and you are a developer, they might actually be a pretty solid choice. But if external designers are going to build the views, maybe you need to pause and try not to think as a developer for a moment.

The main problem with the include approach (and the reason why master pages were invented) is that the outer markup for the page needs to be on all pages. So if you decide to change that markup, you need to do so on all pages.

But in more and more applications, in particular CMS, this problem becomes moot. If your application decouples the content from the view code, and if the layout or view to use for a given content can be determined at runtime by a themeing engine, you might end-up with templates that look like this:

<%@ Page Language="C#" %>
<!DOCTYPE html>
<html>
<head>
    <title><%= Title %></title>
</head>
<body>
    <div>
    <% this.RenderZone("Header"); %>
    <% this.RenderZone("Contents"); %>
    <% this.RenderZone("Footer"); %>
    </div>
</body>
</html>

This is actually no different in concept from master pages (there are place holders in generic markup and no specific contents) but the contents do not come from a content page. Instead, they are dynamically inserted by the application.

The template file then becomes no more than layout. It is easy to understand and easier to assign a different layout to any given contents.

So in general there is no perfect answer on whether you should use master pages or not, but if you are able, in your application, to decouple page layout from contents, there is an opportunity to have clean and easy to understand markup that also maximizes re-use.

More Posts