Linq to SharePoint. Блокировка документов
Иногда при работе с документами необходимо на некоторое время запретить другим пользователями его изменение. В Microsoft SharePoint 2010 для реализации данного требования есть две возможности: извлечение файла и блокировка файла. В этом посте я расскажу об отличиях этих двух операций и покажу пример реализации блокировки документов с использованием репозитория.
Извлечение файлов
Первый способ, извлечение файлов, доступен из интерфейса пользователя. Это стандартная реализация системы управления версиями. Есть один недостаток: пользователи с достаточными на то привилегиями могут отменить извлечение документа или вернуть его. SharePoint в таком случае просто выдаст предупреждение о том, что файл был извлечен другим пользователем:
Такое поведение SharePoint'а оправдано, тем, что пользователь, извлекший документ может, например, уйти в отпуск. И тогда администратор может отменить извлечение документа, предоставив тем самым возможность работать с документов другим пользователям. Такой подход не подходит для обеспечения монопольного доступа к файлу.
Блокировка документов
Второй способ более радикален и позволяет обеспечить монопольный доступ к файлу. Но здесь есть несколько особенностей:
- Заблокировать файл, используя интерфейс пользователя нельзя;
- Блокировать файл можно только на определенное время. Это связано с тем, что блокировку может отменить только пользователь, наложивший её;
- При попытке редактировать свойства заблокированного файл, возникает исключение, которое не обрабатывается SharePoint'ом в дружелюбном виде.
Исключение это выглядит следующим образом:
<nativehr>0x80071779</nativehr><nativestack></nativestack>
Файл "http://[SPServer]/DocumentLibrary/Report.xlsx" заблокирован для монопольного использования пользователем SHAREPOINT\system.
Или так (по-английски):
<nativehr>0x80071779</nativehr><nativestack></nativestack>
The file "http://[SPServer]/DocumentLibrary/Report.xlsx" is locked for exclusive use by SHAREPOINT\system.
При открытии файла в клиентском приложении SharePoint выдаст вот такое сообщение:
Блокировка файла программными средствами
Так как блокировать документы в SharePoint'е можно только программно, я покажу как это сделать на примере репозитория, описанного в посте Linq to SharePoint. Паттерн Repository
Блокировка в объектной модели SharePoint
В объектной модели SharePoint блокировка реализована в классе SPFile и представлена следующими методами:
- Lock(SPLockType lockType, string lockId, TimeSpan timeout) - блокирование файла на заданный период времени;
- ** RefreshLock(string lockId, TimeSpan timeout)** - продление блокировки файла на заданный период времени;
- ReleaseLock(string lockId) - снятие блокировки с файла;
Информация о блокировке файла содержится в следующих свойствах объекта SPFile:
- LockedByUser - пользователь, заблокировавший файл;
- LockedDate - дата блокировки файла;
- LockExpires - время, на которое заблокирован файл;
- LockId - Id блокировки;
- LockType - тип блокировки.;
Тип блокировки может принимать следующие значения:
- Exclusive - доступ к файлу имеет только пользователь, наложивший на него блокировку;
- Shared - доступ к файлу имеет группа пользователей;
- None - файл не заблокирован;
Получение файла
Прежде чем блокировать файл, необходимо его получить. Для этого в репозиторий я добавил следующий метод:
Этот метод использует мета-данные списка, способ получение которых я описал в посте Linq to SharePoint. Получение мета-данных списка. В SharePoint'е и для элемента списка можно получить файл, но заблокировать его не удастся, т.к. он не является файлом, подлежащим хранению в системе управления версиями.
Блокировка файла
Файл есть, теперь можно и блокировку реализовать:
В объектной модели SharePoint при блокировки файла или её продления требуется указать Id этой блокировки. В реализации этих методов в репозитории я "опустил" это требование.
Информация о блокировке
Для получения информации о блокировке файла я сделал простой класс:
И метод в репозитории для получения его экземпляра:
Применение
Использовать новый функционал можно примерно так: