Ссылки на скрипты не загружаются в частичном PostBack, если указано "new ScriptReference(resourceName,assemblyName)"

Я создал элемент управления ASP.NET AJAX, который реализует IScriptControl в соответствии с разделом Добавление возможностей клиента в элемент управления веб-сервера. Этот элемент управления работает как ожидалось - когда ресурс скрипта загружен; Тем не менее, проблема заключается в том, что ресурс скрипта загружается не всегда.

Элемент управления загружает все соответствующие ссылочные ресурсы при загрузке из Full PostBack. Это не очень удивительно. Контроль работает. Следует соответствующему IScriptControl правила, регистрирует элемент управления Script и отображает соответствующие дескрипторы сценариев. И то и другое GetScriptReferences а также GetScriptDescriptions реализованы.

Теперь, когда GetScriptReferences записывается как..

public IEnumerable<ScriptReference> GetScriptReferences()
{
  return new List<ScriptReference> {
    new ScriptReference("Resource.js", GetType().Assembly.FullName)
  }
}

..то ресурс не загружается ScriptManager в обновлении Partial PostBack!

Таким образом, если элемент управления можно использовать только в том случае, если он сначала загружен в полный PostBack, поэтому соответствующие ссылки на сценарии уже загружены. В тех случаях, когда это работает (например, в Full PostBack), выборка ресурса может рассматриваться как http://dev/ScriptResource.axd?d=..,

Тем не менее, когда ресурс загружается через..

public IEnumerable<ScriptReference> GetScriptReferences()
{
  return new List<ScriptReference> {
    new ScriptReference(Page.ClientScript.GetWebResourceUrl(GetType(), "Resource.js"))
  };
}

.. затем ресурс загружается, даже в частичном PostBack. Запрос можно увидеть в журнале сети браузера как http://dev/WebResource.axd?d=.., Я хотел бы избежать этой второй формы, так как тогда я должен вручную прикрепить Sys.Application.notifyScriptLoaded код вручную.

ASP.NET 3.5 ScriptManager создается на пользовательской главной странице SharePoint 2010 (так что он заменяет элемент управления ScriptManager по умолчанию) со следующей конфигурацией:

<aspExt:ScriptManager runat="server" ID="MyScriptManager"
    EnablePartialRendering="True" EnablePageMethods="True" EnableViewState="True"
    EnableHistory="True" EnableSecureHistoryState="False"
    EnableScriptLocalization="False" EnableScriptGlobalization="False"
    LoadScriptsBeforeUI="True">
</aspExt:ScriptManager>

Принудительная загрузка скриптов вручную ScriptManager.RegisterClientScriptResource (который загружает из http://dev/ScriptResource.axd?d=..) "работает", но при этом элемент управления должен нарушать модель IScriptControl и не возвращать никаких ссылок из GetScriptReferences, чтобы можно было обеспечить согласованное поведение как в ситуации Full, так и в режиме частичного PostBack. В противном случае один и тот же ресурс будет загружен несколько раз, когда ресурс сценария действительно загружен правильно в ситуации Full PostBack.

1 ответ

Решение

Это похоже на проблему с SharePoint 2010, и я наконец-то смог выкопать некоторую информацию в этом посте.

Это известная проблема в Sharepoint 2010. Ресурсы сценария не загружаются, если элементы управления изначально не видны.

.. Проблема "Sharepoint 2010 не генерирует ссылки javascript при частичной обратной передаче".. возникает, если элементы управления добавлены (или сделаны видимыми) во время частичной обратной передачи.

К счастью,

Microsoft наконец-то решила эту проблему и в одном из накопительных обновлений Sharepoint 2010 за октябрь 2011 года. Установка этого обновления обычно должна устранять проблемы со скрытыми элементами управления ajax, регистрирующими свои сценарии.

Похоже, накопительный пакет обновления SharePoint Server 2010 (серверный пакет SharePoint): 25 октября 2011 года - первый CU с исправлением, хотя я не проверял это.


Для исторического справочника - или для бедных людей, таких как я, которые не могут гарантировать, что CU/SP применялось - "работа" заключается в ручной регистрации ресурсов. (Это также было найдено в связанном посте.)

public class MyComboBox : RadComboBox
{
    protected override System.Collections.Generic.IEnumerable<System.Web.UI.ScriptReference> GetScriptReferences()
    {
#if MANUAL_SCRIPT_POSTBACK_FIX
        HashSet<string> registeredNames = new HashSet<string>();
        ReadOnlyCollection<RegisteredScript> registeredScripts = ScriptManager.GetCurrent(Page).GetRegisteredClientScriptBlocks();           
        foreach (RegisteredScript registeredScript in registeredScripts)
        {
            registeredNames.Add(registeredScript.Key);
        }

        foreach (ScriptReference reference in base.GetScriptReferences())
        {
            if (!registeredNames.Contains(reference.Name))
            {
                ScriptManager.RegisterClientScriptResource(this, typeof(MyComboBox).BaseType, reference.Name);
            }
        }
        return new List<ScriptReference>();
#else
        return base.GetScriptReferences();
#endif     
    }
}
Другие вопросы по тегам