reSP — great Resharper plugin from SubPoint Solutions.
Makes Your SharePoint solutions code more stable and robust:
http://subpointsolutions.com/resp/
reSP — great Resharper plugin from SubPoint Solutions.
Makes Your SharePoint solutions code more stable and robust:
http://subpointsolutions.com/resp/
я обновил Sharepoint EventHandlerExplorer 2013/2016, утилиту которая позволяет управлять обработчиками событий без использования SharePoint-фич. Позволяет привязывать ресиверы к вебам, спискам/библиотекам SharePoint, а также к контент-тайпам:
Описание:
Фичи позволяют привязывать обработчики только к известным типам контента(хрестоматийный пример – список “Announcements”):
<Receivers ListTemplateId="104">
Но такое декларативное развёртывание действует на весь scope и не позволяет к примеру привязать два обработчика к разным Announcement-спискам. Также не позволяет регистрировать обработчик для списка с неизвестным Id.
Изначально первая версия EventHandlerExplorer была создана Patrick Tisseghem и работала с третьей версией WSS. В Windows 2012(в .NET 4) появился новый глобальный кеш сборок, и исчезла возможность “перетягивать” мышью DLL-ки в GAC. Вместо drag-n-drop теперь рекомендуется использовать powershell:
[System.Reflection.Assembly]::Load('System.EnterpriseServices, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b03f5f7f11d50a3a'); $publish = New-Object System.EnterpriseServices.Internal.Publish; $publish.GacInstall('$fullpath');
я добавил обёртку для развёртывания через powershell и поддержку 2013 и 2016 версий SharePoint on-premise
Есть вебчасть, содержащая внутри себя меню PeopleEditor. Столкнулся с тем что для анонимных пользователей она недоступна:
Спасибо Karel Hájek, который раскопал рефлектором что дело в дополнительной проверке, которая происходит на этапе рендеринга. Для отображения не хватает пермишна “BrowseUserInfo”, который по умолчанию выключен для анонимных юзеров, а веб-интерфейс не позволяет его выдать.
Karel предлагает подредактировать базу данных контента и разрешить анонимные запросы в Active Directory.
Намного проще это сделать через Powershell-скрипт, тем более что редактирование базы контента напрямую это очень bad-practice 🙂
Подключаем консоль, получим текущие разрешения и добавим к ним SPBasePermissions.BrowseUserInfo:
$sharePointSnapin = Get-PSSnapin | Where-Object { $_.Name -eq "Microsoft.SharePoint.PowerShell"} if($sharePointSnapin -eq $null) { Add-PSSnapin Microsoft.SharePoint.PowerShell } $web = Get-SPWeb http://portal/web/ $web.AnonymousPermMask64; # output: ViewListItems, ViewVersions, ViewFormPages, Open, ViewPages, UseClientIntegration $web.AnonymousPermMask64 = "$rights, BrowseUserInfo"; $web.Update();
Теперь PeoplePicker рендерится для всех пользователей(для того чтобы он ещё и работал надо включить запросы в AD):
Есть система багтреккинга, сделанная на Sharepoint с использованием Infopath-форм.
Формы имеют несколько копий и в зависимости от принадлежности сотрудника в AD, ему подставляется своя копия и люди из разных отделов могут редактировать только свои поля:
Задача:
После экспорта узла из вида пропало поле «Статуса». То есть на форме оно есть, а в колонках видов и настройках списка уже нет.
Решение:
— Переопубликовать форму в Infopath Designer(колонка должна появиться, но без значений).
— Обновить все элементы списка, чтобы значения появились в видах SharePoint.
Программно это можно сделать например так
using (SPSite site = new SPSite("http://server/webName ")) using (SPWeb web = site.OpenWeb()) { SPList list = web.GetList("http://server/webname/libName/"); foreach (SPListItem item in list.Items) { try { Console.Write("Updating " + item.ID.ToString()); item.SystemUpdate(); Console.WriteLine(".. Ok."); } catch (Exception ex) { Console.WriteLine(ex.ToString()); } } }
или через Powershell:
$web = Get-SPWeb -identity "http://server/webName" $list = $web.Lists["listName"] $list.Items | ForEach-Object { Write-Host "Updating " $_.Name; $_.SystemUpdate(); } $web.Dispose()
p.s.: при этом пользовательские виды с участием этих “пропавших и возвращённых” полей возможно прийдётся пересоздать
В интернетах есть несколько вариантов как к примеру обновить элемент без старта привязанных к нему событий, но они либо не очень работают, либо работают в определённых контекстах. Вот ниже способ, который работает при обращении к элементам даже из консольного приложения.
Это extension-класс для SPListItem. Основа это пост на stackoverflow , я лишь добавил от себя ещё пару функций для работы с файлами — добавление файла и функцию CopyTo, для «тихого» копирования файла.
using Microsoft.SharePoint; public static class SPListItemExtensions { /// <summary> /// Provides ability to update list item without firing event receiver. /// </summary> /// <param name="item">list item</param> /// <param name="doNotFireEvents">Disables firing event receiver while updating item.</param> public static void Update(this SPListItem item, bool doNotFireEvents) { SPItemEventReceiverHandling rh = new SPItemEventReceiverHandling(); if (doNotFireEvents) { try { rh.DisableEventFiring(); item.Update(); } finally { rh.EnableEventFiring(); } } else { item.Update(); } } /// <summary> /// Provides ability to update list item without firing event receiver. /// </summary> public static void SystemUpdate(this SPListItem item, bool incrementListItemVersion, bool doNotFireEvents) { SPItemEventReceiverHandling rh = new SPItemEventReceiverHandling(); if (doNotFireEvents) { try { rh.DisableEventFiring(); item.SystemUpdate(incrementListItemVersion); } finally { rh.EnableEventFiring(); } } else { item.SystemUpdate(incrementListItemVersion); } } /// <summary> /// Provides ability to copy file from list item without firing event receiver. /// </summary> public static void CopyTo(this SPFile file, string strNewUrl, bool bOverWrite, bool doNotFireEvents) { SPItemEventReceiverHandling rh = new SPItemEventReceiverHandling(); if (doNotFireEvents) { try { rh.DisableEventFiring(); file.CopyTo(strNewUrl, bOverWrite); } finally { rh.EnableEventFiring(); } } else { file.CopyTo(strNewUrl, bOverWrite); } } /// <summary> /// Provides ability to update list item without firing event receiver. /// </summary> public static void SystemUpdate(this SPListItem item, bool doNotFireEvents) { SPItemEventReceiverHandling rh = new SPItemEventReceiverHandling(); if (doNotFireEvents) { try { rh.DisableEventFiring(); item.SystemUpdate(); } finally { rh.EnableEventFiring(); } } else { item.SystemUpdate(); } } /// <summary> /// Provides ability to add file to sharepoint library without firing event receiver. /// </summary> public static SPFile AddFile(SPFileCollection spFileCollection, string destPathToFile, byte[] binFileData, bool overwrite, bool doNotFireEvents) { SPItemEventReceiverHandling rh = new SPItemEventReceiverHandling(); if (doNotFireEvents) { try { rh.DisableEventFiring(); SPFile addedFile = spFileCollection.Add(destPathToFile, binFileData, overwrite); return addedFile; } finally { rh.EnableEventFiring(); } } else { SPFile addedFile = spFileCollection.Add(destPathToFile, binFileData, overwrite); return addedFile; } } private class SPItemEventReceiverHandling : SPItemEventReceiver { public SPItemEventReceiverHandling() { } new public void DisableEventFiring() { #pragma warning disable 612,618 base.DisableEventFiring(); #pragma warning restore 612,618 } new public void EnableEventFiring() { #pragma warning disable 612,618 base.EnableEventFiring(); #pragma warning restore 612,618 } } }