I think you will best solve this problem by calling back to the server (via AJAX) to get the ads after the page has rendered on the end-user's browser.
You could do this via several technologies (AJAX.NET and UpdatePanels, plain-old-Javascript, or a JS framework like jQuery or MooTools along with a Web Service to serve up the ads), depending on your comfort.
With jQuery + ASHX option, you can do the following:
In the Javascript:
// when the document has finished loading
$(document).load(function() {
// make an AJAX request to MyHandler.ashx, with the content's height
var height = $("#ContentContainer").height()
$.get("MyHandler.ashx?contentheight=" + height, ResponseCallback);
}
// put the server's response (data) into the ad container
function ResponseCallback(data) {
$("#AdContainer").html(data);
}
In the HTML:
<body>
<div id="ContentContainer">
...
...
</div>
<div id="AdContainer"></div>
</body>
MyHandler.ashx:
public void ProcessRequest(HttpContext context) {
HttpRequest request = context.Request;
HttpResponse response = context.Response;
int height = Convert.ToInt32(request.QueryString["contentheight"] ?? "0");
// do something to calculate number of ads and get the HTML for the ads
// assuming we have a list of Advert objects:
List<Advert> ads = GetSomeAds(height);
foreach(Advert a in ads) {
response.Write(a.GetHtml());
}
}
Obviously the most integrated with ASP.NET is the UpdatePanel option, though I would recommend that you move towards using a JS framework with .ASHX (custom handlers) or .ASMX (web services) on the server side. It is much more transparent and comprehensible, in terms of knowing "what is this code doing?". UpdatePanels can seem like black magic.