c# - ASP.NET ScriptManager output not included in ASP.NET partial cache (ascx) -


i wrote simple control, implements scriptcontrol. holder jquery framework:

 /// <summary> /// generic control client behavior handled via jquery /// </summary> public abstract partial class jqcontrol : scriptcontrol, inamingcontainer {     /// <summary>     /// client method called after jquery initialization     /// </summary>     [persistencemode(persistencemode.innerproperty)]     public jqraw afterinit     {         get;         set;     }      /// <summary>     /// client method called before jquery initialization     /// </summary>     [persistencemode(persistencemode.innerproperty)]     public jqraw preinit     {         get;         set;     }      /// <summary>     /// data initialize control (name-value pairs)     /// </summary>     public idictionary<string, object> initdata     {         get; set;     }      /// <summary>     /// authorization templates registered , used privilege manager     /// </summary>     public idictionary<string, authorizationtemplate> authorizationtemplates     {         get; set;     }      /// <summary>     /// if themepath specified, css file looked , loaded theme folder     /// </summary>     protected string themecssname     {         get; set;     }      private string _themepath;      /// <summary>     /// specifies path custom css , images enable theming.     /// </summary>     public string themepath     {                 {             return _themepath == null ? defaultthemehelper.themename : resolveclienturl(_themepath);         }         set         {             _themepath = value;         }     }      /// <summary>     /// collection of streamed javascript files     /// </summary>     private readonly list<scriptreference> scriptrefs = new list<scriptreference>();      /// <summary>     /// collection of streamed stylesheet files     /// </summary>     private readonly list<string> cssrefs = new list<string>();      protected override void oninit(eventargs e)     {         base.oninit(e);         fillscriptreferences();     }      protected override void onprerender(eventargs e)     {         base.onprerender(e);      }     protected bool usedynamiccss = true;         private bool dynamiccssenabled;     protected void enabledynamiccss()     {         if(!dynamiccssenabled)         {             //enable dynamic css loading             addscriptreference(typeof(jqcontrol), "lwm.implementation.controls.dynamicstylesheet.css.js");             dynamiccssenabled = true;         }     }      protected virtual void fillscriptreferences()     {         type t = typeof(jqcontrol);         addscriptreference(t, "lwm.implementation.controls.jscripts.jquery.js");         addscriptreference(t, "lwm.implementation.controls.jscripts.extendjquery.js");         addscriptreference(t, "lwm.implementation.controls.jscripts.extendajaxdotnet.js");         addscriptreference(t, "lwm.implementation.controls.jq.chainrequests.js");         addscriptreference(t, "lwm.implementation.controls.jscripts.jquery.jcache.js");         addscriptreference(t, "lwm.implementation.controls.jscripts.jquery.cookie.js");         addscriptreference(t, "lwm.implementation.controls.jscripts.jquery.offset.js");         //if ((_themepath != null && themecssname != null))         {             enabledynamiccss();                         }     }      //added render automatically assigned id, otherwise escaped     protected override void addattributestorender(htmltextwriter writer)     {         const string extcss = "jqcontrol";         this.cssclass = this.cssclass != null ? this.cssclass + " " + extcss : extcss;          base.addattributestorender(writer);         writer.addattribute(htmltextwriterattribute.id, clientid);         //writer.addattribute(htmltextwriterattribute.class, cssclass);     }      /// <summary>     /// ataches embedded script refernnce using full name     /// </summary>     /// <param name="name">name of reference</param>     /// <param name="usebaseclassassembly">true if using base class assembly</param>     protected void attachscriptreferncebyname(string name, bool usebaseclassassembly)     {         //current type         type type = this.gettype();         if (usebaseclassassembly)         {             //base type             type = type.basetype;         }         addscriptreference(type, name);     }      private void _addcssreference(type type, string name)     {         string assembly = type.assembly.fullname;         type t = null;         if (boosthelper.adjustresourceparts(this, type.assembly, ref assembly, ref name, ref t))         {            //  loggerhelper.loginfo(string.format("css init with- client script:{0}, type:{1}, name:{2} ", this.page.clientscript.tostring(),t.tostring(),name),"lwmsiteresourcebooster");              var sr = new dynamicstylesheetscriptreference(this.page.clientscript, t, new[] { name });    //(name, assembly);              if (!scriptrefs.contains(sr))             {                 scriptrefs.add(sr);             }         }         else         {             string url = name;  // getembeddedurl(type, name);             if (!cssrefs.contains(url))             {                 cssrefs.add(url);             }         }     }      //protected void addcssreference(string name, type type)     //{     //    _addcssreference(type, name);     //    if (cssrefs.count > 0)     //    {     //        scriptrefs.add(new dynamicstylesheetscriptreference(this.page.clientscript, type, cssrefs.toarray()));     //        cssrefs.clear();     //    }     //}      protected void addcssreference(type type, params string[] names)     {         if (names == null) return;         foreach (string name in names)         {             _addcssreference(type, name);         }         if(cssrefs.count > 0)         {             scriptrefs.add(new dynamicstylesheetscriptreference(this.page.clientscript, type, cssrefs.toarray()));             cssrefs.clear();         }     }       protected void removecssreference(type type, string name)     {         //todo         //if (cssrefs.contains(url))         //{         //    cssrefs.remove(url);         //}     }      protected void addscriptreference(type type, string name)     {           //full name of current assembly                     string assembly = type.assembly.fullname;         type t = null;         boosthelper.adjustresourceparts(this, type.assembly, ref assembly, ref name, ref t);         var sr = new humanreadablescriptreference(name, assembly);         if (!scriptrefs.contains(sr))         {             scriptrefs.add(sr);         }     }      protected void removescriptreference(type type, string name)     {         //full name of current assembly                     string assembly = type.assembly.fullname;         type t = null;         boosthelper.adjustresourceparts(this, type.assembly, ref assembly, ref name, ref t);         var sr = new humanreadablescriptreference(name, assembly);         if (scriptrefs.contains(sr))         {             scriptrefs.remove(sr);         }     }      private string _jqbreadcrumb;      /// <summary>     /// unique jquery pattern identifies control     /// </summary>     protected string jqbreadcrumb     {                 {             if (_jqbreadcrumb == null)             {                 //stringbuilder sb = new stringbuilder();                 //control c = this;                 control c = this.namingcontainer;                 //int step = 1;                 while (c != null && c.clientid != "__page")                 {                     if (c jqcontrol) // || step > 1)                     {                         _jqbreadcrumb = c.clientid;                         break;                         //sb.insert(0, " ");                         //sb.insert(0, "#" + c.clientid);                     }                     c = c.namingcontainer;                     //step++;                 }                 //_jqbreadcrumb = sb.tostring();             }             return _jqbreadcrumb;         }     }      //regular expression tokens     private static readonly regex tokenregex = new regex(         @"##(?<tokenname>[\w\:]+)"         );        //actually replaces tokens     private string tokenreplacer(match m, bool usecontext)     {         //token found         string tokenname = m.groups["tokenname"].value;         string ctlname = null;         //check if have resource token         if (resourcehelper.checkstringfortoken(tokenname))         {             return "\"" + resourcehelper.getstringbytoken(tokenname, resourcetype.portal) + "\"";         }         switch (tokenname)         {             case "this":                 //special case: seek current control                 if (usecontext) return "$(__$)";                 ctlname = "#" + this.clientid; // jqbreadcrumb;                 break;             case "parent":                 //special case: seek direct parent control                 ctlname = "#" + jqbreadcrumb;                 // this.namingcontainer.clientid;   //note: use parent breadcrumb here                 break;             default:                 //seek child control given name                 if (!usecontext)                 {                     control ctl = getchildbyname(tokenname);                     if (ctl != null) ctlname = "#" + ctl.clientid;                 }                 //else ctlname = "[id^='" + this.clientid + "_']" + "[id$='_" + tokenname + "']:first";                 break;         }         if(ctlname != null) return "$(\"" + ctlname + "\")";         if (!usecontext) return "$(this)._cc('" + tokenname + "', '" + this.clientid + "')";         return "$(__$)._cc('" + tokenname + "')";     }      private string tokenreplacerwithcontext(match m)     {         return tokenreplacer(m, true);     }      private string tokenreplacerwithoutcontext(match m)     {         return tokenreplacer(m, false);     }      protected virtual control getchildbyname(string name)     {         return this.controls.cast<control>().singleordefault(c => c.id == name);     }      //regular expression insert context holder     private static readonly regex contextregex = new regex(         @"^(\s*function\(\s*\)\s*{)", regexoptions.multiline         );      private static int replacednum;     private static string contextreplacer(match m)     {         replacednum++;         return "function() { var __$ = this; \r\n";     }      /// <summary>     /// substitue occurences of tokens of type ##[token] corresponding jquery calls     /// </summary>     /// <param name="callbackmethod">callback method definition contains tokens</param>     /// <param name="usecontext">true if local context used on client</param>     protected void preparecallbackmethod(jqraw callbackmethod, bool usecontext)     {         if(usecontext)         {             replacednum = 0;             callbackmethod.jqrawcontent = contextregex.replace(callbackmethod.jqrawcontent, contextreplacer);             if(replacednum == 0) usecontext = false;         }         if (callbackmethod != null)         {             matchevaluator me;             if(usecontext) me = tokenreplacerwithcontext;             else me = tokenreplacerwithoutcontext;              //find tokens in callback body , replace them             callbackmethod.jqrawcontent = tokenregex.replace(callbackmethod.jqrawcontent, me);         }     }      protected void preparecallbackmethod(jqraw callbackmethod)     {         preparecallbackmethod(callbackmethod, false);     }      protected virtual void preparecallbackmethods(object @params)     {         foreach (propertyinfo pi in @params.gettype().getproperties().where(                 p => p.propertytype.equals(typeof(jqraw))             ))         {             if (pi.getcustomattributes(typeof(callbackmethodattribute), false).length > 0)             {                 //property has attribute: prepare                 jqraw pty = (jqraw)pi.getvalue(@params, null);                 if (pty != null && pty.jqrawcontent != null)                 {                     preparecallbackmethod(pty);                 }             }         }     }      /// <summary>     /// returns script files control     /// </summary>     /// <returns>collection contains ecmascript (javascript) files have been registered embedded resources</returns>     protected override ienumerable<scriptreference> getscriptreferences()     {         return scriptrefs;     }      private const string selfalias = "__$";     protected virtual string getdescriptorselector()     {         //return this.clientid;         return selfalias;     }      protected virtual ienumerable<scriptdescriptor> _getscriptdescriptors()     {         yield break;     }      //private const string afterinittemplate = "function() {{ var _method = {0}; _method(); $('#{1}').trigger('_loadcomplete'); }}";      protected sealed override ienumerable<scriptdescriptor> getscriptdescriptors()     {         var result = new list<scriptdescriptor>();          //yield return new jqselfdescriptor(this.clientid, selfalias);         result.add(new jqselfdescriptor(this.clientid, selfalias));           if (preinit != null)         {             //to executed before initialization             preparecallbackmethod(preinit, true);             //yield return new jqdescriptor(getdescriptorselector(), "each", true, preinit);             result.add(new jqdescriptor(getdescriptorselector(), "each", true, preinit));         }          if(initdata != null)         {             foreach (string key in initdata.keys)             {                 //initialize given object data                 object data;                 bool usestd = false;                 if (initdata[key] nativecontainer)                 {                     data = ((nativecontainer)initdata[key]).content;                     usestd = true;                 }                 else data = initdata[key];                 jqdescriptor jdesc = new jqdescriptor(getdescriptorselector(), "data", true, key, data);                 if(usestd) jdesc.usestandardserializer = true;                     //yield return jdesc;                     result.add(jdesc);             }         }          if (authorizationtemplates != null)         {             //register authorization templates             //yield return new jqdescriptor(getdescriptorselector(), "pm_registerauthtemplates", true, authorizationtemplates);             result.add(new jqdescriptor(getdescriptorselector(), "pm_registerauthtemplates", true, authorizationtemplates));         }          //enumerate overriden method results         foreach(scriptdescriptor sd in _getscriptdescriptors())         {            // yield return sd;             result.add(sd);         }          if (afterinit != null)         {             //to executed after initialization             preparecallbackmethod(afterinit, true);             //afterinit.jqrawcontent = string.format(afterinittemplate, afterinit.jqrawcontent, getdescriptorselector());             //yield return new jqdescriptor(getdescriptorselector(), "each", true, afterinit);             result.add(new jqdescriptor(getdescriptorselector(), "each", true, afterinit));         }          if (themepath != null && themecssname != null)         {             //load css file dynamically             string cssurl = virtualurlhelper.combine(themepath, themecssname);             dynamicstylesheetdescriptor dsdesc = new dynamicstylesheetdescriptor(cssurl);             //yield return dsdesc;             result.add(dsdesc);         }          if (cssrefs.count > 0)         {             dynamicstylesheetdescriptor dsdesc = new dynamicstylesheetdescriptor(cssrefs);             //yield return dsdesc;             result.add(dsdesc);         }          //final trigger         //yield return new jqdescriptor(getdescriptorselector(), "trigger", "_loadcomplete");          //yield break;         return result;     }      /// <summary>     /// helper method create url embedded resource     /// </summary>     /// <param name="type">the type of server-side resource</param>     /// <param name="resourcename">the name of server-side resource</param>     /// <returns>the url reference resource</returns>     protected string getembeddedurl(type type, string resourcename)     {         //get base url         string url = page.clientscript.getwebresourceurl(type, resourcename);         //attach name of resource         return url.replace("?", "?name=" + resourcename + "&");     } } 

i place on page ascx control: page: `<%@ page language="c#" autoeventwireup="true" codebehind="p2.aspx.cs" inherits="lwm.implementation.portal.sample.testoutputcache.p2" %>

<%@ register tagprefix="lwm" src="~/sample/testoutputcache/testcontrol2.ascx" tagname="testcontrol2"%>

<lwm:testcontrol2 id="testcached" runat="server" />   </div> </form> 

`

ascx: `<%@ control language="c#" autoeventwireup="true" codebehind="testcontrol2.ascx.cs" inherits="lwm.implementation.portal.sample.testcontrol2" %> <%@ outputcache duration="600" varybyparam="none" %> <%@ register tagprefix="controls" assembly="lwm.implementation.controls" namespace="lwm.implementation.controls.jqcomposite" %> test 2 function (evt) {

        console.log("afterinit 2");     } </afterinit> 

`

also enable ascx control cache. when page first loaded ok, when page getted server cache script references missing...

i search lot , can't find idea. so, problem scriptmanager not generate script reference when control loaded server cache.

this bug outputcaching , script manager, officially recognized microsoft

there workaround add scripts scriptmanager manually:

 <asp:scriptmanager id="scriptmanager1" runat="server">         <scripts>             <asp:scriptreference name="ajaxcontroltoolkit.common.common.js" assembly="ajaxcontroltoolkit" />             <asp:scriptreference name="ajaxcontroltoolkit.extenderbase.basescripts.js" assembly="ajaxcontroltoolkit" />             <asp:scriptreference name="ajaxcontroltoolkit.textboxwatermark.textboxwatermark.js"                 assembly="ajaxcontroltoolkit" />         </scripts>     </asp:scriptmanager> 

Comments

Popular posts from this blog

ASP.NET/SQL find the element ID and update database -

jquery - appear modal windows bottom -

c++ - Compiling static TagLib 1.6.3 libraries for Windows -