Pull to refresh

Загрузка данных в списки Sharepoint

Reading time6 min
Views16K
При разработке SharePoint-решений часто стоит задача, помимо автоматического разворачивания структуры сайта (поля, типы контента, списки), также и наполнять его базовым контентом. Это могут быть, в основном, списки со справочной информацией. Но, помимо этого, может возникунть потребность наполнить их какими-то тестовыми данными, чтобы провести тестирование решения, в том числе и нагрузочного.

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

Итак, идея заключается в следующей логике:

создание таблиц с данными в Excel,
экспорт данных из Excel в XML,
добавление XML файлов в проект Visual Studio,
парсинг XML содержимого файлов и добавление данных в списки в ресивере фичи на активацию.
Использовать Excel довольно-таки удобно. Во-первых, данные там легко наполнять; можно создавать копии разных строк, просто протянув их мышкой; можно писать разные формулы, чтобы придать значениям рандомности в целях тестирования и т.д. И самое главное — именно в таком виде справочную информацию обычно присылает заказчик, то есть подготоить информацию по вашему запросу в Excel ему будет намного проще.

Последовательность действий:

1. Создайте в Excel-книге на отдельном листе таблицу с данными.

2. Создайте файл .xsd, который будет представлять схему данных, в таком формате:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Currencies">
<xs:complexType>
<xs:sequence>
<xs:element ref="Currency" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Currency">
<xs:complexType>
<xs:sequence>
<xs:element name="Title" type="xs:string"/>
<xs:element name="Currency_IsNational" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

Для удобства называйте корневой элемент так, как называется ваш список на сайте (или как основная часть его адреса). Я называл этот элемент Currencies. При парсинге XML можно будет сразу использовать это название для доступа к нужному списку.

Название полей указывайте в соответствии с InternalName у полей в нужном списке (в примере выше это Title и Currency_IsNational).

Также не смущайтесь, что тип значений стоит «xs:string». При парсинге XML вы все равно будете получать стринговые значения, которые при записи в объект SPListItem сами будут сконвертированы в нужный тип.

Если же вам надо использовать более сложные типы, вроде User, то указывайте в Excel-таблице, к примеру, login name, а в коде выполняйте дополнительную конвертацию в SPFieldUserValue. Далее это будет продемонстрировано.

3. Активируйте вкладку «Разработчик» в экселе.

4. На этой вкладке нажмите кнопку «Источник»:

5. В появившейся панеле нажмите кнопку «Карты XML»:

6. Нажмите кнопку «Добавить» и добавьте созданный ранее файлик .xsd:

7. После добавления схемы выделите заголовок таблицы в экселе и нажмите в панеле справа на дереве данных «Сопоставить элемент»:

Таким образом вы сопоставите вашей таблице схему данных. Теперь её можно экспортировать в XML.

8. Нажмите «Экспорт» и сохраните файл .xml:

Экспортированный файл будет выглядеть примерно так:

9.Проделайте описанные выше операции для всех таблиц, которые вы собираетесь загрузить на сайт.

10. Создайте Module в вашем проекте Visual Studio и добавьте в него все .xml фалы с данными, созданными таким образом. Назовите его к примеру InitialData.

Не забудьте включить модуль в фичу.

11. При активации фичи на сайте будет создаваться папка с именем InitialData, куда будут добавлены .xml файлы.

12. Далее в ресивере активации фичи добавьте логику по парсингу этих xml файлов и создании айтемов в нужных списках.

К моменту выполнения этих действий списки уже должны существовать на сайте со всеми необходимыми полями. При этом вы можете наполнять данными списки, в которых уже присутствуют другие данные.

Метод ниже проходит по всем xml файлам в папке InitialData и вызывает метод ImportToSPList для каждого.

public void Import()
{
// _siteUrl - адрес сайтовой коллекции
using (SPSite site = new SPSite(_siteUrl))
{
SPWeb web = site.RootWeb;
// _initialDataFolderName - название Модуля (папки, которую он создает)
SPFolder initialDataFolder = web.RootFolder.SubFolders[_initialDataFolderName];

foreach (SPFile file in initialDataFolder.Files)
{
if (file.Name.EndsWith(".xml", StringComparison.CurrentCultureIgnoreCase))
{
using (MemoryStream inStream = new MemoryStream(file.OpenBinary()))
{
using (XmlTextReader reader = new XmlTextReader(inStream))
{
XmlDocument xd = new XmlDocument();
xd.Load(reader);

ImportToSPList(web, xd);
}
}
}
}
}
}

В методе ImportToSPList определяется список на основании названия корневого элемента из xml, как я писал выше. Далее для каждого вложенного элемента, который, по сути, преобразовывается в SPListItem, идёт обход по их полям и запись значений в поля SPListItem’а.

private void ImportToSPList(SPWeb web, XmlDocument xd)
{
XmlElement root = xd.DocumentElement;
// получаем вн. название списка из названия корневого элемента
string rootName = root.LocalName;
string listUrl = String.Format("Lists/{0}/AllItems.aspx", rootName);
SPList list = web.GetListFromUrl(listUrl);

foreach (XmlNode item in root.ChildNodes)
{
SPListItem spListItem = list.AddItem();
// обходим все поля
foreach (XmlNode field in item.ChildNodes)
{
// ищем специальное правило для этого списка и поля
DataImportSpecialRule specialRule =
_diSpecialRules.FirstOrDefault(x => x.ListUrl == listUrl && x.FieldName == field.LocalName);
if (specialRule == null)
{
// специального правила нет, поэтому записываем стринговое значение
spListItem[field.LocalName] = field.InnerText;
}
else
{
// записываем значение нужного типа через метод-конвертер
spListItem[field.LocalName] = specialRule.Converter(web, field.InnerText);
}
}
// сохраняем айтем
spListItem.Update();
}
}

Также обратите внимание на вспомогательный класс DataImportSpecialRule, который нужен для конвертации стринговых значений из xml в более сложный тип, если это требуется.

Вот сам класс DataImportSpecialRule, который хранит в себе адрес списка, название поля и функцию для конвертации:

public delegate object GetTypedValue(SPWeb web, string value);

class DataImportSpecialRule
{
public string ListUrl { get; set; }
public string FieldName { get; set; }
public GetTypedValue Converter { get; set; }
}

Функция имеет сигнатуру, описанную в делегате GetTypedValue. На вход она принимает SPWeb и стринговое значение, а возвращает объект, который должен быть записан в поле SPListItem’а.

Изначально вы можете описать все правила, которые должны быть применены ко всем вашим справочникам, так, как показано в примере:

_diSpecialRules = new List()
{
new DataImportSpecialRule()
{
ListUrl = "Lists/BusinessBlocks/AllItems.aspx",
FieldName = "BusinessBlock_Group",
Converter = (SPWeb web, string value) =>
{
SPGroup group = web.SiteGroups[value];
return new SPFieldUserValue(web, group.ID, group.Name);
}
}
// тут добавляются другие правила
};

Как вы видите, в данном правиле происходит описание того, как значение из xml файла, содержащее только название группы, будет записано в поле SPListItem корректным образом.

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

private SPFieldMultiChoiceValue MultiChoiceConverter(SPWeb web, string value)
{
SPFieldMultiChoiceValue fValue = new SPFieldMultiChoiceValue();
foreach (string choice in value.Split(';')) fValue.Add(choice.Trim());
return fValue;
}


Вы можете изменить разделитель, дописать другие правила. В статье приводится лишь концепция и примеры, как это можно легко сделать.

Вывод:

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

Больше на SharePoint Channel
Tags:
Hubs:
+2
Comments3

Articles