вторник, 31 августа 2010 г.

SharePoint 2010: How to show list from sub site

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

К моему удивлению оказалось что средствами SharePoint сделать такое нельзя, но это можно сделать используя SharePoint Designer 2010.

Для этого идем на тот сайт, где находится наш блог и добавляем туда вебпарт с нашим блогом. Потом вырезаем из aspx определение нашего вепарта и вставляем его уже на aspx главной страницы. Надо только дописать параметр WebID с ID сайта на котором лежит наш блог.

Должно получится что то типа этого:

<WebPartPages:XsltListViewWebPart runat="server" IsIncluded="True" GhostedXslLink="main.xsl" FrameType="None" NoDefaultStyle="TRUE" ViewFlag="8" Title="Posts" PageType="PAGE_NORMALVIEW" ListName="{946CA9B7-6667-4640-9CAE-7645F7A305B6}" Default="FALSE" DisplayName="Posts" WebId="{46b924b2-7eb1-4834-8882-5b786eda5598}"

четверг, 12 августа 2010 г.

SharePoint 2010 BDC: Simple external lists

Поглядел появившийся в SP 2010 Business Data Connectivity Service. Мне понравилось , все очень просто и легко работает.

Например, есть у меня на SQL вот такая вот табличка :

CREATE TABLE [dbo].[My_Names](
        [ID] [uniqueidentifier] NOT NULL,
        [Started] [bit] NOT NULL,
        [Name] [nvarchar](400) NOT NULL,
        [Description] [nvarchar](1750) NOT NULL,
        ) ON [PRIMARY]

Содержащая имена:

И хочу я отобразить все это богатство на SP 2010 в виде листа.

Берем SharePoint Designer 2010 , подключаемся нашему сайту и создаем новый "External Content Type" , и две операции для чтения листа и чтения записей.


После чего создаем "External List"


Пытаемся поити на сайт, чтобы посмотреть что вышло, и с высокой вероятностью видим "Access denied by Business Data Connectivity.". Чтобы это решить идем и даем права для BDC на этот контентный тип.

Идем снова ,и наслаждаемся результатом.


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

Так же вы можете увидеть ошибку о том что BDC не смог подключиться к SQL , в этом случае в настройках контентного типа надо поменять "Authentication Mode" на "BDC Identity".
Если же SharePoint 2010 выдаст ошибку "The metadata object that has Name 'yourName' has a Property with name 'AuthenticationMode' and value 'RevertToSelf'", то надо разрешить эту фичу

В итоге с помощью BDC достаточно просто добавить любые внешние данные в SharePoint и позволить с ними работать используя единый интерфейс.

понедельник, 9 августа 2010 г.

SharePoint: How to use Content migration API for indexing contents

Потребовалось пройти по всей иерархии объектов SharePoint, можно это было сделать через рекурсивный проход по SPWeb , и циклы по SPList и SPListItem, но мне показалось это весьма сложным, не очень интересным и весьма медленным. Кроме того, такой подход, делает крайне сложной реализацию поиска изменении.

SharePoint 2007 и 2010, содержат специальный Content Migration API, который умеет экспортировать данные из SharePoint, на файловую систему, и может инкрементально доставать изменения.

К сожалению этот API не позволяет вместо экспорта объектов на файловую систему, сделать с объектами что то свое. Покопавшись немного в Reflector я пришел к вот такой реализации энумерации объектов используя этот самый API.

static private string exportData(string srcRootUrl, string exportFileLocation, string exportChangeToken)
{
 SPExportObject eobj = new SPExportObject();
 eobj.Url = srcRootUrl;
 eobj.Type = SPDeploymentObjectType.Web;
 
 var expset = new SPExportSettings();

 expset.ExportMethod = string.IsNullOrEmpty(exportChangeToken) ? SPExportMethodType.ExportAll : SPExportMethodType.ExportChanges;
 expset.SiteUrl = srcRootUrl;
 expset.FileLocation = exportFileLocation;
 expset.OverwriteExistingDataFile = true;
 expset.FileCompression = false;
 expset.AutoGenerateDataFileName = false;
 if (!string.IsNullOrEmpty(exportChangeToken))
  expset.ExportChangeToken = exportChangeToken;
 
 expset.ExportObjects.Add(eobj);

 var export = new SPExport(expset);

 typeof(SPExport).InvokeMember("InitializeExport", BindingFlags.Default | BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.NonPublic,
    null, export, null);


 Console.WriteLine("Change token: {0}", export.Settings.CurrentChangeToken);

 var lastChangeToken = export.Settings.CurrentChangeToken;

 typeof(SPExport).InvokeMember("CalculateObjectsToExport", BindingFlags.Default | BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.NonPublic,
    null, export, null);

 PropertyInfo ObjectTotalProp = typeof(SPExport).GetProperty("ObjectsTotal", BindingFlags.Default | BindingFlags.Instance | BindingFlags.NonPublic);
 var total = (int)ObjectTotalProp.GetValue(export, null);
 Console.WriteLine("Total objects to migrate: {0}", total);

 PropertyInfo ObjectManagerProp = typeof(SPExport).GetProperty("ObjectManager", BindingFlags.Default | BindingFlags.Instance | BindingFlags.NonPublic);
 var ObjectManager = (IEnumerable)ObjectManagerProp.GetValue(export, null);

 var DeploymentObjectType = typeof(SPExport).Assembly.GetType("Microsoft.SharePoint.Deployment.ExportObject", true);
 var DeploymentObjectUrlProp = DeploymentObjectType.GetProperty("Url", BindingFlags.Default | BindingFlags.Instance | BindingFlags.Public);
 var DeploymentObjectTypeProp = DeploymentObjectType.GetProperty("Type", BindingFlags.Default | BindingFlags.Instance | BindingFlags.Public);
 var DeploymentObjectSPObjectProp = DeploymentObjectType.GetProperty("SPObject", BindingFlags.Default | BindingFlags.Instance | BindingFlags.Public);
 var DeploymentObjectObjectInfoProp = DeploymentObjectType.GetProperty("ObjectInfo", BindingFlags.Default | BindingFlags.Instance | BindingFlags.Public);
 var DeploymentObjectParentWebIdProp = DeploymentObjectType.GetProperty("ParentWebId", BindingFlags.Default | BindingFlags.Instance | BindingFlags.Public);
 var DeploymentObjectIdProp = DeploymentObjectType.GetProperty("Id", BindingFlags.Default | BindingFlags.Instance | BindingFlags.Public);

 foreach (object obj in ObjectManager)
 {
  var url = (string)DeploymentObjectUrlProp.GetValue(obj, null);
  var type = (Type)DeploymentObjectTypeProp.GetValue(obj, null);
  var spobj = DeploymentObjectSPObjectProp.GetValue(obj, null);
  var expobj = (SPExportObject)DeploymentObjectObjectInfoProp.GetValue(obj, null);
  var spObjId = (Guid)DeploymentObjectIdProp.GetValue(obj, null);
  var parentWebId = (Guid)DeploymentObjectParentWebIdProp.GetValue(obj, null);

  
  Console.WriteLine("--- object with type '{1}' from url='{0}' Id='{2}' parentWebId='{3}' spObject='{4}'", url, type, spObjId, parentWebId, spobj);
  
  // add your code here
 }

 return lastChangeToken;
}

Использовать можно так - выдаст сначала все объекты, а потом будет отдавать изменения :

var srcRootUrl = @"http://server/MySite";
var exportFileLocation = @"C:\ExportFolder";
string lastChangeToken = "";
while (true)
{
 Thread.Sleep(1000);
 Console.WriteLine("Export start with token '{0}'", lastChangeToken);

 lastChangeToken = exportData(srcRootUrl, exportFileLocation, lastChangeToken);
}

Из артефактов осталась необходимость в фолдере на фаиловой системе куда сохраняется пустой файл "ExportSettings.xml"

пятница, 6 августа 2010 г.

Книга: "Управление проектами стандарты методы опыт"

Дали мне тут почитать книжечку "Управление проектами стандарты методы опыт" авторы А.С.Товб,Г.Л.Ципес издательство "Олимп-Бизнес" Москва 2003.

Прочитал, и попробовал вынести ряд тезисов, которые меня в этой книжке привлекли:


  1. Проект - ограниченное во времени предприятие с установленными целями, достижение которых определяет его завершение.
  2. Фазы проекта - инициация, планирование, выполнение, контроль, завершение.
  3. Главной целью стандартов систем управления является сообщество профессионалов имеющих унифицированный профессиональный язык и общую управленческую структуру.
  4. Наибольшее распространение получили PMP IPMA и PMP PMI.
  5. Устав проекта - это план, содержащий scope, milestones, бюджет, сроки ...
  6. На проектно-ориентированных предприятиях смысл деятельности начальника подразделения - продать своих подчиненных в проекты.
  7. При работе с персоналом - начальник подразделения отвечает за дисциплину, прием, увольнение, методологии, инструментарии, авторский надзор. Начальник проекта за оценку работы, проектирование, разработку.
  8. Проектные процедуры (формальности) не должны занимать у сотрудника более одного часа в неделю.
  9. Сильная матрица характеризуется тем, что все руководители проектов состоят в одном отделе и выделяются на проект.
  10. Руководитель проекта помимо ответственности имеет полномочия распоряжаться бюджетом и временем участников, пусть и в некоторых рамках.
  11. Трудовой ресурс - это наиболее сложно планируемый, контролируемый и учитываемый вид ресурсов, особенно в компаниях с квалифицированным персоналом.
  12. Основной принцип мотивации то, что поощрение или взыскание должны накладываться только за то, что находится под контролем сотрудника.
  13. Если от руководителя проекта или технического лидера не зависит прибыль, то премировать их надо исходя из экономии затрат которую они произвели.
  14. Подход по обеспечению качества проектов является затратным, но единственным для компаний завершающих путь от кооператива, где все осознают себя личностями в команде друзей-единомышленников, к корпорации, где необходимо определять роль и функции сотрудников в соответствии с корпоративной иерархией.
  15. Внедрение проектных методов управления существенным образом влияет на организацию бизнеса и, как правило, приводит к изменениям в организационной структуре предприятия.


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