Untitled

Первая часть этой серии была написана примерно полтора года назад, после этого появился SharePoint 2013, в котором добавили очень много возможностей для использовании поиска в решениях. Но недавний опрос в сообществе (https://www.facebook.com/groups/sharepointrussian/permalink/514677285314072/?stream_ref=2) показал, что наиболее популярной версией до сих пор является SharePoint 2010.

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

DataFormWebPart

Стандартная веб-часть SharePoint позволяет использовать различные источники данных и формировать разметку с помощью XSL. Источник данных описывается с помою класса наследника System.Web.UI.DataSourceControl. В разметке страницы или .webpart файле можно указать какой DataSource использовать в веб-части.

SearchDataource

Для начала создадим DataSource, который возвращает результаты поискового запроса. На MSDN есть инструкция по созданию класса DataSource - http://msdn.microsoft.com/RU-RU/library/92e191zc(v=vs.90)

public class SearchDataSource: DataSourceControl
{
    protected override DataSourceView GetView(string viewName)
    {
        return new SearchDataSourceView(this);
    }

    public string QueryText { get; set; }

    public string SelectProperties { get; set; }        
}
Основная работа делается в классе SearchDataSourceView, наследнике DataSourceView.
class SearchDataSourceView: DataSourceView
{
    SearchDataSource dataSource;

    public SearchDataSourceView(SearchDataSource dataSource): base(dataSource,"")
    {
        this.dataSource = dataSource;
    }

    public override bool CanPage
    {
        get
        {
            return true;
        }
    }

    public override bool CanSort
    {
        get
        {
            return true;
        }
    }

    public override bool CanRetrieveTotalRowCount
    {
        get
        {
            return true;
        }
    }

    protected override System.Collections.IEnumerable ExecuteSelect(DataSourceSelectArguments arguments)
    {
        var query = GetQuery(arguments.SortExpression);

        query.StartRow = arguments.StartRowIndex;
        query.RowLimit = arguments.MaximumRows;

        var results = query.Execute()[ResultType.RelevantResults];
        arguments.TotalRowCount = results.TotalRows;
        return results.Table.DefaultView;
    }

    private KeywordQuery GetQuery(string sortExpression)
    {
        /* omited for clarity */
    }
}

Основной метод класса – ExecuteSelect, он должен возвращать IEnumerable, поддерживающий TypeDescriptor, например DataView. Про TypeDescriptors я писал ранее – http://gandjustas.blogspot.ru/2011/08/blog-post_22.html. Класс DataSourceView может поддерживать разбиение на страницы и сортировку, это определяется свойствами, которые я переопределил в начале.

Код создания запроса:

private KeywordQuery GetQuery(string sortExpression)
{
    var query = new KeywordQuery(SPContext.Current.Site);
    query.QueryText = this.dataSource.QueryText;
    query.ResultTypes = ResultType.RelevantResults;

    if (!string.IsNullOrEmpty(this.dataSource.SelectProperties))
    {
        query.SelectProperties.Clear();
        foreach (var property in this.dataSource.SelectProperties.Split(','))
        {
            query.SelectProperties.Add(property.Trim());
        }
    }

    if (!string.IsNullOrEmpty(sortExpression))
    {
        query.SortList.Clear();
        foreach (var sort in sortExpression.Split(','))
        {
            if (sort.EndsWith(" DESC"))
            {
                query.SortList.Add(sort.Substring(0, sort.IndexOf(" DESC")), SortDirection.Descending);
            }
            else
            {
                query.SortList.Add(sort, SortDirection.Ascending);
            }
        }
    }

    return query;
}

Этот код заполняет базовые параметры, запрашиваемые свойства и параметры сортировки.

Настройка веб-части

Добавляем веб-часть на страницу

image

 

Далее заменяем DataSource и вставляем identity transform

image

Директиву Register нужно вставлять прямо в раздел DataSource. В XSL надо вставить Identity Transform, чтобы получить данные в виде XML :

<xsl:stylesheet version="1.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:template match="/"  >
        <xmp>
            <xsl:copy-of select="." />
        </xmp>
    </xsl:template>
</xsl:stylesheet>

В результате получим такое:

image

Далее можно скопировать полученный XML и сделать необходимый XSL в Visual Studio или в SharePoint Designer.

Например так:

image

Создаем пакет решения

Чтобы завернуть полученный результат в WSP надо экспортировать веб-часть с сайта. Получившийся .webpart файл включить в решение. Это все.

Причем можно деплоить сборку с DataSource в farm solution, а .webpart файлы в sandbox.

Для конкретных задач можно расширить функционал:

  • Добавить обработку параметров DataSource. Параметры позволяют использовать значения QueryString, связи между веб-частями и другие внешние факторы. Также можно создавать свои параметры.
  • Сделать аналогичный DataSource для RefinementResults, чтобы получать статистику. Что очень часто нужно для главной страницы порталов.

Если вам нужна веб-часть в одном экземпляре (что бывает чуть менее, чем всегда), то можно не париться с сохранением .webpart и ковырянием в SharePoint Designer. Достаточно просто сделать наследника DataFormWebPart и переопределить метод GetDataSouce. При этом можно также переопределить XSL, чтобы он всегда указывал на файл в виртуальной файловой системе. Это значительно облегчит сопровождение решения.

Заключение

Как обычно исходники можно найти на http://spsamples.codeplex.com. Также сделал релиз: https://spsamples.codeplex.com/releases/view/117762.

Качайте, смотрите, изучайте, интегрируйте в свои решения.

Теги : DataFormWebPart, XSLT, SharePoint Designer, код, DataSource, поиск, разработка, SharePoint