Страницы с тегами : WCF

Поиск в приложениях SharePoint. Часть 3.

В SharePoint 2013 появился REST веб-сервис, который позволяет делать поисковые запросы из JavaScript. В SharePoint 2010 есть только search.asmx, который требует генерировать и парсить большой объём XML (в лучших традициях SharePoint).

Чтобы упростить жизнь разработчику клиентских компонентов я написал REST веб-сервис для SharePoint 2010.

Реализация

За основу взял метод, который описывал ранее - Javascript-enabled SharePoint WCF services.

Контракт у сервиса очень простой:

[ServiceContract]
public interface ISearch
{
    [OperationContract]
    [WebGet(BodyStyle = WebMessageBodyStyle.Bare, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
    Stream Query(string q, int top, int skip, string select, string orderBy, bool includeRefiners, string refiners);
}

Параметры вызова:

  • q – текст запроса (обязательно).
  • top – количество результатов.
  • skip – с какой позиции в выборке отдавать результаты.
  • select – через запятую названия managed properties в результатах.
  • orderBy – через запятую названия managed properties по которым сортировать результат, после имени можно указать desc для сортировки по убыванию.
  • includeRefinerstrue или false, возвращать результаты уточнений или нет.
  • refiners - через запятую названия managed properties для формирования уточнений.

Реализация:

public System.IO.Stream Query(string q, int top, int skip, string select, string orderBy,
                    bool includeRefiners, string r) 
{
    using (new SPMonitoredScope("Execute Query Method"))
    {
        var site = SPContext.Current.Site;
        var result = GetSearchResults(site, q, top, skip, select, orderBy, includeRefiners, r);
        return ToJson(result);
    }
}

Метод GetSearchResults довольно простой, он передает параметры запроса в объект KeywordQuery и получает результат.

private static ResultTableCollection GetSearchResults(SPSite site, string q, int top, int skip, string select, string orderBy, bool includeRefiners, string r)
{
    var query = new KeywordQuery(site);
    query.QueryText = q;
    query.StartRow = skip;
    if (top > 0)
    {
        query.RowLimit = top;
    }


                
            


Javascript-enabled SharePoint WCF services

К сожалению очень мало толковой информации о том, как создать WCF веб-сервис для SharePoint, который будет доступен как для WS-* клиентов, так и для Javascript.

Да-да, я знаю что уже вышел SharePoint 2013 и .NET 4.5, то что WCF уже не модно, и надо юзать WebAPI и REST. НО не факт что можно будет расширять API для SharePoint 2013, а WebAPI в SharePoint 2013 не работает (или по крайней мере это еще никто не сделал).

Так что пока используем WCF, благо его возможностей более чем достаточно для решения задачи.

Для начала надо поставить расширение студии CKS Dev (правильно говорить “секасдев”, @amarkeev гарантирует это), в нем есть шаблон для WCF сервиса

image

Этот пункт создает веб-сервис с BasicHttpBinding.

В SharePoint не обязательно параметры указывать в web.config, достаточно указать Factory в .svc файле, что и делает данный шаблон.

Какие есть Factory и зачем они нужны можно узнать по ссылке.

В принципе можно и этот сервис использовать в javascript коде, но придется долго и мучительно генерировать и парсить XML для SOAP. Чего делать крайне не хочется.

Для того, чтобы работать с теплым ламповым JSON достаточно сделать несколько изменений.

  1. Скопировать .svc файл и поставить ему те же параметры развертывания, что у исходного сервиса. Я даю сервисам имя <servicename>.json.svc
  2. В новом файле .svc зменить MultipleBaseAddressBasicHttpBindingServiceHostFactory на MultipleBaseAddressWebServiceHostFactory
  3. В интерфейсе сервиса добавить атрибуты методам, например
    [ServiceContract]
    public interface ITestService
    {
        [OperationContract]
        [WebGet(BodyStyle = WebMessageBodyStyle.Bare, 
                RequestFormat = WebMessageFormat.Json, 
                ResponseFormat = WebMessageFormat.Json)]
        //[WebInvoke(Method="POST",
        //        BodyStyle = WebMessageBodyStyle.Bare,
        //        RequestFormat = WebMessageFormat.Json,
        //        ResponseFormat = WebMessageFormat.Json)]
        string HelloWorld();
    }

И все, код сервиса править не надо. Атрибуты WebGet и WebInvoke можно найти в сборке System.SeviceModel.Web.

Код для вызова сервиса (javascript):

var webServerRelativeUrl = _spPageContextInfo.webServerRelativeUrl != "/" 
                           ? _spPageContextInfo.webServerRelativeUrl 
                           : "";