No se puede obtener ScriptManager.RegisterStartupScript en WebControl anidado en UpdatePanel para funcionar

StackOverflow https://stackoverflow.com/questions/802506

Pregunta

Estoy teniendo lo que creo que debería ser un problema bastante simple, pero por mi vida no puedo ver mi problema. El problema está relacionado con ScriptManager.RegisterStartupScript, algo que he usado muchas veces antes.

El escenario que tengo es que tengo un control web personalizado que se ha insertado en una página. El control (y uno o dos más) están anidados dentro de un UpdatePanel. Se insertan en la página en un PlaceHolder:

<asp:UpdatePanel ID="pnlAjax" runat="server">
  <ContentTemplate>
    <asp:PlaceHolder ID="placeholder" runat="server">
    </asp:PlaceHolder>
    ...

protected override void OnInit(EventArgs e){
  placeholder.Controls.Add(Factory.CreateControl());
  base.OnInit(e);
}

Este es el único panel de actualización en la página.

El control requiere que se ejecute javascript inicial para que funcione correctamente. El control llama:

ScriptManager.RegisterStartupScript(this, GetType(), 
                                    Guid.NewGuid().ToString(), script, true);

y también he intentado:

ScriptManager.RegisterStartupScript(Page, Page.GetType(), 
                                    Guid.NewGuid().ToString(), script, true);

El problema es que el script se ejecuta correctamente cuando se muestra la página por primera vez, pero no se vuelve a ejecutar después de una devolución de datos parcial. He intentado lo siguiente:

  1. Llamando a RegisterStartupScript desde CreateChildControls
  2. Llamando a RegisterStartupScript desde OnLoad / OnPreRender
  3. Usando diferentes combinaciones de parámetros para los dos primeros parámetros (en el ejemplo anterior, el Control es Page y Type es GetType (), pero he intentado usar el control en sí, etc.).
  4. He intentado usar identificadores persistentes y nuevos (no es que crea que esto debería tener un impacto importante de ninguna manera).
  5. He usado algunos puntos de interrupción y he verificado que la línea de registro se llama correctamente.

Lo único que no he probado es usar el propio UpdatePanel como Control y Tipo, ya que no creo que el control deba tener en cuenta el panel de actualización (y, en cualquier caso, no parece ser una buena forma de obtener el panel de actualización?).

¿Alguien puede ver lo que podría estar haciendo mal en lo anterior?

Gracias :)


Bueno, para responder la consulta anterior, parece como si el marcador de posición de alguna manera estropeara el ScriptManager.RegisterStartupScript.

Cuando saco el control del marcador de posición y lo codifico directamente en la página, el script de Registro funciona correctamente (también estoy usando el control como parámetro).

ScriptManager.RegisterStartupScript(this, GetType(), Guid.NewGuid().ToString(), script, true);

¿Alguien puede arrojar luz sobre por qué un control inyectado en un PlaceHolder impediría que el ScriptManager registrara correctamente el script? Supongo que esto podría tener algo que ver con el ciclo de vida de los controles dinámicos, pero agradecería (por mi propio conocimiento) si hay un proceso correcto para lo anterior.

¿Fue útil?

Solución

Creo que debería usar la Control de sobrecarga de RegisterStartupScript.

He probado el siguiente código en un control de servidor:

[ToolboxData("<{0}:AlertControl runat=server></{0}:AlertControl>")]
public class AlertControl : Control{
    protected override void OnInit(EventArgs e){
        base.OnInit(e);
        string script = "alert(\"Hello!\");";
        ScriptManager.RegisterStartupScript(this, GetType(), 
                      "ServerControlScript", script, true);
    }
}

Entonces en mi página tengo:

protected override void OnInit(EventArgs e){
    base.OnInit(e);
    Placeholder1.Controls.Add(new AlertControl());
}

Donde Placeholder1 es un marcador de posición en un panel de actualización. El marcador de posición tiene un par de otros controles, incluidos los botones.

Esto se comportó exactamente como era de esperar, recibí una alerta que decía " Hola " cada vez que cargaba la página o hacía que el panel de actualización se actualizara.

La otra cosa que podría ver es conectarse a algunos de los eventos del ciclo de vida de la página que se activan durante una solicitud de panel de actualización:

Sys.WebForms.PageRequestManager.getInstance()
   .add_endRequest(EndRequestHandler);

El evento PageRequestManager endRequestHandler se activa cada vez que un panel de actualización completa su actualización: esto le permitiría llamar a un método para configurar su control.

Mis únicas otras preguntas son:

  • ¿Qué está haciendo realmente tu script?
  • Presumiblemente puede ver el script en el HTML en la parte inferior de la página (justo antes del cierre < / form > tag)?
  • ¿Has intentado poner algunas " alert (" Here "); " llama en su script de inicio para ver si se llama correctamente?
  • ¿Has probado Firefox y Firebug ? ¿Eso informa algún error de script?

Otros consejos

Tuve un problema al usar esto en un control de usuario (en una página esto funcionó bien); el Button1 está dentro de un updatepanel, y el scriptmanager está en el usercontrol.

protected void Button1_Click(object sender, EventArgs e)  
{  
    string scriptstring = "alert('Welcome');";  
    ScriptManager.RegisterStartupScript(this, this.GetType(), "alertscript", scriptstring, true);  
}

Ahora parece que debes tener cuidado con los dos primeros argumentos, deben hacer referencia a tu página, no a tu control

ScriptManager.RegisterStartupScript(this.Page, this.Page.GetType(), "alertscript", scriptstring, true);

Cuando llama a ScriptManager.RegisterStartupScript, el " Control " El parámetro debe ser un control que esté dentro de un UpdatePanel que se actualizará. Debe cambiarlo a:

ScriptManager.RegisterStartupScript(this, this.GetType(), Guid.NewGuid().ToString(), script, true);

La solución es colocar los scripts en un archivo js externo (llamado 'yourDynamic.js') y volver a registrar el archivo cada vez que actualice el panel de actualización.

Lo uso en el evento updatepanel_prerender:

ScriptManager.RegisterClientScriptBlock(UpdatePanel1, UpdatePanel1.GetType(), "UpdatePanel1_PreRender", _
                   "<script type='text/javascript' id='UpdatePanel1_PreRender'>" & _
                   "include('yourDynamic.js');" & _
                   "removeDuplicatedScript('UpdatePanel1_PreRender');</script>" _
                   , False)

En la página o en alguna otra inclusión, necesitará este javascript:

// Include a javascript file inside another one.
function include(filename)
{
    var head = document.getElementsByTagName('head')[0];

    var scripts = document.getElementsByTagName('script');
    for(var x=0;x<scripts.length;>    {
        if (scripts[x].getAttribute('src'))
        {
            if(scripts[x].getAttribute('src').indexOf(filename) != -1)
            {
                head.removeChild(scripts[x]);
                break;
            }
        }
    }

    script = document.createElement('script');
    script.src = filename;
    script.type = 'text/javascript';
    head.appendChild(script)
}

// Removes duplicated scripts.
function removeDuplicatedScript(id)
{
    var count = 0;
    var head = document.getElementsByTagName('head')[0];

    var scripts = document.getElementsByTagName('script');
    var firstScript;
    for(var x=0;x<scripts.length;>    {
        if (scripts[x].getAttribute('id'))
        {
            if(scripts[x].getAttribute('id').indexOf(id) != -1)
            {
                if (count == 0)
                {
                    firstScript = scripts[x];
                    count++;
                }
                else
                {
                    head.removeChild(firstScript);
                    firstScript = scripts[x];
                    count = 1;
                }
            }
        }
    }
    clearAjaxNetJunk();
}
// Evoids the update panel auto generated scripts to grow to inifity. X-(
function clearAjaxNetJunk()
{
    var knowJunk = 'Sys.Application.add_init(function() {';
    var count = 0;
    var head = document.getElementsByTagName('head')[0];

    var scripts = document.getElementsByTagName('script');
    var firstScript;
    for(var x=0;x<scripts.length;>    {
        if (scripts[x].textContent)
        {
            if(scripts[x].textContent.indexOf(knowJunk) != -1)
            {
                if (count == 0)
                {
                    firstScript = scripts[x];
                    count++;
                }
                else
                {
                    head.removeChild(firstScript);
                    firstScript = scripts[x];
                    count = 1;
                }
            }
        }
    }
}

Muy bien, ah ... jejeje Esta parte de lo que publiqué hace algún tiempo aquí .

Espero que esta ayuda ... :)

Tuve un problema con Page.ClientScript.RegisterStartUpScript: no estaba usando un panel de actualización, pero el control estaba en caché. Esto significaba que tenía que insertar el script en un Literal (o podría usar un PlaceHolder) para que cuando se procesara desde el caché se incluyera el script.

Una solución similar podría funcionar para usted.

NO USE GUID para la clave

ScriptManager.RegisterClientScriptBlock(this.Page, typeof(UpdatePanel) 
       Guid.NewGuid().ToString(), myScript, true);

y si quieres hacer eso, llama a Something Like this function

 public static string GetGuidClear(string x)
 {
      return x.Replace("-", "").Replace("0", "").Replace("1", "")
              .Replace("2",  "").Replace("3", "").Replace("4", "")
              .Replace("5", "").Replace("6", "").Replace("7", "")
              .Replace("8", "").Replace("9", "");
 }

Lo que funcionó para mí, es registrarlo en la página mientras especifica el tipo como el UpdatePanel, así:

ScriptManager.RegisterClientScriptBlock(this.Page, typeof(UpdatePanel) Guid.NewGuid().ToString(), myScript, true);

A veces no se activa cuando el script tiene algún error de sintaxis, asegúrese de que el script y la sintaxis de JavaScript sean correctos.

ScriptManager.RegisterStartupScript(this, this.GetType(), Guid.NewGuid().ToString(),script,  true );

El " verdadero " el valor de parámetro al final del ScriptManager.RegisterStartupScript agregará una etiqueta de JavaScript dentro de su página:

<script language='javascript' defer='defer'>your script</script >

Si el valor será " false " inyectará solo el script sin la etiqueta --script--.

Intento muchas cosas y finalmente descubrí que el último parámetro debe ser falso y debe agregar la etiqueta <SCRIPT> al script java:

string script = "< SCRIPT >alert('hello!');< /SCRIPT>";

ScriptManager.RegisterClientScriptBlock(Page, Page.GetType(), key, script, **false**);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top