Хочу поделиться информацией о разработке отчетов для SharePoint 2010.

Есть традиционный способ:

  1. Устанавливаете SQL Server Reporting Services 2008 R2 в режиме интеграции SharePoint,
  2. Настраиваете сервер отчетов и SharePoint 2010,
  3. Добавляете тип контента Отчет в построителе отчетов в библиотеку, в которой хотите хранить отчеты,
  4. Создаете отчет при помощи Report Builder 3.0 (Построитель отчетов) или BIDS (Business Intelligence Development Studio)
  5. Подключаетесь к одному из стандартных источников – SQL Server, SharePoint и другие,
  6. Публикуете отчет в библиотеке SharePoint,
  7. Просматриваете отчет, щелкая на файле или добавляя веб часть для просмотра отчета на страницу.

А есть другой способ… Что если в качестве источника отчета Вам нужно отобразить данные аудита, прав пользователей, истории версий документа и другую информацию с портала?

  1. Создаете класс для хранения данных,
  2. Создаете класс с методом для получения коллекции данных,
  3. Создаете в Visual Studio 2010 отчет (*.rdlc файл),
  4. В качестве источника указываете класс хранения данных,
  5. Добавляете в отчет, например, таблицу с полями из источника,
  6. Создаете веб часть или страницу в папке LAYOUTS,
  7. Добавляете на страницу элемент управления ReportViewer,
  8. Указываете отчет и задаете ObjectDataSource со ссылкой на класс и метод получения данных.

По идее все просто и должно работать, но не тут-то было! Все делается через одно место, вернее через несколько мест J

Итак, с какими проблемами придется столкнуться:

  1. Как сделать класс данных, чтобы отчет его «видел»?
  2. Куда в SharePoint развернуть файлы отчетов?
  3. Как заставить заработать ReportViewer? (по умолчанию не работает, выдает ошибку)

Начнем с первого пункта. По неизвестной мне пока причине отчет не видит ни одного класса в текущем проекте. Думаю, это вина Visual Studio 2010, может выйдет какой-то hotfix или в SP1 исправят. Поэтому я сначала создал второй проект в решении – Class Library. В этом проекте в файле класса я написал следующий код:

namespace SPDataAccess

{

public class DataClass

{

public int id { get; set; }

public string title { get; set; }

 

public static List<DataClass> gets()

{

var l = new List<DataClass>();

l.Add(new DataClass() { id = 1, title = "hi" });

l.Add(new DataClass() { id = 2, title = "hello" });

l.Add(new DataClass() { id = 3, title = "whats up" });

return l;

}

}

}

 

В реальной жизни Вы, конечно же, обратитесь к SharePoint или другому источнику за более полезной информацией.

Далее библиотеку нужно подписать, поскольку её нужно будет развернуть в GAC. Для этого откройте настройки проекта (Signing) и выберите ключ (key.snk) от проекта SharePoint, который уже подписан.

Затем откройте пакет решения SharePoint (Package), на закладке Advanced добавьте библиотеку для развертывания – Add assembly from project output – и выберите второй проект.

Теперь добавьте в проект SharePoint отчет.

Можно добавить отчет в папку возможности, предварительно создав её, или используйте существующую.

Добавьте в отчет новый набор данных.

Создайте новое подключение.

Выберите тип – Object

Тип SharePoint добавляет Service Reference на REST сервис SharePoint (OData) с адресом типа http://portal/_vti_bin/listdata.svc То же самое касается и типа Service. Но реальных объектов, которые можно было бы использовать нет – нужно их отдельно создавать.

Далее Вы добавляете ссылку на второй проект, выбираете класс, хранящий данные и нажимаете Готово.

После этого добавьте из Toolbox таблицу в отчет и перетащите поля из набора данных в эту таблицу.

На этом этапе можете сразу скопировать файл отчета в домашнюю директорию веб приложения SharePoint. Например, C:\inetpub\wwwroot\wss\VirtualDirectories\80

В будущем эту процедуру лучше автоматизировать при помощи события FeatureInstalled в возможности. С примером можно ознакомиться здесь - http://geekswithblogs.net/bjackett/archive/2009/12/01/deploy-files-to-sharepoint-web-application-virtual-directories-at-feature-again.aspx При этом важно учесть, что в веб приложении может быть до 5 веб сайтов соответствующих зонам, при этом у каждого своя аутентификация и домашняя директория.

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

В ascx или aspx файле добавьте регистрацию сборки и класса для доступа к данным. В моем случае это:

<%@ Assembly Name="SPDataAccess, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9cb361091e2dad5b" %>

<%@ Import Namespace="SPDataAccess" %>

 

Если будете писать все вручную, то добавьте и ссылку на сборку с ReportViewer.

<%@ Register Assembly="Microsoft.ReportViewer.WebForms, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"

Namespace="Microsoft.Reporting.WebForms" TagPrefix="rsweb" %>

 

Добавьте компонент ReportViewer, укажите в качестве источника бизнес объект, на страницу добавиться ObjectDataSource, задайте ему свойства – класс и метод для получения данных.

В качестве отчета ReportViewer задайте имя файла для свойства ReportPath.

В коде это выглядит так:

<rsweb:ReportViewer ID="ReportViewer1" runat="server" Font-Names="Verdana"

Font-Size="8pt" InteractiveDeviceInfos="(Collection)"

WaitMessageFont-Names="Verdana" WaitMessageFont-Size="14pt">

<LocalReport ReportPath="test.rdlc">

<DataSources>

<rsweb:ReportDataSource DataSourceId="ObjectDataSource3" Name="DataSet1" />

</DataSources>

</LocalReport>

</rsweb:ReportViewer>

<asp:ObjectDataSource ID="ObjectDataSource3" runat="server"

 

TypeName="SPDataAccess.DataClass, SPDataAccess, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9cb361091e2dad5b"

OldValuesParameterFormatString="original_{0}" SelectMethod="gets">

</asp:ObjectDataSource>

 

Визуально – выглядит так:

1 - Добавление компонента

2 – Выбор отчета

3 – Путь к отчету

4 – Настройка Объекта

5 – Выбор Объекта

6 – Выбор метода для получения данных

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

1 – Запустите службу ASP.NET State

2 – внесите изменения в файл web.config веб приложения. (до 5 файлов для разных сайтов в разных зонах). Лучше автоматизировать операции при помощи SPWebConfigModification (http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.administration.spwebconfigmodification.aspx ).

 

1 - Найдите строку в AppSettings и закомментируйте:

<!--<add key="ReportViewerMessages" value="Microsoft.SharePoint.Portal.Analytics.UI.ReportViewerMessages, Microsoft.SharePoint.Portal, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />-->

2 - добавьте тег внутри system.web:

<sessionState mode="InProc" timeout="60" />

3 - Включите сессии на уровне страницы - тег page внутри system.web:

<pages enableSessionState="true" enableViewState="true" enableViewStateMac="true" validateRequest="false" />

4 - Закомментируйте строку внутри тега system.webserver\modules:

<!--<remove name="Session" />-->

5 - Добавьте тег внутри system.web\httphandlers:

<add verb="*" path="Reserved.ReportViewerWebControl.axd" type = "Microsoft.Reporting.WebForms.HttpHandler, Microsoft.ReportViewer.WebForms, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />

6 - Добавьте тег внутри system.webserver\handlers:

<add name="ReportViewerWebControlHandler" preCondition="integratedMode" verb="*" path="Reserved.ReportViewerWebControl.axd" type="Microsoft.Reporting.WebForms.HttpHandler, Microsoft.ReportViewer.WebForms, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />

7 - Закомментируйте строку внутри тега system.WebServer\httphandlers:

<!--<add name="ReportViewerWebControl" verb="*" path="Reserved.ReportViewerWebControl.axd" type="Microsoft.Reporting.WebForms.HttpHandler, Microsoft.ReportViewer.WebForms, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />—>

8 – найдите секцию SafeControls и тэг SafeControl с элементом ObjectDataSource, измените значение атрибута Safe=”false” на true.

TypeName="ObjectDataSource" Safe="True"

Пожалуй, на этом все – можно пробовать!

У меня получилось так:

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