Generate SharePoint project constants with T4 by feature definitions

Problem

Usually the main problem of SharePoint development is accessing SPListItem fields values by theirs internal names of field ids. For example:


SPListItem listItem = GetLIstItem();
// I prefer to use field ids for speed and garanteed way extract values
listItem[SPBuiltInFieldId.Title]

The output file will be like that:


But in some scenarios fieldId doesn’t help me for get values, such as get it in item event receivers. In this case I need to know the field internal name.


public override void ItemAdding(SPItemEventProperties properties)
        {
            string toolTipFieldInternalName = "";
            //oops, this place have some perfomance overhead
            using (SPWeb web = properties.OpenWeb())
            {
                toolTipFieldInternalName = web.Lists[properties.ListId].Fields[toolTipFieldId].InternalName;
 
            }
 
            string urlVal = properties.AfterProperties["URL"].ToString();
            SPFieldUrlValue val = new SPFieldUrlValue(urlVal);
            string desc = val.Description;
            properties.AfterProperties[toolTipFieldInternalName] = desc;
        }

For best experience you may install Visual T4 Editor

There is a simple way to extract and generate usefull constants for field ids and internal names from features definition files in your project with T4 mechanism built-in into visual studio:

Constants.tt (this code works fine only in Visual Studio 2010)

<#@ template inherits="Microsoft.VisualStudio.TextTemplating.VSHost.ModelingTextTransformation" language="C#" debug="true" hostSpecific="true" #>
<#@ assembly name="Microsoft.VisualStudio.TextTemplating.Modeling.10.0.dll"#>

<#@ output extension=".cs" #>
<#@ Assembly Name="System.Core.dll" #>
<#@ Assembly Name="System.Xml.dll" #>
<#@ Assembly Name="System.Xml.Linq.dll" #>
<#@ Assembly Name="System.Windows.Forms.dll" #>
<#@ Assembly Name="EnvDTE" #>
<#@ import namespace="System" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Diagnostics" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Xml.Linq" #>
<#@ import namespace="System.Collections" #>
<#@ import namespace="System.Reflection" #>
<#@ import namespace="System.Collections.Generic" #> 
<#@ import namespace="EnvDTE" #>
<#@ import namespace="Microsoft.VisualStudio.TextTemplating" #>
<# 
var currentDirectory = Path.GetDirectoryName(Host.TemplateFile);
var xmlFiles = Directory.GetFiles(currentDirectory, "*.xml", SearchOption.AllDirectories);
var fieldQualifier = XName.Get("Field", "http://schemas.microsoft.com/sharepoint/");
var listdQualifier = XName.Get("ListInstance", "http://schemas.microsoft.com/sharepoint/");
#>using System;	

namespace <#= System.Runtime.Remoting.Messaging.CallContext.LogicalGetData("NamespaceHint") #>
{
    public static partial class Constants 
    {
        public static class Fields
        {
<#  
		var fields = xmlFiles
					.Select(XDocument.Load)
					.Select(d => d.Descendants(fieldQualifier))
					.SelectMany(x => x)
					.Where(i => i != null)
					.Select(i => new KeyValuePair<string, string>(
							i.Attribute("ID") != null ? i.Attribute("ID").Value : null,
							i.Attribute("Name") != null ? i.Attribute("Name").Value : null))
					.Where(i => !string.IsNullOrEmpty(i.Key) && !string.IsNullOrEmpty(i.Value))
					.Distinct();
            foreach (var field in fields)
            {
			#>
            public static string <#= field.Value #>_InternalName = "<#= field.Value #>";
            public static Guid <#= field.Value #>_Id = new Guid("<#= field.Key #>");
			
<#
			}
		   #>

		}

        public static class Lists
        {
		}
    }
} 

The output file will be like follow:



 
using System;	

namespace MyProjectNameSpace.Project1
{
    public static partial class Constants 
    {
        public static class Fields
        {
            public static string DocKind_InternalName = "DocKind";
            public static Guid DocKind_Id = new Guid("{b4fc3e5e-7573-4e39-9417-81d85f25ed73}");
			
            public static string RegDate_InternalName = "RegDate";
            public static Guid RegDate_Id = new Guid("{e453a0ee-7797-4d90-941c-0ea9a775f48d}");
			
            public static string RegUser_InternalName = "RegUser";
            public static Guid RegUser_Id = new Guid("{616997f5-6cf2-4795-b625-d7b7f4681a2e}");
        }

       public static class Lists
       {
       }
    }
} 
Реклама

Презентации с выступлений на прошлой неделе

На прошлой неделе состоялось 2 очень значимых для меня мероприятия:

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





SharePoint and oData

В SharePoint 2010 многое сделано для открытости доступа к данным, в том числе поддержка oData. Клиентская модель построена поверх этих возможностей.

Для того, чтобы опробовать возможности SharePoint oData в действии вам достаточно вызвать сервис ListData:

http://[serverName]/_vti_bin/ListData.svc

Если в результате получите ошибку 404, то скорее всего у вас не стоит ADO.NET Data Services v1.5 CTP2

Далее можно попробовать воспользоваться Visual Studio

image

В результате получить довольно-таки неоднозначные в связи с локалью богатые возможности:

  class Program
  {
    static void Main(string[] args)
    {
      var context = new ClientDataContext(new Uri("http://localhost/_vti_bin/ListData.svc"));
      context.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
      var результат = context.ДокументыПроекта.Где(x => x.Имя != null).ToList();
    }
  }

  public static class Расширения
  {
    public static IEnumerable<T> Где<T>(this IEnumerable<T> source, Func<T, bool> predicate)
    {
      return source.Where(predicate);
    }
  }

Ну или просто возможность работы из браузера:

image

А так же из Excel, благодаря PowerPivot.


Каких возможностей мне не хватает в SharePoint 2010 BCS

В данной заметке я решил немного поразмышлять о том, чего же мне не хватает в BCS при планировании основных сервисов приложений, руководствуясь стандартными для SharePoint практиками. Большинство из этих ограничений связаны с природой сервисов BCS, а именно тем, что данные не находятся в локальном хранилище, соответственно не могут полностью контролироваться с помощью сервисов SharePoint.

Итак, начнём:

  • Нельзя давать разрешения на отдельные записи во внешнем списке (external list). Наконец-то SharePoint в исполнении 2010ой версии научили корректно использовать Access Control Lists (ACL), однако, по вполне понятным причинам данные возможности не доступны при работе с внешними данными
  • Возможности рабочих процессов не доступны полностью для внешних списков. Казалось бы, всё замечательно и готово для интеграции, однако внешние данные остаются внешними данными, и многие события, необходимые для работы с рабочими процессами недоступны для SharePoint, однако это не исключает использование внешних данных в рабочих процессах, работающих на обычных списках. Об этой проблеме и способах её разрешения довольно-таки подробно описано в статье Using SharePoint workflows with Business Connectivity Services (BCS).
  • Отсутствие версионности и истории изменений во внешних списках. Вполне логично, что внешние списки остаются лишь “обёрткой” для внешних данных и хранить изменения, а следовательно и обеспечивать версионность, довольно-таки неординарная задача, которую команда BCS решила не касаться, по той же причине “элементы социального взаимодействия”, такие как рейтинги и тегирование, так же будут недоступными при работе с внешними данными (BCS).
  • Экспорт в Excel. Очень странно почему данный функционал не доступен, т.к. не накладывает никаких ограничений на используемые данные, а просто меняет их представление. Как альтернативу данному подходу могу предложить что-нибудь наподобие Print List (http://www.sharepoint-tips.com/2007/01/how-to-add-print-list-option-to-list.html), т.е. решения по экспорту внешних данных из SharePoint будут подразумевать кастомизацию.
  • RSS каналы. С одной стороны причины схожи с экспортом в Excel, однако здесь, как мне кажется, противоречие даже со здравым смыслом, т.е. RSS-канал как правило должен отслеживать изменения в данных и оповещать об этом подписчика, в случае с внешними данными, они могут и не меняться, а будет меняться лишь выборка, что будет генерировать многочисленное количество неконтролируемых обновлений.
  • Просмотр в виде таблицы. Очень удобная функция, не понятно, что именно сподвигло на её отсутствие команду разработчиков, скорее всего возможности пакетной обработки в новом интерфейсе SharePoint, которыми она была так удобна.
  • Внешние данные не доступны для доступа через REST сервисы. Как мне кажется причина так же в возможности непрогнозируемого изменения данных произвольным образом, что не даёт никакой гарантии для потребителя данных сервисов.

В заключение

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


SharePoint 2010: Примеры работы с BCS

Введение

Предлагаю рассмотреть несколько примеров работы с SharePoint 2010 Business Connectivity Services.

Все ресурсы, связанные с Business Connectivity Services можно найти на Business Connectivity Services Resource Center. Кстати на нём же можно скачать замечательный постер-шпаргалку по технологии.

image

Для работы с рассматриваемыми примерами предлагаю вам скачать SharePoint 2010 SDK.

Adventure Works Web Service

В данном примере показана реализация стандартного asp.net asmx сервиса, ориентированного на работу с BCS. Этот сервис представляет доступ к данным из SQL Server. С помощью LINQ to SQL реализовано объектно-реляционное преобразование.

Вы наверняка согласитесь с утверждением, что при прочих равных условиях asmx сервисы создаются намного проще WCF сервисов

Для работы с ним понадобится sample database с соответствующим названием “AdventureWorks”.

Примеры баз данных (таких как AdventureWorks) для основных версий SQL Server, а так же решений для них, теперь централизованны и хранятся на CodePlex: http://msftdbprodsamples.codeplex.com/

Сервис WebService.asmx предоставляет ряд методов для стандартных операций взаимодействия с данными (Create, Read, Update, Delete).

Для наглядности предметной области основные сущности определены в виде POCO классов, к примеру:

public class SalesCustomer 
{ 
    public int CustomerId { get; set; } 

    public String Title { get; set; } 
    public String FirstName { get; set; } 
    public String MiddleName { get; set; } 
    public String LastName   { get; set; } 
    public String EmailAddress { get; set; } 
    public String Phone { get; set; } 
    public DateTime ModifiedDate { get; set; } 
}

Классы же, генерируемые LINQ to SQL используются по назначению, т.е. в качестве DataModel, которая в последствии отображается на модель предметной области. Хоть пример и учебный, было очень приятно, что он имеет довольно таки логичное и обоснованное применение технологий по назначению.

Предметная область в данном случае состоит из 3 основных сущностей:

  1. SalesCustomer
  2. SalesOrderDetail
  3. SalesOrderHeader

Причём дизайн данных сущностей ориентирован на работу с BCS, это можно проследить по построению ассоциаций между сущностями не по ссылке, а по идентификатору. К примеру, связь между SalesCostumer и SalesOrderHeader:

public class SalesOrderHeader 
{

    public int CustomerID { get; set; }

    …

}


Здесь стоит пояснить механизм работы с ассоциациями в BCS. Ассоциации в BCS – основной механизм связи нескольких “внешних типов содержимого”. Для его реализации используются так называемые Association Methods. По организации работы принцип вторит тому, что применяется в реляционных базах данных для реализации отношений, т.е. через доступ по внешнему ключу (Foreign Key).

В связи с данными особенностями в сервисе определяются специализированные методы, например этот:

[WebMethod] 
public SalesOrderHeader[] GetOrdersForCustomer(int customerId) 
{ 
    List<SalesOrderHeader> salesOrderHeaders = new List<SalesOrderHeader>(); 
    Adventureworks.SalesOrderHeader[] sohArr = 
        (from soh in dataContext.SalesOrderHeaders 
         where soh.CustomerID == customerId 
         select soh).ToArray(); 
    PopulateSalesOrderHeader(salesOrderHeaders, sohArr); 
    return salesOrderHeaders.ToArray(); 
}

Данные методы в дальнейшем будут привязаны к BCS Associations Methods, которые и будут работать для связанных сущностей.

Представленный веб-сервис следует опубликовать в IIS.

Далее, воспользовавшись SharePoint Designer 2010 создать и опубликовать BDC Model:

  • Открыть в SharePoint Designer 2010 интересующий вас узел
  • Перейти в секцию External Content Types
  • Создать новый “внешний тип содержимого”
  • В качестве источника данных выбрать WCF Service
  • Указать URL подключения и тип соединения
  • С помощью мастера произвести отображение всех необходимых веб-методов на методы BDС Model
  • Сохранить внешний тип содержимого

Данный процесс наглядно описан в SDK http://msdn.microsoft.com/en-us/library/ee556431(office.14).aspx

 

Пример файла, описывающего BDC Model
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Model xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://schemas.microsoft.com/windows/2007/BusinessDataCatalog BDCMetadata.xsd" Name="AdventureWorksWSModel" IsCached="false" xmlns="http://schemas.microsoft.com/windows/2007/BusinessDataCatalog">
   <LobSystems>
    <LobSystem Type="Wcf" Name="AdventureWorksWS">
      <Properties>
        <Property Name="WsdlFetchAuthenticationMode" Type="System.String">PassThrough</Property>
        <Property Name="WcfMexDiscoMode" Type="System.String">Disco</Property>
        <Property Name="WcfMexDocumentUrl" Type="System.String">http://webserver:90/webservice.asmx?wsdl</Property>
        <Property Name="WcfProxyNamespace" Type="System.String">BCSServiceProxy</Property>
        <Property Name="WildcardCharacter" Type="System.String">*</Property>
      </Properties>
      <LobSystemInstances>
        <LobSystemInstance Name="AdventureWorksWS">
          <Properties>
            <Property Name="WcfAuthenticationMode" Type="System.String">PassThrough</Property>
            <Property Name="WcfEndpointAddress" Type="System.String">http://webserver:90/webservice.asmx</Property>
            <Property Name="ShowInSearchUI" Type="System.String"></Property>
          </Properties>
        </LobSystemInstance>
      </LobSystemInstances>
      <Entities>
        <Entity Namespace="AdventureWorks” Version="1.0.0.0" EstimatedInstanceCount="10000" Name="WSCustomer" DefaultDisplayName="WSCustomer">
          <Properties>
            <Property Name="OutlookItemType" Type="System.String">Contact</Property>
          </Properties>
          <Identifiers>
            <Identifier TypeName="System.Int32" Name="CustomerId" />
          </Identifiers>
          <Methods>
            <Method IsStatic="false" Name="GetCustomerById">
              <Parameters>
                <Parameter Direction="In" Name="customerId">
                  <TypeDescriptor TypeName="System.Int32" IdentifierName="CustomerId" Name="customerId" />
                </Parameter>
                <Parameter Direction="Return" Name="GetCustomerById">
                  <TypeDescriptor TypeName="BCSServiceProxy.SalesCustomer, AdventureWorksWS" Name="GetCustomerById">
                    <TypeDescriptors>
                      <TypeDescriptor TypeName="System.Int32" ReadOnly="true" IdentifierName="CustomerId" Name="CustomerId" />
                      <TypeDescriptor TypeName="System.String" Name="Title" />
                      <TypeDescriptor TypeName="System.String" Name="FirstName">
                        <Properties>
                          <Property Name="OfficeProperty" Type="System.String">FirstName</Property>
                        </Properties>
                      </TypeDescriptor>
                      <TypeDescriptor TypeName="System.String" Name="MiddleName" />
                      <TypeDescriptor TypeName="System.String" Name="LastName">
                        <Properties>
                          <Property Name="OfficeProperty" Type="System.String">LastName</Property>
                        </Properties>
                      </TypeDescriptor>
                      <TypeDescriptor TypeName="System.String" Name="EmailAddress" />
                      <TypeDescriptor TypeName="System.String" Name="Phone" />
                      <TypeDescriptor TypeName="System.DateTime" Name="ModifiedDate" />
                    </TypeDescriptors>
                  </TypeDescriptor>
                </Parameter>
              </Parameters>
               <MethodInstances>
                <MethodInstance Type="SpecificFinder" ReturnParameterName="GetCustomerById" Default="true" Name="GetCustomerById" DefaultDisplayName="Read Item WSCustomer">
                 <Properties>
                   <Property Name="LastDesignedOfficeItemType" Type="System.String">Contact</Property>
                 </Properties>
                </MethodInstance>
               </MethodInstances>
            </Method>
          </Methods>
        </Entity>
      </Entities>
    </LobSystem>
  </LobSystems>
</Model>

AdventureWorksDll

Данный пример ориентирован на подключение .NET типа в качестве источника данных для внешнего типа содержимого. Фактически пример не отличается от предыдущего. Принципиальная разница состоит в том, что в данном случае сборка должна находится локально по отношению к установленному SharePoint. Все принципы дизайна методов доступа сохранены.

Кстати, данный пример практически ничем не уступает в поддержке актуальности варианту с веб-сервисом, т.к. современные методы дистрибуции .NET решений (к примеру ClickOnce) позволяют поддерживать в актуальном состоянии решение у большого количества клиентов.

Так что же происходит в BCS при работе с веб-сервисами

Механизм вполне логичен и является стандартным во многих ситуациях. Запрашивается URL, который указан в качестве адреса сервиса. На основе полученной схемы (как правило в SOAP это WSDL). Далее происходит самое интересное, в рантайме генерятся прокси-объекты для доступа к данным. Данные объекты компилируются в памяти и кэшируются для дальнейших вызовов.

Custom Connector

Кроме подключения к .NET типу, так же существует возможность реализации “своего коннектора”. В чём же принципиальная разница? В том, что коннектор является свободной абстракцией над источником данных. Т.е. подразумевается его настройка пользователем, к примеру, в SharePoint Designer’e, в отличии от .NET типа, который будет отражаться на конкретный “внешний тип содержимого”. Подробнее можно узнать здесь: http://msdn.microsoft.com/en-us/library/ee554911(office.14).aspx

BCS Cache

В заключение хочу немного рассказать о способах оптимизации ваших решений на основе BCS.

В BCS существует мощных механизм кэширования. Реализуется он на основе так называемых Cache Description. Описываются они в XML файле subscription.xml и должны располагаться в папке вместе в XML описанием BDC Model. С помощью можно описывать правила кеширования определенных методов, определенных сущностей (по их идентификатору), а так же связанных сущностей.

Так выглядит Cache Description

  <?xml version="1.0" encoding="utf-8"?>
<Subscription xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Name="CustomerQuery Item List" IsCached="true" EntityName="Customer" EntityNamespace="http://example.com" RefreshIntervalInMinutes="60" View="CustomerRead Item" LobSystemInstanceName="AdventureWorks" xmlns="http://schemas.microsoft.com/office/2006/03/BusinessDataCatalog">
  <Queries>
    <Query Name="27aa2ba2-fd5f-452c-87bb-24cf505f6071" IsCached="true" RefreshIntervalInMinutes="60" MethodInstanceName="CustomerQuery Item List" Enabled="false" />
  </Queries>
</Subscription> 

Подробнее о кэшировании можно узнать здесь: http://msdn.microsoft.com/en-us/library/ee556385(office.14).aspx


Может ли .NET Reflector 6 помочь разработчику SharePoint?

Сегодня наконец-то дошли руки до Reflector 6 Pro Beta. Если вы ещё не слышали, то я повторюсь, что эта версия рефлектора умеет дебажить внешние сборки в Visual Studio. Конечно же меня в первую очередь заинтересовала возможность дебага Microsoft.SharePoint.dll

При первом запуске рефлектора, он автоматически установит плагин в студию. Далее с помощью появившегося пункта меню можно подгрузить интересующую сборочку:

image

Microsoft.SharePoint.dll загружался довольно таки приличное количество времени (несколько минут), после чего передо мной была следующая картинка:

image

Далее я выбрал в том же пункте меню Explore Decompiled Assemblies, нашёл в Object Browser класс SPWeb, выбрал в меню Go To Decompiled Definition, подключился к рабочему процессу w3wp с SharePoint и увидел следующее:

image

Считаю, что это очень полезная возможность. Рекомендую приобрести данный продукт, так как он сможет сэкономить большое количество вашего времени.


SharePoint 2010: Безопасность в Business Conectivity Services

Введение

Существует два подхода к аутентификации при работе с внешними источниками данных:

  • идентификатор пользователя
  • имперсонализация

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

Второй тип аутентификации подразумевает под собой наличие специализированной учетной записи, через которую пользователи вашей системы получают данные из внешних источников.

Явным примером двух типов аутентификации может являться работа с SQL Server для развертывания SharePoint.

При наличии у разработчика локально-развернутой копии SharePoint, получение данных происходит через идентификатор текущего пользователя, т.к. разработчик обычно выполняет все действия под единым для SharePoint и SQL Server пользователем.

Однако при варианте развертывания SharePoint на ферме, появляется необходимость имперсонализации пользователя для доступа к данным из SQL Server. Как правило заводится специализированная доменная учетная запись с необходимыми для работы с SQL Server разрешениями. И соответственно, все действия с данными SharePoint производит именно через неё, независимо от того, какой пользователь в данное время аутентифицирован в нём.

Рассмотрим, как же организовать имперсонализацию при работе с внешними источниками данных в SharePoint 2010.

Single Sign-On или Secure Stored Service

Вы наверняка знаете, что такое SSO (single sign-on), и помните, что в предыдущих версиях SharePoint она называлась именно так. В SharePoint 2010 данная служба сменила своё название, теперь она называется Secure Store Service (русский эквивалент: Служба Безопасного Хранения).

Данная служба занимается проверкой подлинности на сервере приложений, если быть точным, то она обеспечивает взаимодействие пользователей/групп пользователей с различными системами без необходимости повторного входа в систему. Основное назначение данной службы в SharePoint – взаимодействие с внешними системами. Если в вашей организации имеются приложения, данные из которых вы хотели бы предоставить для пользователей SharePoint, а так же обеспечить безопасность доступа, то вы должны воспользоваться SSS (Secure Store Service).

При настройке SSS вы указываете отображение данных пользователя SharePoint на данные, передаваемые внешней системе. Данными параметрами могут Имя пользователя, Пароль, Идентификатор пользователя. Набор полей не ограничен и может быть изменен в зависимости от ваших нужд. Для обеспечения взаимодействия с настольными приложениями так же доступны сервисы определения разрешений на основе идентификатора Windows пользователя.

Настройка SSS

Secure Stored Service представляет собой сервис аутентификации на сервере приложений, а так же базу данных, содержащую информацию о разрешениях пользователей. Как и SSO, он поддерживает федеративную аутентификацию, а так же имперсонализацию и делегирование.

На основе хранимых соответствий во время подключения внешних источников данных каждому пользователю назначаются соответствующие

Кстати, в отличии от SSO и BDC, который был доступен только в MOSS, Secure Stored Service и Business Connectivity Services будут доступны и в SharePoint Server 2010 и в SharePoint Fundation 2010

SSS можно включить в SharedServices. По-умолчанию данный сервис отмечен галочкой в мастере настройке фермы, так что велика вероятность того, что у вас он уже установлен.

Создадим Secure Store Application, для этого нам понадобится:

  1. Пройти к Central Administration — Application Management — Manage Service Applications
  2. Перед созданием приложения необходимо так же сгенерировать для него ключик:
  3. Далее вам необходимо будет указать администратора и настройки приложения, а так же отображаемые поля (по-умолчанию они называются Windows User Name, Windows Password, название не несёт в себе никакой нагрузки, кроме описательной, в связи с чем можно переименовать их просто в UserName и Password, чтобы не путаться).
  4. В конце создания укажите разрешения для приложения:

Вот мы и создали приложение для безопасного хранения, зачем же оно нам может понадобиться?

Рассмотрим пример со сторонним приложением, данные которого хранятся в SQL Server, однако по историческим причинам в нём заведены для доступа отдельные учетные записи. Перед вами стоит задача организовать приложение на BCS для доступа к этим данным.

Для этого вам необходимо:

  1. Запустить SharePoint Designer 2010
  2. Перейти к секции External Content Types
  3. Создать новый тип содержимого
  4. В качестве источника данных указать SQL Server
  5. В окне доступа к данным уточнить наименование сервера, наименование базы данных, так же имя для отображения. Так же вам потребуется выбрать способ имперсонализации (в данном случае на основе Windows Identity) и указать идентификатор (его наименование, которое вы указывали при его создании) Secure Store Application

 

Если соединение удастся, то вы всё сделали верно, остальные действия ничем не будут отличаться от стандартных, а так же будут действовать все указанные вами в Secure Store Application правила.

Давайте также разберемся с терминологией SharePoint аутентификации

Users Identity (PassThrough)

Пользователь, прошедший идентификацию обращается к BCS со своим идентификатором. Это обозначает, что Windows идентификатор будет передан напрямую через BCS приложение к IIS, который в свою очередь отправит его на SQL Server (к примеру), где в зависимости от его разрешений будут предоставлены данные.

BDC Identity (RevertToSelf)

Как не трудно догадаться в данном случае доступ к внешнему источнику данных будет осуществляться под идентификатором пользователя пула приложения (под ним выполняются службы BCS). Соответственно вам необходимо предоставить доступ к данным для этой учетной записи.

Impersonated Windows Identity (WindowsCredentials)

Под данным термином и подразумевается SSS аутентификация.

Impersonated Custom Identity

В основном под данным пунктом подразумевается Claims based Federated Authentication. К примеру поддерживающий SAML аккаунты пользователей

SAML (англ. Security Assertion Markup Language — язык разметки подтверждения безопасности) — основанный на языке XML стандарт, разработанный OASIS для обмена данными об аутентификации и авторизации между защищенными доменами. Одной из важных проблем, которую пытается решить SAML это обеспечение сквозной аутентификации (Технология единого входа, Single Sign On) при работе через Web-браузер.

Данный тип аутентификации так же весьма подходит для WCF сервисов, позволяющих передавать резрешения в Secure Token Service.

Если вы будете писать,  к примеру настольное приложение для работы с BCS, то данный вид аутентификации будет вам весьма полезен. Аналогично работают и Office-клиенты (Outlook, SharePoint Workspace). Каждый клиент обращается к Security Token Service на ферме SharePoint, где получает ”доверенный идентификатор”, с которым впоследствии отправляется в BCS.

RdbCredentials

Этот тип аутентификации используется для обработки идентификатора пользователя, полученного из не-Windows среды с помощью SSS.

Разрешения в BCS

Разрешения для BCS можно указывать для пользователей, групп пользователей, а так же запросов на нескольких уровнях. Разрешения доступа к данным хранятся в метаданных BCS, а так же имеют иерархическую структуру.

Напомню, что основными элементами описания в BCS являются:

  • Metadata store – фактически все описания, содержащиеся в BCS
  • Model – описание так называемой BDC Model, может содержать несколько внешних типов содержимого, связи с внешними данными, а так же типаутентификации
  • External system – источник данных (база данных, веб-сервис, .NET сборка)
  • External content type – внешний тип содержимого
  • Method – операция над типом содержимого
  • Method instance – настройка метода, к примеру параметры по-умолчанию

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

В SharePoint BCS существуют 4 типа разрешений:

  1. Edit – практически на всех уровнях иерархии позволяет редактировать элементы, а так же создавать новые
  2. Execute – как правило определяет какие методы могут быть вызваны
  3. Selectable in clients – означает, что пользователь может создавать на основе данного типа содержимого списки
  4. Set permissions – пользователь может указывать разрешения для других пользователей на данном элементе

Так же существуют специализированные группы разрешений для SharePoint:

  • Администртор фермы – привилегированный пользователь BCS, имеет полный набор прав по-умолчанию. Данные полномочия предоставлены для возможности восстановления прав. Однако администратор фермы не имеет прав Execute, пока ему их не предоставит администратор экземпляра BDC
  • Клиенты объектной модели – сюда попадают скриптовые сценарии (PowerShell, IronPython, STSADM Extensions), а так же приложения, написанные на .NET (C#, VB). Они так же имеют полный набор разрешений
  • Пользователи, под которыми запущены пулы приложений на серверах приложений – имеют те же права, что и администраторы ферм, это связанно, с тем, что есть необходимость в разрешениях для установки определений
  • Пользователи SharePoint Designer – имеют, как правило, полный набор прав, за исключением предоставления прав (set permissions), хотя могут убирать права

Редактировать разрешения можно через SharePoint Designer, узел администрирования, редактируя описание BDC Model’и, а так же через объектную модель. Первые два средства соответственно не дают возможностей тонкой настройки.

Материалы

http://www.lightningtools.com/blog/ – блог о SharePoint BDC, BCS от создателей BDC MetaMan и MCS MetaMan

http://technet.microsoft.com/en-us/library/ee681491(office.14).aspx – планирование BCS на Technet