среда, июля 27, 2011

По поводу утечек персональных данных с сайтов.

На мой взгляд все очень просто.
Надо:

  1. Оштрафовать всех владельцев сайтов с которых произошла утечка в пользу людей чья информация оказалась в публичном доступе.
  2. Уволить всех псевдо специалистов имевших отношение к развертыванию информационных систем из которых произошла утечка и их начальников (составить robots.txt крайне просто, а если ты не в курсе что это такое и зачем оно надо ты не тех а ДЕБИЛ
  3. Наконец перестать нанимать студентов с мизерной ЗП на должности где есть ответственность.
З.ы.: ублюдков из мегафона штрафовать в 10кратном размере. Они должны знать 152фз на зубок. Вообще за такой косяк я-бы лишил ЗАО "СОНИК ДУО" лицензии на предоставление услуг.

среда, июля 13, 2011

Все гениальное просто. Смена стиля.

Надоело пестрое разноцветие прошлой темы.
Решил - "Все гениальное просто" и выбрал стандартную темную тему.

Sharepoint 2010 и пустые значения SPFieldLookup и SPFieldLink

Тут недавно обнаружил что если очистить поле Lookup или Ссылка в записи списка. То вместо пустого значения пишется не null а "0;#" для Lookup и "," для Ссылки. А во время создания поле будет задано как null.
Скажу более - данное поведение зависит от браузера. Таким образом в пустом значении этих полей может оказаться как null так и  "0;#"или ",".
Далее привожу пример функции проверки на пустые значения:

public static class NullComparer{
       public bool IsEmptyValue(object value){
              var strval=string.Format("{0}",value).Trim();
              if(value==null ||
                 string.IsNullOrEmpty(strval) ||
                 strval == "," ||
                 strval == "0;") return true;
              return false;
       }
}

вторник, июля 12, 2011

Настройка GZIP для IIS ASP.NET приложений в web.config

Можно включить GZIP сжатие из web.config сайта\приложения. Очень полезно на shared хостингах

<system.webServer>
<httpCompression directory="%SystemDrive%\inetpub\temp\IIS Temporary Compressed Files">
<scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll"/>
<dynamicTypes>
<add mimeType="text/*" enabled="true"/>
<add mimeType="message/*" enabled="true"/>
<add mimeType="application/javascript" enabled="true"/>
<add mimeType="*/*" enabled="false"/>
</dynamicTypes>
<staticTypes>
<add mimeType="text/*" enabled="true"/>
<add mimeType="message/*" enabled="true"/>
<add mimeType="application/javascript" enabled="true"/>
<add mimeType="*/*" enabled="false"/>
</staticTypes>
</httpCompression>
<urlCompression doStaticCompression="true" doDynamicCompression="true"/>
</system.webServer>

Для проверки работы убедитесь в том, что у страниц сайта появился заголовок:
Content-Encoding: gzip

суббота, июля 09, 2011

Кладбищенский сторож.

Чувствую себя сторожем кладбища фильмов. Я постоянно качаю что-нибудь посмотреть и всегда нехватает времени на "посмотреть". При поверхностной проверке диска обнаружилось около 20ГБ фильмов которые я уже вряд-ли посмотрю.

суббота, июня 25, 2011

Новая технологическая демонстрация. SLAR + SL5

Итак. Поигравшись с Balder для Sliverlight 4, я понял - он не справляется с производительностью. Было принято решение перейти на Silverlight 5 XNA. Что дало приличный прирост производительности. Правда все еще не перенесены некоторые ф-ции (залипание объекта, множественные одинаковые теги).
Создана демонстрация концепции интерактивного объекта смешанных реальностей (Визитка\Портфолио).

Новые вопросы:

  1. Правильное положение и дизайн логотипа.
  2. Как правильно активировать объекты портфолио (сами картинки).
  3. Дизайн и носитель карточки.
  4. Возможность дальнейшего уменьшения элементов карточки.

пятница, июня 24, 2011

Вернулись времена коротких путей.

Сегодня при попытке использовать msbuild словил.
Error 14 The specified path, file name, or both are too long. The fully qualified file name must be less than 260 characters, and the directory name must be less than 248 characters. [C:\Users\holinov\Desktop\SRC\Layer1\MRR.DVIZ\trunk\src\Mrr.Dviz.LookupFieldWithPicker \LookupFieldWithPicker\Mrr.Dviz.LookupFieldWithPicker.csproj] C:\Users\holinov\Desktop\SRC\Layer1\MRR.DVIZ\trunk\src\Mrr.Dviz.Deploy\Mrr.Dviz.Setup.DeployAction\> C:\Users\holinov\Desktop\SRC\Layer1\MRR.DVIZ\trunk\src\Mrr.Dviz.LookupFieldWithPicker\ LookupFieldWithPicker\Package\Package.package Mrr.Dviz.Setup.DeployAction
Мда, я думал такие времена уже прошли. Придется искать workaround.

четверг, июня 23, 2011

Качество связи #yota и обновление

Вчера вечером мой Yota-egg решил обновиться. Как водится начал мигать синим огоньком. Минуты через две огонек мигать перестал мигать и просто загорелся. Я подождал мигель десять и понял что ситуация не меняется. Позвонил в тех поддержку йоты, где мне посоветовали его перезагрузить. Сказав спасибо, я положил трубку, но подойдя к яйцу и взяв его в руки, я обнаружил что яйцо не реагирует на нажатия кнопок. Так что я не смог его ни выключить, ни перезагрузить, ни сбросить в заводские настройки. Сегодня днем я отвез яйцо в сервис. Там мне его смогли перезагрузить путем поочередного тыкания в ресет и кнопку включения. Что-ж на этом цирк не окончился. Приехав домой я обнаружил что сеть ловится на несколько секунд и пропадает. Пинг яндекса в течении 40 минут дал около 75% потерь пакетов. По моим сведениям подобное поведение связи наблюдалось не только не моем устройстве.
Вот собственно интересно - что было в том обновлении?

суббота, июня 04, 2011

Серия статей про Augmented Reality. Моя точка зрения.

Начинаю публикацию результатов моих исследовательских работ связанных с концепциями AR (Augmentet reality), NUI (Natural User Interface).
Идея концепции которую я хочу проверить состоит в построении системы пользовательского интерфейса на принципах смешанных реальностей. В теории пользователь, для удовлетворения своих информационных потребностей, должен производить действия не с экранными объектами , а с объектами реального или виртуального-трехмерного миров(реальностей).  Пользователь может воздействовать на объекты виртуального мира посредством воздействия на объекты реального мира (AR-теги), путем относительных перемещений, вращения или внесения новых AR-тегов. А так-же распознания трехмерного положения пользователя относительно виртуальных объектов производимых системой Kinekt или подобной ей.
Для проверки данной концепции были выбраны следующие технологические платформы:

  1. Система смешивания реальностей построена на AR-тегах. ( ARToolkit: Реализация SLARToolkit )
  2. Система 3D визуализации ( Balder , Silverlight 5 XNA ) 

Список опубликованных мною материалов по данному  исследованию: (все видео в статьях)
  1. Первые результаты экспериментов SLARToolkit + Blader + Концепция
  2. Демонстрация концепции интерактивного объекта смешанных реальностей

пятница, июня 03, 2011

SLARToolkit + Balder + Концепция

В последнее время я все чаще стал задумываться на тему создания интерфейсов пользователей взаимодействующих с 3D окружение пользователя. Здесь можно увидеть первые эксперименты на эту тему. Как тех. основа взяты SLARToolkit (ARToolkit для Silverlight), Balder (3d движок полностью реализованный на C# для Silverlight)
Существующие в эксперименте сущности: 
  1. Информационный объект (Тег: SLAR, время жизни 50 циклов распознания, отображается как большой синий куб)
  2. Объект команда (Тег: L, время жизни 5 циклов, отображается маленьким зеленым кубом, выполняет произвольную смену цветов объекта)
  3. Связи команда-объект отображаются зелеными линиями

Часть 1

Часть 2
Выводы:

  1. Распознание AR-тегов  происходит быстро и плавно (при распознании 3х тегов по 16 сегментов на стороне FPS не падало меньше 60).
  2. Качество и стабильность распознания сильно зависят от освещения и деформаций маркеров.
  3. Необходима калибровка камеры для улучшения качества распознания положения маркеров
Вопросы для экспериментов:
  1. Возможно ли распознание цветных паттернов?
  2. Максимальное количество распознаваемых тегов за один раз.
  3. Схемы композиции тегов (для считывания большего количества информации)
  4. Оптимальная размерность тегов (16,32 ... )

Путь развития
  1. Теги разных размеров
  2. Создание удобного движка манипулирования 3D сценой
  3. Отслеживание позиций ушедших с экранов тегов
  4. Разные размеры для тегов объектов и тегов команд (как линейные так и количество сегментов)
  5. Разработать систему команд для воздействия на объекты. (сейчас вижу что-то вроде набора из Переместить, Вращать, Активация, Считать стоку данных)
  6. Вывод изображения через 3D-телевизор для получения эффекта установки 3D-объекта дат AR-тегом непосредственно.
Меркантильные вопросы. Буду благодарен за помощь в разрешении этих вопросов.
  1. Нужна внешняя веб-камера.
  2. Нужна система Kinekt с кабелем питания \ адаптером подключения к ПК
  3. Нужен 3D телевизор для проверки системы отображения

воскресенье, мая 15, 2011

Sharepoint 2010 и русские имена столбов списков

Если вы сталкивались с написанием CAML запросов для Sharepoint 2010 то знаете, что обращение к столбцам с русскими именами достаточно затруднительно т.к. если столбец создавался изначально с русским именем то его внутреннее имя будте представленно закодированным значением. Например если вы назвали свой столбец "Столбец" то его внутренним именем будет : _x0421__x0442__x043e__x043b__x0431__x0435__x0446_.
Я часто сталкиваюсь с такой белибердой и выяснил что это на самом деле HEX значение Unicode символов окруженные и _ . Вооружившись этим знанием я написал две функции для преобразования строки туда и обратно:

public static class NameConverter
    {
        /// <summary>
        /// Расшифровать имя из внутреннего представления
        /// </summary>
        /// <param name="val">Закодированое имя</param>
        /// <returns>Расшифрованое значение</returns>
        public static string DecodeName(string val)
        {
            val = val.Replace("ows", "");
            if (!val.Contains("_x")) return val;

            var sb = new StringBuilder();
            val = val.Replace("_", "");
            var parts = val.Split(new[] { 'x' }, StringSplitOptions.RemoveEmptyEntries);
            foreach (string part in parts)
            {
                int v = int.Parse(part, NumberStyles.HexNumber);
                var c = (char)v;
                sb.Append(c);
            }
            return sb.ToString();
        }
        /// <summary>
        /// Закодировать русскую строку
        /// </summary>
        /// <param name="name">Имя для кодирования</param>
        /// <returns>Закодированое значение</returns>
        public static string EncodeName(string name)
        {
            var sb = new StringBuilder();
            for (int i = 0; i < name.Length; i++)
            {
                sb.AppendFormat("_x{0:x4}_", (int)name[i]);
            }
            return sb.ToString();
        }
    }

суббота, апреля 30, 2011

Удаление элементов из SPList через ProcessBatchData

Всем разработчикам Sharepoint 2010 (да и вообще любой версии Sharepoint или MOSS) известна ситуация с медленной работой объектной модели и большом времени поиска\модификации через нее.
Так вот мне однажды пришлось писать систему массового удаления данных из разных списков сайта под управлением Sharepoint 2010. Решения через SPListItem.Delete(), SPList.Items.DeleteItem(idx) и даже SPList.Items.DeleteItemById(itemId) давали жуткие показатели времени работы (удаление 100 элементов за 60000(!)-120000(!) секунд). И тут я вспомнил про волшебную возможность SPWeb.ProcessBatchData которая позволяет выполнять CAML запросы напрямую, минуя слой объектной модели.( Забегая вперед скажу что такое решение мне дало производительность в районе ~650сек на 5000 записей.)
Что-ж покопав документацию на сайте Microsoft (http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spweb.processbatchdata.aspx) я подумал что все тривиально и создал свое первое решение. Радостно посапывая я ткнул в кнопочку деплой и запустил свой код. Как ни странно код рухнул. Не буду описывать процесс поиска ошибки и сразу скажу: Разбивайте свои запросы на пачки! Не больше 180 запросов в одном теге . Лично я разбиваю свои запросы в пачки по 100.
Поправив код и сделав разбиение на пачки я запустил все снова. Как и ожидалось пепелац не взлетел. А я поимел совершенно смутившую меня ошибку ArgumentException. Тут надо отметить удивительную абсолютную невразумительности сообщений Sharepoint об ошибках.
Вот к примеру как выглядел мой Expcetion
Exception type: ArgumentException
[Message] = "0x80070057"
[ParamName] = ""
[Data] = "System.Collections.ListDictionaryInternal"
[TargetSite] = "Void GetListItemDataWithCallback2(Microsoft.SharePoint.Library.IListItemSqlClient, System.String, System.String, System.String, System.String, Microsoft.SharePoint.Library.SAFEARRAYFLAGS, Microsoft.SharePoint.Library.ISP2DSafeArrayWriter, Microsoft.SharePoint.Library.ISPDataCallback, Microsoft.SharePoint.Library.ISPDataCallback, Microsoft.SharePoint.Library.ISPDataCallback, Microsoft.SharePoint.Library.ISPDataCallback, Microsoft.SharePoint.Library.ISPDataCallback, Boolean ByRef)"
[StackTrace] = "   в Microsoft.SharePoint.Library.SPRequestInternalClass.GetListItemDataWithCallback2(IListItemSqlClient pSqlClient, String bstrUrl, String bstrListName, String bstrViewName, String bstrViewXml, SAFEARRAYFLAGS fSafeArrayFlags, ISP2DSafeArrayWriter pSACallback, ISPDataCallback pPagingCallback, ISPDataCallback pPagingPrevCallback, ISPDataCallback pFilterLinkCallback, ISPDataCallback pSchemaCallback, ISPDataCallback pRowCountCallback, Boolean& pbMaximalView)
   в Microsoft.SharePoint.Library.SPRequest.GetListItemDataWithCallback2(IListItemSqlClient pSqlClient, String bstrUrl, String bstrListName, String bstrViewName, String bstrViewXml, SAFEARRAYFLAGS fSafeArrayFlags, ISP2DSafeArrayWriter pSACallback, ISPDataCallback pPagingCallback, ISPDataCallback pPagingPrevCallback, ISPDataCallback pFilterLinkCallback, ISPDataCallback pSchemaCallback, ISPDataCallback pRowCountCallback, Boolean& pbMaximalView)
   в Microsoft.SharePoint.SPListItemCollection.EnsureListItemsData()
   в Microsoft.SharePoint.SPListItemCollection.GetEnumerator()
   в MRR.DVIZ.Workflows.ClearFormsWorkflow.ClearFormsWorkflow.FindRunning(Object sender, EventArgs e)
   в System.Workflow.ComponentModel.Activity.RaiseEvent(DependencyProperty dependencyEvent, Object sender, EventArgs e)
   в System.Workflow.Activities.CodeActivity.Execute(ActivityExecutionContext executionContext)
   в System.Workflow.ComponentModel.ActivityExecutor`1.Execute(T activity, ActivityExecutionContext executionContext)
   в System.Workflow.ComponentModel.ActivityExecutor`1.Execute(Activity activity, ActivityExecutionContext executionContext)
   в System.Workflow.ComponentModel.ActivityExecutorOperation.Run(IWorkflowCoreRuntime workflowCoreRuntime)
   в System.Workflow.Runtime.Scheduler.Run()"
[HelpLink] = ""
[Source] = ""
Поиски google ничего вразумительного не дали. Правда у меня зародилось смутное сомнение в том что я что-то не так делаю с форматом CAML запроса. Я даже не могу сказать что мена натолкнуло на эту мысль, интуиция если только.
Не буду рассказывать свои танцы вокруг подбора нового формата. скажу лишь что:
<Batch OnError="Continue">

<SetList>b15da36c-6ed8-4fe1-bbcc-89a1996c1dbe</SetList>
<Method ID="1" Cmd="Delete"><Field Name="ID">638</Field></Method>
<Method ID="2" Cmd="Delete"><Field Name="ID">639</Field></Method>
<Method ID="3" Cmd="Delete"><Field Name="ID">648</Field></Method>
<Method ID="4" Cmd="Delete"><Field Name="ID">649</Field></Method>
<Method ID="5" Cmd="Delete"><Field Name="ID">650</Field></Method>
<Method ID="6" Cmd="Delete"><Field Name="ID">651</Field></Method>
<Method ID="7" Cmd="Delete"><Field Name="ID">652</Field></Method>
<Method ID="8" Cmd="Delete"><Field Name="ID">653</Field></Method>
<Method ID="9" Cmd="Delete"><Field Name="ID">654</Field></Method>
<Method ID="10" Cmd="Delete"><Field Name="ID">655</Field></Method>
<Method ID="11" Cmd="Delete"><Field Name="ID">656</Field></Method>
<Method ID="12" Cmd="Delete"><Field Name="ID">657</Field></Method>

</Batch>
не красиво но не правильно. Надо:
<?xml version="1.0" encoding="UTF-8"?>

<Batch OnError="Return">
<Method ID="1,Del"><SetList 
Scope="Request">465ebd0a-d6d4-4736-81d7-27cac86e8952</SetList> <SetVar 
Name="ID">20</SetVar><SetVar Name="Cmd">Delete</SetVar></Method>
<Method ID="2,Del"> <SetList 
Scope="Request">465ebd0a-d6d4-4736-81d7-27cac86e8952</SetList> <SetVar 
Name="ID">21</SetVar><SetVar Name="Cmd">Delete</SetVar></Method>
<Method ID="3,Del"> <SetList 
Scope="Request">465ebd0a-d6d4-4736-81d7-27cac86e8952</SetList> <SetVar 
Name="ID">22</SetVar><SetVar Name="Cmd">Delete</SetVar></Method>
<Method ID="4,Del"> <SetList 
Scope="Request">465ebd0a-d6d4-4736-81d7-27cac86e8952</SetList> <SetVar 
Name="ID">23</SetVar><SetVar Name="Cmd">Delete</SetVar></Method>
<Method ID="5,Del"> <SetList 
Scope="Request">465ebd0a-d6d4-4736-81d7-27cac86e8952</SetList> <SetVar 
Name="ID">24</SetVar><SetVar Name="Cmd">Delete</SetVar></Method>
<Method ID="6,Del"> <SetList 
Scope="Request">465ebd0a-d6d4-4736-81d7-27cac86e8952</SetList> <SetVar 
Name="ID">25</SetVar><SetVar Name="Cmd">Delete</SetVar></Method>
<Method ID="7,Del"> <SetList 
Scope="Request">465ebd0a-d6d4-4736-81d7-27cac86e8952</SetList> <SetVar 
Name="ID">26</SetVar><SetVar Name="Cmd">Delete</SetVar></Method>
<Method ID="8,Del"> <SetList 
Scope="Request">465ebd0a-d6d4-4736-81d7-27cac86e8952</SetList> <SetVar 
Name="ID">27</SetVar><SetVar Name="Cmd">Delete</SetVar></Method>
<Method ID="9,Del"> <SetList 
Scope="Request">465ebd0a-d6d4-4736-81d7-27cac86e8952</SetList> <SetVar 
Name="ID">28</SetVar><SetVar Name="Cmd">Delete</SetVar></Method>
<Method ID="10,Del"> <SetList 
Scope="Request">465ebd0a-d6d4-4736-81d7-27cac86e8952</SetList> <SetVar 
Name="ID">29</SetVar><SetVar Name="Cmd">Delete</SetVar></Method>
<Method ID="11,Del"> <SetList 
Scope="Request">465ebd0a-d6d4-4736-81d7-27cac86e8952</SetList> <SetVar 
Name="ID">30</SetVar><SetVar Name="Cmd">Delete</SetVar></Method>
<Method ID="12,Del"> <SetList 
Scope="Request">465ebd0a-d6d4-4736-81d7-27cac86e8952</SetList> <SetVar 
Name="ID">31</SetVar><SetVar Name="Cmd">Delete</SetVar></Method>

</Batch>
Код создающий такую структуру и выполняющие его в пачках (listMods - IEnumerable с ИД строк для уделания):
List<string> listBatch = new List();

StringBuilder batch = new StringBuilder();
StringBuilder log = new StringBuilder();

if (!string.IsNullOrEmpty(listTitle) && listMods != null && listMods.Count > 0)
{
    log.AppendFormat("Очистка списка {0}. Удалеине {1} элементов.", listTitle, listMods.Count);
    batch.AppendLine("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
    batch.AppendLine("<Batch OnError=\"Return\">");
    int batchSize = 0;
    foreach (int toDelete in listMods)
    {
        batchSize++;
        batch.AppendFormat(
            "<Method ID=\"{0},Del\"> {2} <SetVar Name=\"ID\">{1}</SetVar><SetVar Name=\"Cmd\">Delete</SetVar></Method>",
            batchSize, toDelete,
            string.Format("<SetList Scope=\"Request\">{0}</SetList>",
                            queryRoot.Lists[listTitle].ID))
            .AppendLine();

        if (batchSize >= 100)
        {
            batch.AppendLine("</Batch>");
            listBatch.Add(batch.ToString());
            batchSize = 0;

            batch = new StringBuilder(batch.Capacity);
            batch.AppendLine("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
            batch.AppendLine("<Batch OnError=\"Return\">");
        }
    }
    batch.AppendLine("</Batch>");
    listBatch.Add(batch.ToString());


    foreach (string cmd in listBatch)
    {
        try
        {
            log.Append("Исполнение запроса :").AppendLine().Append(cmd).AppendLine();
            string cmd1 = cmd;
            SPSite siteColl = currentSite;
            SPWeb site = currentWeb;
            SPSecurity.RunWithElevatedPrivileges(delegate()
                                                        {
                                                            using (
                                                                SPSite ElevatedsiteColl =
                                                                    new SPSite(siteColl.ID))
                                                            {
                                                                using (
                                                                    SPWeb ElevatedWeb =
                                                                        ElevatedsiteColl.OpenWeb(
                                                                            site.ID))
                                                                {
                                                                    ElevatedWeb.ProcessBatchData(cmd1);
                                                                }
                                                            }
                                                        });                                
        }
        catch (Exception e)
        {
            var ex = new ApplicationException("Ошибка при исполнении комманды: " + cmd, e);
            throw ex;
        }
    }
}

среда, апреля 20, 2011

Chrome\Firefox + Silverlight + CSS Styles

Если вы на своей странице используете silverlight и попытаетесь изменить значение атрибута стиля position то Chrome\Firefox заново создадут и загрузят ваше приложение.
Обойти это не получилось.

четверг, апреля 07, 2011

Настройка приложения Sharepoint 2010 для авторизации форм (FBA) с хранением данных в SQLServer

Для настройки приложения Sharepoint 2010 для работы с авторизацией форм FBA (forms based authentication) важно знать что приложение должно быть настроено для работы через Claims Based Authentication.

Самый простой вариант - при создании приложения указать Claims based [Авторизация на утверждениях] (по умолчанию приложение создается в режиме Basic authentication).
Если-же у вас уже имеется приложение для которого надо включить FBA вам придется конвертировать приложение. Сложного в этом ничего нет, но стоит помнить что конвертация НЕОБРАТИМА. 
Для конвертации приложения из Basic в Claims based вам необходимо открыть Powershell для Sharepoint 2010 с правами администратора и там выполнить команды:

$app=Get-SPWebApplication("http://site") 
$app.UseClaimsAuthentication = 1 
$app.Update() 
$app.ProvisionGlobally()

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


c:\Windows\Microsoft.NET\Framework64\v2.0.50727\aspnet_regsql.exe

В своем случае я указал имя БД SharepointAuthDB, и учетные данные пользователя от которого у меня работает Sharepoint для простоты настройки администратором домена/сервера, а так-же из-за стойкой неприязни к хранению имени пользователя и пароля доступа в строке подключения.  Для создания строки подключения нам надо запомнить имя сервера, имя БД, и способ авторизации пользователя.

Далее открываем Управление службами IIS и в настройках сервера  нажимаем на ConnectionStrings(Строки подключения) и там нажимаем на "Создать". В открывшемся диалоге вводим имя сервера,имя БД (SharepointAuthDB в моем случае) и способ авторизации пользователя которые вы указывали в мастере регистрации. Так-же необходимо проверить что данный пользователь имеет права dbo и public на базу с пользователями. Так-же вам надо указать имя строки подключения (я указал SqlAuthConnection) и запомнить его.

Далее нам необходимо модифицировать 3 файла web.config

  1. Web.config от приложения Sharepoint которые вы настраиваете для авторизации форм Обычно он расположен по адресу: C:\inetpub\wwwroot\wss\VirtualDirectories\80 (можно посмотреть в настройках узла)

        <roleManager defaultProvider="c" enabled="true" cacheRolesInCookie="false">
          <providers>
            <add name="c" type="Microsoft.SharePoint.Administration.Claims.SPClaimsAuthRoleProvider, Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
            <add connectionStringName="SharepointAuthDB" applicationName="/" description="Stores and retrieves roles from SQL Server" name="FBARole" type="System.Web.Security.SqlRoleProvider, System.Web, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
          </providers>
        </roleManager>
        <membership defaultProvider="i">
          <providers>
            <add name="i" type="Microsoft.SharePoint.Administration.Claims.SPClaimsAuthMembershipProvider, Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
            <add connectionStringName="SharepointAuthDB" passwordAttemptWindow="5" enablePasswordRetrieval="false" enablePasswordReset="false" requiresQuestionAndAnswer="true" applicationName="/" requiresUniqueEmail="true" passwordFormat="Hashed" description="Stores and Retrieves membership data from SQL Server" name="FBA" type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
          </providers>
        </membership>
  2. Файл web.config от SharePoint Central Administration Обычно он расположен по адресу: C:\inetpub\wwwroot\wss\VirtualDirectories\26719 (можно посмотреть в настройках узла)
    В этом файле после тега </SafeControls> добавить секцию
    <PeoplePickerWildcards>
    <clear />
    <add key="AspNetSqlMembershipProvider" value="%" />
    <add key="FBA" value="%" />
    <add key="LdapMembershipProvider" value="*"/>
    <add key="LdapRoleManager" value="*"/>
    </PeoplePickerWildcards>

    и перед тегом </system.web> добавить секцию:
    <roleManager defaultProvider="AspNetWindowsTokenRoleProvider" enabled="true" cacheRolesInCookie="false">
    <providers>
    <add connectionStringName="SharepointAuthDB" applicationName="/" description="Stores and retrieves roles from SQL Server" name="FBARole" type="System.Web.Security.SqlRoleProvider, System.Web, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
    </providers>
    </roleManager>
    <membership defaultProvider="FBA">
    <providers>
    <add connectionStringName="SharepointAuthDB" passwordAttemptWindow="5" enablePasswordRetrieval="false" enablePasswordReset="false" requiresQuestionAndAnswer="true" applicationName="/" requiresUniqueEmail="true" passwordFormat="Hashed" description="Stores and Retrieves membership data from SQL Server" name="FBA" type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
    </providers>
    </membership>


  3. Файл web.config от Sharepoint Security Token Service (STS)Обычно он расположен по адресу: C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\WebServices\SecurityToken В этот файл необходимо добавить секцию:


    <system.web>

    <roleManager defaultProvider="c" enabled="true" cacheRolesInCookie="false">

    <providers>

    <add name="c" type="Microsoft.SharePoint.Administration.Claims.SPClaimsAuthRoleProvider, Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />

    <add connectionStringName="SharepointAuthDB" applicationName="/" description="Stores and retrieves roles from SQL Server" name="FBARole" type="System.Web.Security.SqlRoleProvider, System.Web, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />

    </providers>

    </roleManager>



    <membership defaultProvider="i">
    <providers>
    <add name="i" type="Microsoft.SharePoint.Administration.Claims.SPClaimsAuthMembershipProvider, Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
    <add connectionStringName="SharepointAuthDB" passwordAttemptWindow="5" enablePasswordRetrieval="false" enablePasswordReset="false" requiresQuestionAndAnswer="true" applicationName="/" requiresUniqueEmail="true" passwordFormat="Hashed" description="Stores and Retrieves membership data from SQL Server" name="FBA" type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
    </providers>
    </membership>
    </system.web>
Далее необходимо открыть приложение Sharepoint Central Administration  и нам в настройках приложения нажать "Поставщики проверки безопасности", выбрать необходимую зону и в настройках зоны включить галочку "Разрешить проверку подлинности на основе форм (FBA)".

Далее в поле "Имя поставщика контроля членства в ASP.NET" (membership provider) задать FBA , а в поле "Имя поставщика контроля членства в ASP.NET" (role provider) задать FBARole (если вы не меняли имя поставщиков в XML а указали как я написал). А так-же проверить что разрешен анонимный доступ (для обеспечения работоспособности сервиcов Sharepoint)

Нам осталось совсем немного. Для проверки корректности работы авторизации форм надо создать пользователей в базе данных. (ВНИМАНИЕ из-за особенностей настройки Membreship

Providers для Sharepoint 2010 управлять пользователями через стандартную оснастку IIS не получится, я могу посоветовать написать свой менеджер пользователей или воспользоваться программой MembershipSeeder)

Теперь осталось перезапустить IIS. Зайдти в Sharepoint Central Admin и в настройках приложения задать политику доступа для пользователей FBA.


Обрушение потолка в "Москва сити"


Сегодня 7 апреля 2010 гола приблизительно в 09:10 утра произошло обрушение потолка вестибюля выхода со станции метро "Выставочная". В данном вестибюле так-же расположен вход в открывшийся две недели назад торговый цента Амфи Сити Молл расположенный на территории бизнес комплекса Москва-Сити. Во время обрушения в вестибюле станции было достаточно много людей, лишь по счастливой случайности никто не пострадал. Из дырки образовавшейся на месте пролома тут-же начала теч вода (лужу отчетливо видно на фотографиях).




среда, апреля 06, 2011

Sharepoint 2010 и исключение file not found exception

Маленький совет: Если вы пишите приложение использующее объектную модель Sharepoint и при попытке открыть сайт как в примере:
using(SPSite sirte=new SPSite("http://site"){
......
}
И получаете исключение File not fount exception хотя сайт в браузере открывается - проверьте две вещи:

  1. Build platform для проекта должен быть .NET Framework 3.5
  2. Проект обязательно собираться для x64 платформы