There has been some confusion about a change made to ScriptControls between the ASP.NET AJAX Beta2 and RC.  In Beta2, the only requirement for controls implementing IScriptControl or IExtenderControl was to call ScriptManager.RegisterScriptControl() or ScriptManager.RegisterExtenderControl() from their PreRender() method.  In RC, there is an additional requirement to call ScriptManager.RegisterScriptDescriptors() from the Render() method.

Beta2
public class MyScriptControl : Control, IScriptControl {
   
protected override void OnPreRender(EventArgs e) {
       
base.OnPreRender(e);
       
ScriptManager.GetCurrent(Page).RegisterScriptControl(this);
    }
}

RC
public class MyScriptControl : Control, IScriptControl {
   
protected override void OnPreRender(EventArgs e) {
       
base.OnPreRender(e);
       
ScriptManager.GetCurrent(Page).RegisterScriptControl(this);
    }

   
protected override void Render(HtmlTextWriter writer) {
       
base.Render(writer);
       
ScriptManager.GetCurrent(Page).RegisterScriptDescriptors(this);
    }
}

In the RC, we added this to the ExtenderControl base class, so this change doesn't affect controls deriving from ExtenderControl.  It only affects controls directly implementing IScriptControl and IExtenderControl.  This change is mentioned several times in the ASP.NET AJAX CTP to RC whitepaper (search for "RegisterScriptDescriptors").  The rest of this post explains the rationale behind this change.

We needed to make this change because there are some scenarios where a control's PreRender() method is called but its Render() method is not.  One example is a control inside a closed WebPart.  In Beta2, ScriptControls did not work inside closed WebParts.  The ScriptDescriptors would be registered, but the control would never render any HTML, which causes a JavaScript error when we try to find the associated HTML element.

To fix this issue, we needed to somehow verify that a ScriptControl was rendered before registering its ScriptDescriptors.  Unfortunately, there is no way to externally determine whether a control has been rendered, so the only solution was to require the ScriptControl to call into the ScriptManager from its Render() method.  We realize this extra call to RegisterScriptDescriptors() is annoying, but it was the only to fix the bug, and the change only affects controls directly implementing IScriptControl or IExtenderControl.  As a result, we added the ScriptControl base class in RC, which makes it easier to write a basic ScriptControl without directly implementing the IScriptControl interface.

The new model is also more correct from a purist's standpoint.  A control's script library is registered via its ScriptReferences, and it is safe to register these even if the control is never rendered.  To maximize flexibility in rendering these script libraries, the ScriptReferences must be registered during the PreRender phase.  A control's instance script is registered via its ScriptDescriptors, and it is not safe to register these if the control is never rendered.  So, the instance script must be registered during the control's Render phase.