SharePoint + WCF + jqGrid + jQueryUI. Создание справочника на сайте SharePoint

Wednesday, 24 February 2010 16:00 ivanoff

Этот пост будет посвящен описанию создания справочника на сайте SharePoint с использованием WCF-сервиса, библиотеки jQuery и плагинов к ней.

Введение

В рамках запуска нового сайта ИНГГ СО РАН, который построен на SharePoint Server 2007, было решено разработать новую версию телефонного справочника сотрудников. Для клиентской части был выбран jqGrid в качестве элемента для таблицы сотрудников и jQueryUI для отображения подробной информации о сотруднике. Данные клиентская часть получает от RESTful веб-сервиса, реализованного на WCF, который развернут тут же, на сайте SharePoint.

Пара картинок того, что получилось:

image  image

WCF-сервис и PhoneBookWebpart

Справочник сотрудников отображается на странице веб-частей на сайте SharePoint в виде веб-части, содержимое которой загружается из ascx-контрола.

        protected override void CreateChildControls()
        {
            if (!_error)
            {
                try
                {
                    base.CreateChildControls();

                    if (!this.WebPartManager.DisplayMode.AllowPageDesign)
                    {
                        var gridControl = 
                            (JqGridPhoneBookControl)Page.LoadControl(
                                              "~/_controltemplates/IPGG.IntegrationSystem/PhoneBook/JqGridPhoneBookControl.ascx");
                        gridControl.DivisionNumber = DivisionNumber;
                        Controls.Add(gridControl);
                    }
                }
                catch (Exception ex)
                {
                    HandleException(ex);
                }
            }
        }

Контрол JqGridPhoneBookControl.ascx практически не содержит серверного кода, за исключением значения скрытого тега <input>, с помощью которого через свойства веб-части передается номер подразделения для начальной фильтации.

<input type="hidden" id="divisionNumberFromWebpart" value='<%=DivisionNumber %>'/>
<table id="phoneBookGrid"></table>
<div id="phoneBookPager"></div>
<div id="employeeInfoContainer">
    ...
</div> 

Сервис, предоставляющий данные, имеет следующий интерфейс.

    [ServiceContract]
    public interface IPhoneBookService
    {
        [OperationContract]
        [WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json)]
        JqGridResult<Employee> GetAllRecordsForJqGrid();

        [OperationContract]
        [WebInvoke(Method = "GET")]
        Stream GetPhoto(int employeeId);

        [OperationContract]
        [WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json)]
        Employee GetRecord(int employeeId);
    }

JqGridResult – класс, возвращаемый методом GetAllRecordsForJqGrid и принимаемый reader’ом jqGrid.

    [DataContract]
    public class JqGridResult<T>
    {
        [DataMember]
        public int CurrentPage { get; set; }
        [DataMember]
        public int TotalPages { get; set; }
        [DataMember]
        public int TotalRecords { get; set; }
        [DataMember]
        public List<T> Records { get; set; }
    }

Код сервиса разворачивается в GAC вместе с остальными сборками wsp-решения для SharePoint, svc-файл веб-сервиса помещается в подпапке папки c:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\TEMPLATE\LAYOUTS\ вместе с файлом web.config, в котором необходимо указать webHttpBinding

<?xml version="1.0"?>
<configuration>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="serviceBehavior">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="endpointBehavior">
          <webHttp/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <services>
      <service name="IPGG.IntegrationSystem.Web.Services.PhoneBookService" behaviorConfiguration="serviceBehavior">
        <endpoint address="" binding="webHttpBinding" contract="IPGG.IntegrationSystem.Web.Services.IPhoneBookService" behaviorConfiguration="endpointBehavior"/>
      </service>
    </services>
  </system.serviceModel>
</configuration>

Для корректной работы WCF-сервисов в приложении SharePoint, необходимо установить SPWCFSupport, либо реализовать подобный код у себя в решении. Подробности зачем это нужно – здесь.

jqGrid и jQueryUI

Содержимое таблицы phoneBookGrid (см. JqGridPhoneBookControl.ascx) формируется с помощью jqGrid, плагина к jQuery, который берет данные из WCF-сервиса, описанного выше, посредством ajax-запроса, в формате json.

        $("#phoneBookGrid").jqGrid({
            url: "/_layouts/IPGG.IntegrationSystem/PhoneBookService.svc/GetAllRecordsForJqGrid",
            datatype: "json",
            jsonReader: gridJsonReader,
            colNames: columnNames,
            colModel: columns,
            width: 850,
            height: 460,
            shrinkToFit: false,
            pager: "#phoneBookPager",
            rowList: [20, 50, 100, 1000],
            onSelectRow: GetEmployeeDetails,
            loadComplete: gridLoaded
        }).navGrid("#phoneBookPager", { add: false, edit: false, del: false, search: false, refresh: true }).filterToolbar();

        $("#phoneBookGrid").jqGrid("navButtonAdd", "#phoneBookPager", {
            caption: "Отобразить/Скрыть столбцы",
            title: "Изменить порядок столбцов",
            onClickButton: function() {
                $("#phoneBookGrid").jqGrid("columnChooser");
            }
        });

        $("#employeeInfoContainer").dialog({
            bgiframe: true,
            modal: true,
            autoOpen: false,
            width: 550,
            resizable: false,
            close: ClearDialog,
            buttons: {
                Ok: function() {
                    $(this).dialog('close');
                }
            }
        });

jqGrid принимает json-объект с определенными именами свойств, однако можно настроить jsonReader и передавать какой угодно json-объект. В нашем случае – это JqGridResult.

        var gridJsonReader = {
            root: "Records",
            page: "CurrentPage",
            total: "TotalPages",
            records: "TotalRecords",
            repeatitems: false,
            id: "Id"
        };

При щелчке по строке таблицы вызывается функция GetEmployeeDetails, которая отправляет еще один ajax-запрос к веб-сервису и отображает данные в модальном диалоге jQueryUI

        function GetEmployeeDetails(id) {
            $("#employeeInfoContainer").dialog("open");
            $.ajax({
                url: "/_layouts/IPGG.IntegrationSystem/PhoneBookService.svc/GetRecord",
                data: "employeeId=" + id,
                success: ProcessInfo,
                error: ProcessError
            });
            GetImage(id);
            ...            
        }

Фотография сотрудника берется из веб-сервиса с помощью GET-запроса

function GetImage(employeeId) {
        $("#employeeImage").attr("src", "/_layouts/IPGG.IntegrationSystem/PhoneBookService.svc/GetPhoto?employeeId=" + employeeId);
    }

Вместо заключения

В данной статье не приведен код, реализующий доступ к данным. Могу лишь сказать, что это простая реализация паттерна Репозиторий на Linq To SQL. Для фильтрации, поиска и постраничного вывода использован интерфейс IQueryable<T>.

Как оказалось, нет ничего сложного в реализации и развертывании решений на jQuery и WCF под SharePoint.

Однако, если SharePoint  работает на IIS7, то может возникнуть проблема, на решение которой мне пришлось потратить некоторое время.

После развертывания решения на production-сервере, выдавалась 404 ошибка при запросах на URL типа “~/_layouts/IPGG.IntegrationSystem/PhoneBookService.svc/GetRecord”.

Решение состоит в том, что необходимо зарегистрировать обработчник запросов для .svc. По умолчанию, в IIS7 для SharePoint-сайта этого не сделано.

image

Tags:   , , ,
Categories:   .NET | jQuery | SharePoint | Web
Действия:   E-mail | Permalink | Comments (0) | RSS комментариевRSS comment feed

Конкурс Платформы 2010. Принимаю поздравления

Friday, 30 October 2009 22:35 ivanoff

Поучаствовал в конкурсе Платформа 2010, отвечая на вопросы от @gaidar в твиттере. И очень рад тому, что оказался в списке победителей!

Пост @gaidar в твиттере: Конкурс #msplatforma Победили @aleyush-17, @mereskin-12, @Alexion-4, @denisivanov-4, @trukhinyuri-3. Победители - пришлите email в DM.

Принимаю поздравления! :)

Tags:   ,
Categories:  
Действия:   E-mail | Permalink | Comments (1) | RSS комментариевRSS comment feed

Конкурс Платформы 2010. Последние три вопроса.

Friday, 30 October 2009 20:04 ivanoff

Ответы на последние вопросы от @gaidar в конкурсе Платформа 2010.

Времени на ответы уже не осталось. Поэтому кратко.

Вопрос 11 Какие основные нововведения в редакторе кода Visual Studio 2010?

Ответ

Перечислением:

  • Enhanced Docking
  • Zoom
  • Box Selection
  • Иерархия вызовов
  • Navigate To
  • Highlighting References
  • Generate From Usage
  • IntelliSense Suggestion Mode

Вопрос 12 Каковы возможности по использованию .NET в базах SQL Server 2008 R2?

Ответ

Не знаю :)

Вопрос 13 В чем заключаются новшества ASP.NET MVC Framework версии 2 по сравнению с версией 1?

Ответ

Поддержка Areas, шаблонов для Display, Edit и Master Page, улучшения валидация на стороне клиента, ModelMetaData, DataAnnotations, новые атрибуты контроллеров.

Tags:   , ,
Categories:  
Действия:   E-mail | Permalink | Comments (0) | RSS комментариевRSS comment feed

Конкурс Платформы 2010. Вопрос про Correlation в WF.

Friday, 30 October 2009 09:43 ivanoff

Десятый вопрос конкурса Платформа 2010 от @gaidar.

Вопрос

Что такое correlation в WF?

Ответ

Correlation в WF - механизм, с помощью которого хостовый процесс может общаться с конкретной activity в конкретном workflow, передавая уникальный идентификатор в качестве аргумента события.

Таким образом, Windows Workflow Foundation использует correlation для связывания входящего сообщения с конкрентной activity типа HandleExternalEventActivity в экземпляре workflow. Достигается это использованием интерфейсных аттрибутов CorrelationParameterAttribute, CorrelationInitializerAttribute и CorrelationAliasAttribute.

Более подробно в MSDN

Tags:   , ,
Categories:  
Действия:   E-mail | Permalink | Comments (0) | RSS комментариевRSS comment feed

Конкурс Платформы 2010. Вопрос про Smooth Streaming.

Thursday, 29 October 2009 09:33 ivanoff

Ответ на девятый вопрос от @gaidar в конкурсе Платформа 2010

Вопрос 9

Что такое Smooth Streaming? Как его организовать?

Ответ

Smooth Streaming - расширение IIS Media Services, которое позволяет адаптивно передавать по HTTP медиа-контент, используя Silverlight. Клиенты с быстрым соединением в этом случае получают контент в отличном качестве (вплоть до FullHD 1080p), клиенты с более медленным соединением получают тот же контент в качестве, приемлемом для их соединения.

Как это организовать? Основная идея Smooth Streaming заключается в том, что весь поток разбивается на мелкие фрагменты. Фрагмент посылается клиенту и проверяется, что в нужное время он был воспроизведен в нужном качестве. Если этого не было достигнуто, следующий фрагмент посылается в качестве ниже предыдущего.

Таким образом, файл кодируется с разными уровнями качества. Далее IIS, на котором установлены компоненты Smooth Streaming, создает кэшируемые фрагменты этих файлов (виртуальные фрагменты) и по запросу отдает фрагмент с наиболее высоким уровнем качества для каждого клиента.

Tags:   , ,
Categories:  
Действия:   E-mail | Permalink | Comments (0) | RSS комментариевRSS comment feed

Конкурс Платформы 2010. Вопросы про WCF, HttpHandler/HttpModule и Process/Thread

Wednesday, 28 October 2009 20:44 ivanoff

Сегодня ответы на 3 вопроса от @gaidar в рамках конкурса Платформа 2010

Вопрос 6

В какой версии WCF поддерживается Basic Profile 1.2? Какие отличия от 1.1?

Ответ

Basic Profile 1.2 будет поддерживаться в WCF 4. Отличается от Basic Profile 1.1 тем, что появилась поддержка WS-Addressing и Message Transmission Optimization Mechanism (MTOM). Кроме того, Basic Profile 1.2 не может работать с Simple SOAP Binding Profile 1.0.

Вопрос 7

Чем отличаются HttpHandler и HttpModule?

Ответ

HttpModule - глобальный обработчик запросов ко всем страницам приложения. С его помощью можно иметь возможность выполнять свой код на различных этапах обработки запроса к приложению. Во время выполнения приложения существует только один экземпляр класса каждого модуля, прописанного в web.condig.
HttpHandler отличается от HttpModule тем, что является обработчиком конкретного запроса. Экземпляры HttpHandler создаются для каждого запроса. Этим HttpHandler схож с обычной страницей приложения asp.net.

Вопрос 8

Чем отличается Process от Thread?

Ответ

В Windows один или более потоков (thread) работают в рамках одного процесса (process). Процесс вначале запускается с одним управляющим потоком (primary thread) и имеет в своем распоряжении ресурсы ОС, такие как идентификатор процесса, виртуальную память, хэндлы к системным объектам и т.д. Далее в процессе могут быть созданы другие потоки. Таким образом, процесс - контейнер для потоков.
Поток - единица исполнения на процессоре. Потоки используют адресное пространство процесса, в рамках которого они работают и только его.

Tags:   , , , , , ,
Categories:  
Действия:   E-mail | Permalink | Comments (0) | RSS комментариевRSS comment feed

Конкурс Платформы 2010. Пятый вопрос.

Wednesday, 28 October 2009 09:58 ivanoff

Участвую в конкурсе Платформа 2010, отвечая на вопросы от @gaidar

Пятый вопрос конкурса

Что такое Web Garden? Плюсы и минусы использования?

Ответ

Web Garden - термин, обозначающий ситуацию, когда два или более процесса (worker process) сконфигурированы принадлежащими к одному пулу приложений (app pool) на веб-сервере. Отличие от фермы - процессы работают на одном сервере, а не на нескольких.

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

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

Tags:   , ,
Categories:  
Действия:   E-mail | Permalink | Comments (0) | RSS комментариевRSS comment feed

Конкурс Платформы 2010. Четвертый вопрос.

Wednesday, 28 October 2009 09:39 ivanoff

Продолжаю-таки отвечать на вопросы от @gaidar в конкурсе Платформа 2010.

Вопрос

В чем отличия между typeof и GetType?

Ответ

typeof позволяет получить объект типа System.Type для какого-либо типа. GetType же позволяет получить объект типа System.Type для объекта, то есть речь идет о рантайме.

Tags:   , ,
Categories:  
Действия:   E-mail | Permalink | Comments (0) | RSS комментариевRSS comment feed

Конкурс Платформы 2010. Третий вопрос.

Wednesday, 28 October 2009 09:31 ivanoff

Эх, эти часовые пояса. Когда в Москве полшестого, в Новосибирске уже полдевятого. А с утра на все вопросы уже как-то ответили. Ну все равно буду продолжать отвечать, раз уж начал.

Итак, третий вопрос от @gaidar в конкурсе Платформа 2010: Может ли DateTime равняться null?

Ответ очень краткий: нет. DateTime - это структура. А value-type не может быть null. Вот DateTime? - может. @gaidar там точно вопросика нет? :)

Tags:   , ,
Categories:  
Действия:   E-mail | Permalink | Comments (0) | RSS комментариевRSS comment feed

Конкурс Платформы 2010. Второй вопрос.

Tuesday, 27 October 2009 10:30 ivanoff

Для тех, кто не в курсе - @gaidar публикует в твиттере вопросы, ответив на которые можно получить баллы к рейтингу и даже выиграть билет на Платформу 2010. Мой ответ на первый вопрос - здесь

Второй вопрос конкурса: .NET Remoting по протоколу SOAP. Возможно ли? Если да, то в чем отличия от ASMX Web-службы?

Скажу сразу - опыта работы с .NET Remoting у меня нет, поэтому отвечу теоретически.
Ответ: Да, .NET Remoting по протоколу SOAP возможен. Вот скриншот со страницы на GDN в подтверждение.

.NET Remoting usage

Отличие от ASMX Web-службы в том, что ASMX может хоститься только на IIS, .NET Remoting - в любом приложении. Кроме того, .NET Remoting не привязан к HTTP.

Tags:   , , , ,
Categories:  
Действия:   E-mail | Permalink | Comments (0) | RSS комментариевRSS comment feed


Денис Иванов

Занимаюсь разработкой приложений для веб на платформе .NET