понедельник, 1 сентября 2014 г.

Выступаю на Russian SQL Server User Group в Москве 10 сентября

Я всегда много писал о SharePoint, но это далеко не единственная область, в которой я разбираюсь.

Сергей Олонцев, MVP по SQL Server, организует встречи SQL Server User Group в Москве. Ближайшая встреча будет 10 сентября и я буду выступать на ней с докладом: Оптимизация высоконагруженных ASP.NET приложений, работающих с MS SQL Server, с помощью LINQ.

Краткое описание доклада:
Вы разрабатываете веб-приложения и используете хранимые процедуры? Вы пишите SELECT … WITH(NOLOCK)? Вы считаете, что ORMы снижают быстродействие приложений? Тогда этот доклад для вас!
В докладе будут развенчаны популярные мифы о применении библиотек Object-Relational Mapping (ORM) в ASP.NET при работе с Microsoft SQL Server. Также будут рассмотрены конкретные методики увеличения быстродействия работы с данными в веб-приложениях.
Встреча пройдет в Microsoft Technology Center, м. Белорусская, ул. Лесная д. 9 10 сентября с 17:00 до 19:00.

Ссылка на регистрацию: http://www.eventbrite.com/e/russian-sql-server-user-group-10-2014-tickets-12806290961

 

среда, 30 июля 2014 г.

Семинар "Поиск в SharePoint 2013"

Поиск в SharePoint существует очень давно. Даже когда SharePoint не назывался SharePoint_ом в нем существовал поиск. В SharePoint 2013 поиск стал не просто небольшим дополнением к платформе, а инструментом для решения многих задач, как для разработчиков, так и для дизайнеров, и для продвинутых пользователей. Многие части SharePoint основаны на механизме поиска, но для создания решений поиск до сих пор приvеняется очень редко.

Поиск помогает реализовать многие сценарии ECM, сбор данных из разных источников, публикацию контента на порталах с высокой скоростью и многие веб-части, например, информер дней рождения и трудовых юбилеев сотрудников. Поиск SharePoint интегрирован с профилями пользователей и таксономией, может быть использован как в приложениях, так и в решениях.

К сожалению, многие аспекты поиска плохо документированы, что создает проблемы при создании решений и используется от силы 30% всех возможностей.

21 августа пройдет семинар по Поиску в SharePoint 2013. Он будет интересен как разработчикам решений, так и продвинутым пользователям, и администраторам.

Участвуйте в семинаре, и Вы узнаете много нового:

  • Как использовать существующие возможности поиска SharePoint для решения задач.
  • Приемы построения запросов и настройки ранжирования результатов поиска.
  • Возможности настройки схемы для полнотекстового и атрибутивного поиска, а также уточнений.
  • Архитектуру службы поиска SharePoint, возможности масштабирования и отказоустойчивости.
  • Клиентское и серверное API для поиска.

В отличие от предыдущих семинаров, где сначала рассматривались базовые вещи, а потом переходили к реальным примерам, в этот раз начнем с решения практических задач, а потом будем изучать механизмы, которые позволяют это сделать.

Темы, которые будут рассмотрены на семинаре:

  • Сценарии выборки данных (замена CAML)
  • Ранжирование (как настроить собственное и как управлять)
  • Доступность и быстродействие (чтобы поиск не падал и индекс быстро наполнялся)
  • Масштабирование поиска (как положить на несколько серверов в зависимости от объема данных и выделить нужное место на хранилище)
  • Работа с правами доступа (что отобразится в веб-частях в зависимости от прав)
  • Особенности работы через разные зоны (AAM)
  • Обзор стандартных веб-частей и способов их кастомизации (в том числе и локализация)
  • Интересные сценарии использования (выборки в том месте, где высокие нагрузки и пр.)
  • Обзор объектной модели (со стороны клиента, со стороны сервера)

Материала не просто много, а очень много. Семинар будет проходить с 10 утра до 6 вечера, надеюсь удастся уложиться.

Стоимость - 8,500 рублей с участника, обед и кофе-брейки включены. Зарегистрироваться на событие «Семинар

вторник, 29 июля 2014 г.

Загрузка скриптов в SharePoint

В прошедшем недавно семинаре про клиентской разработке в SharePoint (записи – по ссылке) я показывал как сделать клиентский скрипт, который выполняет некоторый код после окончания загрузки страницы в SharePoint.

Эта, казалось бы, простая задача далеко не тривиально реализуется в SharePoint.

Причины

    1. SharePoint формирует интерфейс динамически. Многие блоки добавляются на страницу по событию body.onload. Это событие возникает позже, чем DOMContentLoaded. Именно это событие перехватывает jQuery.ready. Поэтому использование jQuery часто не приводит к хорошему результату. Подробнее об использовании jQuery в SharePoint.
    2. Minimal Download Strategy (MDS), появившийся в SharePoint 2013, загружает страницу один раз, потом обновляет блоки страницы, поэтому нужно выполнять дополнительные действия, чтобы скрипт выполнился после загрузки страницы под MDS.
    3. Механизм загрузки скриптов, о котором я писал ранее, требует чтобы скрипт самостоятельно оповещал об окончании выполнения.

Для скриптов в виртуальной файловой системе SharePoint

Чаще всего скрипты SharePoint деплоятся как файлы в виртуальной файловой системе. Это прекрасно работает как в on premises, так и в online.

Для размещения скриптов на странице используется контрол ScriptLink, в таком виде:

<SharePoint:ScriptLink Name="autofill.js" runat="server" OnDemand="true" LoadAfterUI="true" Localizable="false" />

или с помощью CustomAction ScriptLink в элементе решения

<CustomAction Location="ScriptLink" ScriptSrc="~site/Extensions/typescripttemplates.js" />

Внутри скрипта нужно выполнить следующие действия:

  1. Оповестить SharePoint об окончании загрузки.
  2. Добавить функцию, которую необходимо вызывать после загрузки страницы, в массив _spBodyOnLoadFunctions.
  3. Добавить зарегистрировать скрипт в системе MDS.

Код:

// IIFE для изоляции
(function () {
    "use strict";

    // Имя скрипта должно совпадать с тем, что указано в ScriptLink
    var scriptLink = "~site/Scripts/myscript.js";

    // Код здесь будет выполняться ДО окончания загрузки страницы


    if (_spBodyOnLoadCalled) {
        // Если событие body.onload уже обработано
        // напрмиер при LoadAfterUI="true" или OnDemand="true"
        // то сразу вызываем функцию init
        init();
    } else {
        // Иначе добавляем функцию в массив
        _spBodyOnLoadFunctions.push(init);
    }

    function init() {
        // заменяем токены "~site" и "~sitecollection" на реальные URL 
        // с помощьюв SPClientRenderer.ReplaceUrlTokens
        // но эта функция доступна после загрузки CSR
        // поэтому нужно выполнить зарузку CSR и дождаться её окончания
        // если CSR уже был загружен, то функция выполнится сразу
        SP.SOD.executeFunc("clientrenderer.js", "SPClientRenderer.ReplaceUrlTokens", function() {            
            // тепрь регистрируем скрипт в MDS
            RegisterModuleInit(SPClientRenderer.ReplaceUrlTokens(scriptLink), init);
        });

        // Код здесь будет выполняться ПОСЛЕ окончания загрузки страницы
    }


    SP.SOD.notifyScriptLoadedAndExecuteWaitingJobs(scriptLink);
})();

Если вы сами деплоите страницу, на которой будет работать ваш скрипт, то можете воспользоваться библиотекой mQuery и функцией m$.ready. Эта функция делает тоже самое, что и блок if\else в коде выше.

Для скриптов в layouts

Если вы размещаете свой скрипт в _layouts, то есть несколько особенностей:

  1. При добавлении скрипта надо указывать только имя файла.
  2. SOD автоматически регистрирует в MDS вызов функции с именем $_global_имя_файла_без_js

Код для файла в _layouts

"use strict";

// эта функция должна быть в глобальном пространстве имен
function $_global_myscript() {
    // Код здесь будет выполняться ПОСЛЕ окончания загрузки страницы
}


if (_spBodyOnLoadCalled) {
    // Если событие body.onload уже обработано
    // напрмиер при LoadAfterUI="true" или OnDemand="true"
    // то сразу вызываем функцию init
    init();
} else {
    // Иначе добавляем функцию в массив
    _spBodyOnLoadFunctions.push(init);
}

// этот вызов автоматически добавит регистрацию в MDS
SP.SOD.notifyScriptLoadedAndExecuteWaitingJobs("myscript.js");

Универсальные скрипты

Если ваши скрипты будут вызываться вне страниц SharePoint, то обращение к “пространству имен” SP вызовет ошибку.  Кроме того есть свой механизм оповещения о загрузке скриптов в MsAjax библиотеке, поэтому в конце скрипта надо использовать такой блок:

// Оповестить MsAjax об окончании загрузки
if (typeof Sys != "undefined" && Sys && Sys.Application) {
    Sys.Application.notifyScriptLoaded();
}

// Оповестить SharePoint об окончании загрузки
if (typeof SP != "undefined" && SP && SP.SOD) {
    SP.SOD.notifyScriptLoadedAndExecuteWaitingJobs("myscript.js");
}

Заключение

Более подробно о загрузке скриптов, TypeScript, особенностях SharePoint и Client Side Rendering можете узнать подробнее, посмотрев записи семинара - http://gandjustas.justclick.ru/order/spclient/

четверг, 3 июля 2014 г.

Семинар “Создание решений SharePoint на JavaScript и TypeScript”

Microsoft постоянно развивает средства клиентской разработки в SharePoint. В предыдущей версии появилась объектная клиентская объектная модель, в текущей версии интерфейс пользователя создан с помощью JavaScript. Но многие разработчики SharePoint не используют эти возможности, создавая интерфейс "по-старинке", теряя возможность быстрой разработки, создавая некачественные решения и блокируя возможность развертывания решений в облаке.

Причины этому две - недостаток документации и использования языка JavaScript. Не секрет, что JavaScript недолюбливают многие программисты C# за динамическую типизацию и неочевидные особенности языка.

Я и сам раньше плохо относился к JavaScript и предпочитал создавать решения в серверном коде. Но недавно Microsoft выпустил типизированную версию языка JavaScript - TypeScript, который дает все преимущества компилируемого языка, сохраняя высокую скорость создания решений для SharePoint.

Теперь большую часть решений для SharePoint я создаю с использованием языка TypeScript. Для облегчения этого процесса были созданы определения типов для наиболее часто используемых клиентских библиотек SharePoint.

Я решил поделиться с вами накопленным опытом разработки с использованием TypeScript и JavaScript для SharePoint.

17 июля 2014 года пройдет семинар, посетив который вы научитесь:

  • Создавать и разворачивать приложения с клиентскими скриптами.
  • Применять популярные клиентские библиотеки jQuery и AngularJS в решениях для SharePoint.
  • Использовать клиентскую объектную модель для работы с объектами SharePoint на клиенте.
  • Кастомизировать интерфейсы для работы со списками и библиотеками SharePoint.

На семинаре будем разбирать конкретные примеры приложений и инструменты, повышающие эффективность разработчиков.

Стоимость участия - 3500 рублей при регистрации до 10 июля и 5500 рублей с 11 июля. Для тех, кто не сможет присутствовать лично - будет веб-трансляция.

Зарегистрироваться на событие «Создание решений SharePoint на JavaScript и TypeScript»

Также с 17 июля повышается стоимость видеозаписи прошлого семинара с 250 рублей до 400 рублей. Кто хочет приобрести видеозапись по старой цене – обращайтесь по ссылке http://gandjustas.justclick.ru/order/spsecurity/discount/

понедельник, 16 июня 2014 г.

Результаты мастер-класса SPSecurity

Почти месяц назад я проводит мастер-класс SPSecurity, на котором подробно рассказывал про различные аспекты безопасности и разграничения доступа в SharePoint.

В мастер-классе удалось разобрать следующие темы:

  • Как работает изоляция приложений-служб SharePoint и как это влияет на решения.
  • Механизмы разграничения доступа к данным SharePoint.
  • Распространенные ошибки, связанные с безопасностью, в клиентском и серверном коде.
  • Разграничение доступа в новом механизме приложений SharePoint 2013.

Полную видеозапись и презентации можно получить по ссылке: http://gandjustas.justclick.ru/order/spsecurity/

Фрагмент видеозаписи семинара, где я настраиваю внешний список с фильтром по текущему пользователю.

Отзывы некоторых участников:

Спасибо за семинар. Было очень интересно. Вынес для себя много полезного, в частности про то, что не надо бездумно элементам списков давать уникальные права. У нас в компании часто надо сделать так, что разные филиалы, разные начальники подразделений должны добавлять элементы в один список, и видеть при это должны только свои элементы, а супер-начальники должны видеть всех. Делали за счет проставления прав, будем делать за счет папок (филиалов).

-Илья Канашов, ГК «АВТОМИР».

 

Стас, приветствую! Спасибо за вчерашний мастер-класс! Особо полезным для себя я отметил Ваши подробные объяснения про ACL, FormDigest и получение учетных данных из Secure Store Service.

-Павел Шабанов, K2IT

 

Стас, спасибо за доклад! Он получился крутым и техническим! Мне очень понравился! На другие мероприятия, которые ты будешь организовывать буду подрывать сотрудников из нашего отдела!

-Роман Итакаев, Ай-Теко

Если хотите получить полные видеозаписи курсов, то перейдите по ссылке: http://gandjustas.justclick.ru/order/spsecurity/

пятница, 23 мая 2014 г.

Я выступаю на DevCon 2014

Немного запоздалый, но все же анонс.

28 и 29 мая я буду выступать на конференции DevCon 2014. В этот раз у меня целых два доклада. Первый (28 мая в 17:10) на тему новых возможностей BI в SharePoint 2013, где я буду рассказывать рол PowerPivot и PowerView. Второй доклад (29 мая в 10.30) про BI в облаках с применением PowerBI и Office 365.

Приходите на доклады, кто будет присутствовать на конференции или смотрите трансляцию.

вторник, 20 мая 2014 г.

10 вещей, которые надо знать при использовании jQuery в SharePoint

Для чего нужен jQuery в SharePoint? Обычно его используют для четырех целей:

  • Вызывать код JavaScript в момент загрузки страницы с помощью $(document).ready.
  • Использовать Ajax функции для доступа к данным на сервере.
  • Использовать готовые плагины,такие как tooltip или tabs, для того, чтобы расширить функционал сайта.
  • Проводить некоторые манипуляции с объектной модели документа (DOM).

Если Вы собираетесь использовать jQuery на страницах SharePoint, то вам нужно знать следующие вещи:  

 

1. Используйте mQuery и RequestExecutor в простых случаях

Если у вас простой случай, то Вы можете использовать библиотеку mQuery для манипуляции DOM и RequestExecutor для ajax запросов. Кроме того, вместо Ajax запросов гораздо выгоднее использовать JSOM и TypeScript для клиентской разработки. Об этом я писал ранее.

Если Вы, все таки, решили использовать jQuery, то вам нужно помнить следующее:

2. jQuery(document).ready срабатывает не вовремя

Это происходит потому, что $(document).ready взрывается при событии DOMContentLoaded. А это события создано для тех случаев, когда весь контент страницы загружается с сервера. Оно происходит после того как браузер скачал всю страницу, связанные файлы и всё распарсил. SharePoint использует механизмы динамического формирования страницы, когда скрипты в теле страницы запускаются и формируют части страницы. В этом случае использовать DOMContentLoaded, отрабатывает до того как сформирована страница. Гораздо более надежный способ вызова после загрузки страницы – с помощью события body.onload. Для этого в SharePoint есть готовые функции.

 

3. Используйте _spBodyOnLoadFunctions или _spBodyOnLoadFunctionNames

Эти два массива (да-да, обычные JS массивы). _spBodyOnLoadFunctionNames содержит имена глобальных функций, которые необходимо вызвать на событие body.onload. _spBodyOnLoadFunctions содержит объекты-функции, что гораздо удобнее, но доступно только в SharePoint 2013. Кроме того есть переменная _spBodyOnLoadCalled, которая равна true, если функции уже были выполнены.

Пример:

(function() {
    if (!_spBodyOnLoadCalled) {
        _spBodyOnLoadFunctions.push(pageLoad);
    } else {
        pageLoad();
    }

    function pageLoad() {
        //onload code
    }
})();

4. Используйте RegisterModuleInit

Если у вас на сайте используется Minimal Download Strategy (MDS), то вам необходимо написать дополнительный код, чтобы вызывать функцию при каждой асинхронной загрузке страницы. MDS был создан для того, чтобы загружать не полностью страницу сервера, а только изменившуюся часть. В этом случае не происходит полная загрузка страницы и не вызывается событие body.onload. Для того, чтобы ваш код работал, вам необходимо вызвать функцию RegisterModuleInit, в которую передать имя скрипта и функцию, которая будет вызвана при асинхронной загрузке.

Пример кода загрузки с учетом

(function() {
    if (!_spBodyOnLoadCalled) {
        _spBodyOnLoadFunctions.push(pageLoad);
    } else {
        pageLoad();
    }

    function pageLoad() {
        //onload code
    }

    RegisterModuleInit(
        _spPageContextInfo.webServerRelativeUrl 
            + 'appname/script.js', 
        pageLoad);
})();

5. Для подключения jQuery используйте CustomAction ScriptLink

Не используйте другие способы, не трогайте masterpage, не создавайте ссылки в разметке. Чтобы поместить jQuery на все страницы сайта надо использовать следующий элемент в фиче:

<CustomAction 
    Location="ScriptLink" 
    ScriptSrc="~site/AppName/jquery.js" 
    Sequence="10001"/>

Этот код код добавляет ссылку на скрипт в тег head каждой страницы сайта. Он автоматически добавляет дополнительный параметр в url, который изменяется при изменении версии фичи.

Параметр Sequence позволяет управлять в каком порядке добавляются ссылки на скрипты.

Сам файл jQuery и скрипты размещайте в корне коллекции сайтов в папке с именем вашего приложения. И не забудьте включить BlobCache. Если Вы добавите такой элемент в фичу уровня Site, то jQuery будет добавлен также на все страницы всех подсайтов.

Но нужно помнить, что при подключении jQuery возникают проблемы:

 

6. jQuery ломает Asset Picker

Переменная $, определяемая в jQuery, конфликтует с именем переменной в диалоге выбора актива сайта (Asset Picker). В результате Asset Picker не работает после подключения jQuery.

7. jQuery в разных решениях будут конфликтовать друг с другом

Другая проблема, которая не просто часто, а постоянно встречается, заключается в том, что разные компоненты разных вендоров ставят jQuery. Это приводит к тому, что последняя версия перетирает все предыдущие.

Для этой и предыдущей проблемы есть решение:

8. Используйте jQuery.noConflict(true)

Эта функция делает две вещи:

  • Восстанавливает переменную $
  • При указании true в качестве параметра восстанавливает старое значение jQuery.

Сама функция возвращает текущий объект jQuery, который Вы можете сохранить в переменной.

9. Используйте IIFE

Для того, чтобы было удобно писать и копипастить из интернета код с jQuery удобно использовать Immediately-Invoked Function Expression (IIFE). По сути это объявление анонимной функции, совмещенное с вызовом. Выше я уже приводил пример кода с IIFE, но при использовании параметров можно сделать еще более удобный код:

window.myappName$ = window.myappName$ 
                    || jQuery.noConflict(true);

(function($) {
    if (!_spBodyOnLoadCalled) {
        _spBodyOnLoadFunctions.push(pageLoad);
    } else {
        pageLoad();
    }

    function pageLoad() {
        $('#pageTitle span').text('Hello from jQuery');
    }

    RegisterModuleInit(
            _spPageContextInfo.webServerRelativeUrl 
                + 'appname/script.js', 
            pageLoad);
})(window.myappName$);

Таким образом внутри вашего кода, Вы сможете использовать обычный jQuery код без извращений и конфликтов с другим решениями и частями SharePoint.

 

10. Используйте SPCop или R# c spcafcontrib

Последний совет - используйте инструменты SPCop\SPCAF и R# (ReSharper) с расширением SPCAFContrib.

Для SPCop\SPCAF расширение доступно на сайте http://spcafcontrib.codeplex.com/

Для R# плагин можно поставить из галереи расширений

Расширение содержит правила, которые находят неправильное использование jQuery в SharePoint проектах. В R# также есть возможность чинить неверный код автоматически (эта функциональность сейчас в процессе разработки).

Это расширение создается в основном Дмитрием Долотовских (страна должна знать своих героев), ему помогают Антон Вишняков, Алексей Большаков и я.