Обновление веб-частей
Дата последнего изменения: 1 сентября 2011 г.
Применимо к: SharePoint Foundation 2010
В этом разделе описывается оптимальный способ обновления веб-частей. При его применении учитывается, какая это веб-часть (веб-часть SharePoint Foundation, гибридная веб-часть или веб-часть ASP.NET), преобразуется ли она в другой тип, какой вид обновления производится и при каких условиях код обновления будет выполняться. Если создается новая версия веб-части и необходимо применить логику обновления к значениям свойств, сохраненным для предыдущих версий веб-части, можно использовать следующие возможности Microsoft SharePoint Foundation 2010.
Реализация метода AfterDeserialize
Если все прежние версии — это веб-части Microsoft SharePoint Foundation, а новая версия — веб-часть SharePoint Foundation 2010 или гибридная веб-часть, для обновления веб-части требуется реализация метода AfterDeserialize(). Этот метод будет всегда вызываться при десериализации старой версии в новую, независимо от того, является ли веб-часть статической на странице (т. е. находится вне зоны), динамической (внутри зоны), или ее экземпляры создаются в результате вызова объектной модели. Однако AfterDeserialize() будет вызываться только один раз при обновлении прежней десериализованной версии до новой версии; после обновления веб-части до гибридной версии AfterDeserialize() вызываться не будет. Поэтому если веб-часть SharePoint Foundation преобразована в гибридную веб-часть и развернута как гибридная, после чего в нее добавлена логика обновления, необходимо реализовать метод AfterDeserialize() для обработки обновления веб-части SharePoint Foundation до гибридной веб-части версии 2.0. Необходимо также реализовать описанные ниже интерфейсы для обновления гибридной веб-части версии 1.0 до гибридной веб-части 2.0. С этой целью рекомендуется создать общую функцию обновления (в данном примере TransformMyString), которая будет вызываться и методом AfterDeserialize(), и реализациями упомянутых интерфейсов.
Если прежняя версия веб-части — гибридная веб-часть или веб-часть ASP.NET, а новая версия — гибридная веб-часть или веб-часть ASP.NET, метод AfterDeserialize() вызываться не будет, и логику обновления веб-части следует вызывать из метода OnInit(), EndLoad() или Load(), в зависимости от того, что именно требуется сделать при обновлении.
Дополнительные сведения об использовании метода AfterDeserialize() см. в разделах Upgrading a Web Part Assembly for Microsoft SharePoint Products and Technologies (Обновление сборки веб-части для продуктов и технологий Microsoft SharePoint) (Возможно, на английском языке) и AfterDeserialize().
Определение статуса свойства
Предположим, что имеется строковое свойство SampleProperty и его формат изменился, так что программа обновления должна преобразовать содержимое свойства SampleProperty из прежнего формата в новый. Рекомендуется создать метод TransformSampleProperty, который будет определять, преобразовано ли свойство SampleProperty, и если нет, выполнять преобразование. Ниже приводится пример такой программы:
using Asp = System.Web.UI.WebControls.WebParts
public class MyWebPart : Asp.WebPart
{
private m_dirty = false;
[Insert your standard Web Part logic here…]
private void TransformMyString()
{
if ([SampleProperty is in the old format…])
{
[Transform the SampleProperty value to the new format…]
m_dirty = true;
}
if (m_dirty && null != WebPartManager)
{
SetPersonalizationDirty();
m_dirty = false;
}
}
}
Вызов метода TransformSampleProperty из методов OnInit() и EndLoad() обеспечит обращение к коду обновления для статических и динамических веб-частей и экземпляров, создаваемых путем вызова объектной модели. Возможно, потребуется дополнить веб-часть каким-либо свойством наподобие Upgraded или Version, чтобы метод TransformSampleProperty смог установить это свойство после обновления и чтобы последующие вызовы TransformSampleProperty позволяли определять, преобразована ли уже веб-часть MyString. Для хранения свойства Version целесообразно использовать интерфейс IPersonalizable, потому что это свойство останется в хранилище вместе с остальными свойствами веб-части. Однако оно не будет отображаться в пользовательском интерфейсе области инструментов в процессе изменения свойств веб-части и не будет присутствовать среди элементов разметки веб-части при ее редактировании в Microsoft SharePoint Designer.
В предыдущем примере сразу после десериализации веб-части вызывается метод EndLoad(), и поскольку свойство SampleProperty осталось в прежнем формате, запускается код преобразования значения SampleProperty. Так как веб-часть еще не добавлена в WebPartManager, свойство MyWebPart.WebPartManager сохраняет значение null и метод SetPersonalizationDirty не вызывается. После добавления веб-части в WebPartManager на странице ее жизненный цикл становится текущим, и вызывается метод MyWebPart.OnInit. Однако затем утверждение о сохранении прежнего формата MyString становится ложным, и свойство MyWebPart.WebPartManager получает действительное значение. Поэтому вызывается метод SetPersonalizationDirty, запускающий автоматическое сохранение обновленной веб-части в базе данных контента, независимо от уровня прав текущего пользователя.
Если веб-часть является статической на странице, изменение разметки страницы после выполнения кода обновления веб-части не поддерживается, т. е. элементы разметки всегда будут оставаться в том же виде, какой они имели до обновления, и код обновления будет повторно выполняться в рамках метода OnInit() при каждом просмотре страницы. Особый случай представляют попытки веб-части выполнить запись свойств в базу данных контента, доступную в SQL Server только для чтения. Такое может произойти, поскольку обновление веб-части фактически откладывается до первого использования экземпляра, а первое использование может иметь место, когда база данных доступна только для чтения. Веб-часть должна быть изображена, но затем аккуратно заблокирована для сохранения изменений в базе данных.
Изменение имен свойств
Предположим, что в прежней версии имеется свойство X, которое переименовано в Y в новой версии. В таком случае следует реализовать метод Load(), скопировать в Y значение, хранившееся в X, и установить флаг изменения. Затем этот флаг проверяется в методе OnInit(), и вызывается метод SetPersonalizationDirty. Ниже приводится пример такой программы:
using Asp = System.Web.UI.WebControls.WebParts
public class MyWebPart : Asp.WebPart
{
private m_dirty = false;
[Standard Web Part logic here...]
void IVersioningPersonalizable.Load(IDictionary unknownProperties)
{
[Copy X into Y here…]
m_dirty = true;
}
protected override void OnInit(EventArgs e)
{
if (m_dirty && null != WebPartManager)
{
SetPersonalizationDirty();
m_dirty = false;
}
}
}
В этом примере метод Load() вызывается, если веб-часть динамическая или ее экземпляры создаются путем вызова объектной модели, и не вызывается, если веб-часть — статическая на странице.
Инфраструктура веб-частей вызывает методы интерфейса IVersioningPersonalizable независимо от учетных данных пользователя, и если в коде IVersioningPersonalizable веб-часть была помечена как измененная в предыдущем примере, автоматически инициируется сохранение обновленной веб-части в базе данных с использованием внутреннего кода, не проверяющего учетные данные. Поэтому даже если первым страницу просмотрит пользователь с ограниченными правами (например, читатель), обновление все равно произойдет по ожидаемой схеме.
В случае статической веб-части метод Load() не вызывается. Однако в вызываемый метод OnInit() можно добавить код, который проверит свойства expando веб-части (это понятие связано с элементами управления ASP.NET, а не с инфраструктурой веб-частей), скопирует значение X из свойств expando и присвоит его свойству Y. Кроме того, в данном случае изменение разметки страницы после выполнения кода обновления веб-части не поддерживается, т. е. элементы разметки всегда будут оставаться в том же виде, какой они имели до обновления, и код обновления будет повторно выполняться в рамках метода OnInit() при каждом просмотре страницы.
См. также
Концепции
Веб-части в SharePoint Foundation