Zephyris13
Zephyris13

Reputation: 21

ScriptManager not loading javascript method under Mono

I've been trying to get my head around this issue I'm having with asp.net ScriptManager.RegisterStartupScript().

The lines of code are as follows -

string script = string.Format("initGame('{0}','{1}');", var1, var2);

ScriptManager.RegisterStartupScript(Page, typeof(Page), "mainGameScript", script, true);

The page is hosted on an Ubuntu machine, running apache 2 and mono. Whatever I write in the RegisterStartupScript doesn't work.

Things I've tried -

  1. Windows Server with IIS - works perfectly
  2. Output some web text immediately before calling ScriptManager - works
  3. Coding in a button that calls the "initGame()" method - works
  4. Putting javascript directly into the RegisterStartupScript call - doesn't work
  5. Putting javascript in the page - works

To me it seems like there is an issue with the ScriptManager line, either something trivial, or something that I need to do/change for it to run under Mono. If you wish to take a look, the url is www.zephyrisgames.net/zephyrisgalaxies/Main.aspx

Thank you, and if you need more information, please tell me, I'll try to produce it.

Upvotes: 1

Views: 864

Answers (2)

Tobias81
Tobias81

Reputation: 1850

I ran into the same problem. "ScriptManager.RegisterStartupScript" does not work if in async post-back (ASP.NET 2.0, Ubuntu Server 13.10). It works well if the page is first loaded though.

After digging through the Mono sources at https://github.com/mono/mono/blob/master/mcs/class/System.Web.Extensions/System.Web.UI/ScriptManager.cs I saw that there is some pre-compiler stuff where the scripts are being added to the final output:

switch (scriptEntry.ScriptType) {
  case RegisteredScriptType.ClientScriptBlock:
    if (scriptEntry.AddScriptTags)
      WriteCallbackOutput(output, scriptBlock, scriptContentNoTags, scriptEntry.Script);
    else
      WriteCallbackOutput(output, scriptBlock, scriptContentWithTags, SerializeScriptBlock(scriptEntry));
    break;
#if NET_3_5
  case RegisteredScriptType.ClientStartupScript:
    if (scriptEntry.AddScriptTags)
      WriteCallbackOutput (output, scriptStartupBlock, scriptContentNoTags, scriptEntry.Script);
    else
      WriteCallbackOutput (output, scriptStartupBlock, scriptContentWithTags, SerializeScriptBlock (scriptEntry));
    break;
#endif
  case RegisteredScriptType.ClientScriptInclude:
    WriteCallbackOutput(output, scriptBlock, scriptPath, scriptEntry.Url);
    break;
  case RegisteredScriptType.OnSubmitStatement:
    WriteCallbackOutput(output, onSubmit, null, scriptEntry.Script);
    break;
}

Maybe someone forgot to define "NET_3_5" and so that part is not working. Additionally on initial page-load "ScriptManager.RegisterStartupScript" actually calls "ClientScript.RegisterStartupScript" (that's the reason why it works in that case).

My solution is to emulate the behavior with "ScriptManager.RegisterClientScriptBlock" (which works as expected):

/// <summary>
/// Always adds script tags.
/// </summary>
public static void ScriptManagerRegisterStartupScript(Control control, Type type, string key, string script){
  if (!ScriptManager.GetCurrent(control.Page).IsInAsyncPostBack)
    control.Page.ClientScript.RegisterStartupScript(type, key, script, true);
  else {
    string hName = String.Format("h{0}", Guid.NewGuid().ToString("N"));  // Lazy way to get a unique name
    ScriptManager.RegisterClientScriptBlock(control, type, key,
      "function " + hName + " () {" + 
      "Sys.WebForms.PageRequestManager.getInstance().remove_pageLoaded(" + hName + ");" +
      script +  // This is why we do not support "addScriptTags==false"
      "}" +
      "Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(" + hName + ");",
      true);
  }
}

Upvotes: 0

Zephyris13
Zephyris13

Reputation: 21

After splitting hairs over this, I'm becoming more and more convinced there is an issue with ScriptManager. I even installed Mono 3.07 from the repos, but still that didn't solve anything.

What solved it was replacing ScriptManager with the ClientScript class. The method remains the same, though RegisterStartupScript() under the ClientScript class does not have the option to add the script tags.

A simple remedy is as follows -

string tagStart = "<script type=\"text/javascript\">";
string tagEnd = "</script>";
string script = string.Format("initGame('{0}','{1}');", var1, var2);

script = tagStart + script + tagEnd;

if (!Page.ClientScript.IsStartupScriptRegistered("mainGameScript"))
{
     //ScriptManager.RegisterStartupScript(Page, typeof(Page), "mainGameScript", script, true);
     // Left in for historical purpose

    ClientScript.RegisterStartupScript(typeof(Page), "mainGameScript", script);
 }

Upvotes: 1

Related Questions