вторник, 5 июля 2011 г.

Sharepoint 2010 and UserProfileManager from console app

Добрый день!
Когда вы работаете с консольного приложения и получаете ошибку (Object reference not set to an instance of an object) при таком коде:
UserProfileManager profileManager = new UserProfileManager(contect);

Нужно сделать следующее:
  1. Open the SharePoint 2010 Central Administration page, and then click Manage Service Applications.
  2. Select the row for the User Profile Service application. Instead of clicking the name, select the row to highlight it.
  3. On the Service Applications tab, click Permissions.
  4. In the Connection Permissions for User Profile Service Application dialog box, add the user or group that needs permission to run impersonation applications. After you click Add, and the user name shows in the list of claims, select the added user in the list and then select the Full Control check box. Otherwise, the user is not added when you click OK. Full Control is the only option.
  5. To ensure that the user or group is added, reopen the Connection Permissions for User Profile Service Application dialog box and confirm that the new user or group displays in the list of claims. 
Ссылка на  оригинал статьи:  
 http://ctp.social.technet.microsoft.com/Forums/en-NZ/sharepoint2010programming/thread/09ca1621-1c26-4208-ab62-7bf52df14e23

Экспорт SPList in Excel

Поговорим о экспoрте листа в Excel, и сохранения его в библиотеке документов.
Очень часто возникает необходимость экспортировать не весь список в excel а только некую его часть. Я покажу пример того, как быстро и удобно построить такой экспорт. Использовать мы будем решение которое базируется на создании простого xml:
XmlDocument _report;
            StringBuilder file_content = new StringBuilder();
            file_content.Append(@"<?xml version='1.0'?>
                <?mso-application progid='Excel.Sheet'?>
                <Workbook xmlns='urn:schemas-microsoft-com:office:spreadsheet'
                 xmlns:o='urn:schemas-microsoft-com:office:office'
                 xmlns:x='urn:schemas-microsoft-com:office:excel'
                 xmlns:ss='urn:schemas-microsoft-com:office:spreadsheet'
                 xmlns:html='http://www.w3.org/TR/REC-html40'>
                 <DocumentProperties xmlns='urn:schemas-microsoft-com:office:office'>
                  <Author>PIB</Author>
                  <LastAuthor>PIB</LastAuthor>
                  <LastPrinted>2009-09-15T12:46:54Z</LastPrinted>
                  <Created>2004-05-05T13:41:40Z</Created>
                  <LastSaved>2010-01-18T12:59:49Z</LastSaved>
                  <Company>PIB</Company>
                  <Version>1.00</Version>
                 </DocumentProperties>
                 <OfficeDocumentSettings xmlns='urn:schemas-microsoft-com:office:office'>
                  <AllowPNG/>
                 </OfficeDocumentSettings>
                 <ExcelWorkbook xmlns='urn:schemas-microsoft-com:office:excel'>
                  <SupBook>
                   <Path>Sheet2</Path>
                   <SheetName>Sheet2</SheetName>
                  </SupBook>
                  <WindowHeight>6450</WindowHeight>
                  <WindowWidth>9720</WindowWidth>
                  <WindowTopX>-15</WindowTopX>
                  <WindowTopY>-15</WindowTopY>
                  <TabRatio>831</TabRatio>
                  <PrecisionAsDisplayed/>
                  <DoNotSaveLinkValues/>
                  <ProtectStructure>False</ProtectStructure>
                  <ProtectWindows>False</ProtectWindows>
                 </ExcelWorkbook>
                 <Styles>
                  <Style ss:ID='Default' ss:Name='Normal'>
                   <Alignment ss:Vertical='Bottom'/>
                   <Borders/>
                   <Font ss:FontName='Arial Cyr' x:CharSet='204'/>
                   <Interior/>
                   <NumberFormat ss:Format='_(* #,##0_);_(* \(#,##0.00\);_(* ??_);_(@_)'/>
                   <Protection/>
                  </Style>
                  <Style ss:ID='s62'>
                  <Alignment ss:Vertical='Bottom' ss:WrapText='1'/>
                  <NumberFormat ss:Format='@'/>
                  </Style>
                 </Styles>
                <Worksheet ss:Name='Рабочий лист");
 Дальше объявляем поля:
file_content.Append(@"'>
                                 <Names>
                                   <NamedRange ss:Name='spp10test_akhz_bp_vw_day_real_plan_all'
                                    ss:RefersTo='=Sheet2!R1C1:R31465C8'/>
                                  </Names>
                              <Table ss:ExpandedColumnCount='14'>
                               <Column ss:Width='20'/>
                               <Column ss:Width='80'/>
                               <Column ss:Width='150'/>
                               <Column ss:Width='250'/>
                               <Column ss:Width='100'/>
                               <Column ss:Width='50'/>
                               <Column ss:Width='152'/>
                               <Column ss:Width='100'/>
                               <Column ss:Width='122'/>
                               <Column ss:Width='122'/>
                               <Column ss:Width='180'/>
                               <Column ss:Width='100'/>
                               <Column ss:Width='102'/>
                               <Column ss:Width='140'/>
                               <Row>");
Вносим название колонок из массива:
public static string[] Workshops = new string[] {
            "№ п/п",
            "Дата и время",
            "Тема жалобы",
            "Описание жалобы",
            "Регион",
            "Город",
            "Ф.И.О. Клиента",
            "Телефон клиента",
            "Зарегистрировал",
            "Исполнитель",
            "Результат решения",
            "Дата, время обратной связи",
            "Примечания",
            "Статус обращения" 
        };
 Добавляем поля:
foreach(string name in Workshops)
            {
                file_content.Append(@"<Cell><Data ss:Type='String'>" +name + @"</Data></Cell>");
            }
             file_content.Append(@"</Row>");Дальше я написал фильтер по дате для выбору данных из input
 start_date = Microsoft.SharePoint.Utilities.SPUtility.CreateISO8601DateTimeFromSystemDateTime(DateTime.ParseExact(Hidden_start_date.Value.ToString(), "dd.MM.yyyy", CultureInfo.InvariantCulture));
                end_date = Microsoft.SharePoint.Utilities.SPUtility.CreateISO8601DateTimeFromSystemDateTime(DateTime.ParseExact(Hidden_end_date.Value.ToString(), "dd.MM.yyyy", CultureInfo.InvariantCulture));
         
и сам запрос к листу:
SPQuery query = new SPQuery();
            query.Query = "<Where><And><Geq><FieldRef Name='CallbackDate' /><Value  Type='DateTime'>" + start_date + "</Value></Geq><Leq><FieldRef Name='CallbackDate' /><Value Type='DateTime'>" + end_date + "</Value></Leq></And></Where>";
            SPListItemCollection items = data_List.GetItems(query);
Теперь заполняем ячейки данными:
foreach (SPListItem item in items)
            {
                file_content.Append(@"<Row><Cell><Data ss:Type='String'>");
                file_content.Append(Get_String_From_Obj(item[Workshops[0]]));
                file_content.Append(@"</Data></Cell><Cell><Data ss:Type='String'>");
                file_content.Append(Get_String_From_Obj(item[Workshops[1]]));
                file_content.Append(@"</Data></Cell><Cell><Data ss:Type='String'>");
                file_content.Append(Get_String_From_Obj(item[Workshops[2]]));
                file_content.Append(@"</Data></Cell><Cell ss:StyleID='s62'><Data ss:Type='String'>");
                file_content.Append(Get_String_From_Obj(item[Workshops[3]]));
                file_content.Append(@"</Data></Cell><Cell><Data ss:Type='String'>");
                file_content.Append(Get_String_From_Obj(item[Workshops[4]]));
                file_content.Append(@"</Data></Cell><Cell><Data ss:Type='String'>");
                file_content.Append(Get_String_From_Obj(item[Workshops[5]]));
                file_content.Append(@"</Data></Cell><Cell><Data ss:Type='String' >");
                file_content.Append(Get_String_From_Obj(item[Workshops[6]]));
                file_content.Append(@"</Data></Cell><Cell><Data ss:Type='String'>");
                file_content.Append(Get_String_From_Obj(item[Workshops[7]]));
                file_content.Append(@"</Data></Cell><Cell><Data ss:Type='String'>");
                file_content.Append(getUser(new SPFieldUserValue(web, Get_String_From_Obj(item["Author"]))));
                file_content.Append(@"</Data></Cell><Cell><Data ss:Type='String'>");
                file_content.Append(getUser(new SPFieldUserValue(web,Get_String_From_Obj(item[Workshops[9]]))));
                file_content.Append(@"</Data></Cell><Cell ss:StyleID='s62'><Data ss:Type='String'>");
                file_content.Append(Get_String_From_Obj(item[Workshops[10]]));
                file_content.Append(@"</Data></Cell><Cell><Data ss:Type='String'>");
                file_content.Append(Get_String_From_Obj(item[Workshops[11]]));
                file_content.Append(@"</Data></Cell><Cell ss:StyleID='s62'><Data ss:Type='String'>");
                file_content.Append(Get_String_From_Obj(item[Workshops[12]]));
                file_content.Append(@"</Data></Cell><Cell><Data ss:Type='String'>");
                file_content.Append(Get_String_From_Obj(item[Workshops[13]]));
                file_content.Append(@"</Data></Cell></Row>");
            }
<Cell ss:StyleID='s62'> это стиль для текстового поля с переносом по буквам в ячейке.
методы которые тут задействованы:

private string Get_String_From_Obj(object obj)
        {
            string str = "";
            if (obj != null)
            {
                str = obj.ToString();
            }
            return str;
        }
        public string getUser(SPFieldUserValue field_user)
        {
            if (field_user != null)
            {
                return Get_String_From_Obj(field_user.LookupValue);
            }
            return "";
        }
Дальше добавим в нашу xml следующие:
file_content.Append(@"</Table>
                            <WorksheetOptions xmlns='urn:schemas-microsoft-com:office:excel'>
                            <PageSetup>
                            <Header x:Margin='0.3'/>
                            <Footer x:Margin='0.3'/>
                            <PageMargins x:Bottom='0.75' x:Left='0.7' x:Right='0.7' x:Top='0.75'/>
                            </PageSetup>
                            <Visible>SheetHidden</Visible>
                            <Print>
                            <ValidPrinterInfo/>
                            <HorizontalResolution>600</HorizontalResolution>
                            <VerticalResolution>600</VerticalResolution>
                            </Print>
                            <Selected/>
                            <FilterOn/>
                            <Panes>
                            <Pane>
                            <Number>3</Number>
                            <ActiveRow>25583</ActiveRow>
                            <ActiveCol>3</ActiveCol>
                            </Pane>
                            </Panes>
                            <ProtectObjects>False</ProtectObjects>
                            <ProtectScenarios>False</ProtectScenarios>
                            </WorksheetOptions>
                            </Worksheet>
                            </Workbook>");
И теперь сохраним его в библиотеку:
 MemoryStream stream = new MemoryStream();
            _report = new XmlDocument();
            _report.LoadXml(file_content.ToString());
            _report.Save(stream);
            SPUser user = web.CurrentUser;
            SPFile file = web.Files.Add(web.Url + "/" + sourceListObj.RootFolder.ToString() + "/" + String.Format("{0}_отчет_{1}.xls", user.Name, date.ToString("dddd, dd MMMM yyyy h mm tt")), stream.GetBuffer(), true);
            file.Update();
 Вот и все!

Edit ListItem in popup window from Silverlight or Js in Sharepoint 2010

Добрый день!
Сегодня поговорим о том, как редактировать элементы списка из Silverlight приложения.
 Нас интересует именно встроенный редактор текста в Sharepoint который позволяет создавать ссылки, загружать картинки, рисовать таблицы и прочие красивые вещи. Но нам ведь не хотелось бы давать доступ на страницу списка для обычных пользователей, поэтому я вам расскажу как сделать это просто и красиво.

Для начала выясним что такое popup окно в sharepoint 2010, это красивое всплывающее окно построенное на js. Пример вы можете увидеть когда открываете редактирование элемента списка или просмотр элемента.
string js =
                    var options = {
url: '_layouts/listform.aspx?PageType=6&ListId='IdList'&ID='IdListItem',
                    title: 'Редактирование элемента',
                    allowMaximize: true,
                    showClose: true,
                    width: 625,
                    height: 525,
                    showMaximized: true,
                    dialogReturnValueCallback: silentCallback};
                    function open() {SP.UI.ModalDialog.showModalDialog(options);}
                   function silentCallback(dialogResult, returnValue) {alert('I am here');}
                    function refreshCallback(dialogResult, returnValue) {
                    SP.UI.Notify.addNotification('Operation Successful!');                             SP.UI.ModalDialog.RefreshPage(SP.UI.DialogResult.OK);
                    }
              HtmlWindow htmlWindow = HtmlPage.Window;
                htmlWindow.Eval(js);
 И нужно просто вызвать функцию  open();
Для выполнения функции по возврату назад я использую  silentCallback(), в которую можно передать параметр и с которой можно вызвать метод Silverlight приложения(как это делать я писал в блоге).
Вот так просто и красиво вы получите Sharepoint редактор текста на своей странице.
И не нужно использовать свои решения и создавать красивые редакторы на которые  могут уйти недели времени.








понедельник, 4 июля 2011 г.

Как работать с javascript из silverlight приложения? Или void Silverlight from js!

Доброе время суток!
Сегодня я расскажу как работать с языком java script из приложения написаного на Silverlight, а так же как осуществить обратную связь, как из java script вызвать метод приложения silverlight или получить доступ к свойству silverlight программы.
Приступим!
Технология Silverlight позволяет очень просто работать с js скриптами, а также регистрировать функции js прям из программы Silverlight! Для доступа к DOM модели используется класс  HtmlPage. Пример вывода "HelloWorld" из программы Silverlight:
HtmlWindow htmlWindow = HtmlPage.Window;
htmlWindow.Eval("alert(\"HelloWorld!\");");
Что бы зарегистрировать свою функцию js из программы Silverlight:
string js = "function Hello()"+
               "{ alert(\"HelloWorld!\");}";
             var script = HtmlPage.Document.CreateElement("script");
            script.SetAttribute("type", "text/javascript");
            script.SetProperty("text", js);
            HtmlPage.Document.Body.AppendChild(script);

И теперь вы его можете вызвать через 
HtmlWindow htmlWindow = HtmlPage.Window;
htmlWindow.Eval("Hello();");

Теперь я расскажу как работать с методами Silverlight приложения из js.
Для этого Вам нужно зарегистрировать в вашем Silverlight приложении объект самого приложения:
 HtmlPage.RegisterScriptableObject("Page", this);
Теперь что бы обратится к этому объекту из js функции нужно найти на странице html контейнер с объектом Silverlight:
function Get_Silverlight()
{
   var silverlightObj_id;
  var reg = new RegExp("(SilverlightObjectTag)");                 
 var objects = document.getElementsByTagName("object");
                    for(i=0;i<objects.length;i++)
                   {                    if(objects[i].getAttribute("id")!=null)
                    {     var match=objects[i].getAttribute("id").match(re);
                    if(match!=null && match.length !=null && match.length > 0)
                   {      silverlightObj_id = objects[i].getAttribute("id");     }}}  return silverlightObj_id;}
Пример кода как можно найти объект Silverlight на странице Sharepoint если вы воспользовались вебпартом для вставки Silverlight. Используя jquery этот код станет в разы проще :)

Теперь что бы вызвать метод в Silverlight приложении нужно указать самому Silverlight приложению что этот метод доступен из вне программы:
[ScriptableMember()]
      public void HelloFromJs(string helloMessage)
      {
HtmlWindow htmlWindow = HtmlPage.Window;
htmlWindow.Eval("alert('"+helloMessage+"');");
       }
И что бы вызвать из js этот метод надо следующее:
function HelloToSilverlight()
                    {
                    var id = Get_Silverlight();//ее мы создали ранее
                   var control = document.getElementById(id);
                   control.content.Page.HelloFromJs("I am js"); //Page мы регистрировали как объект в //Silverlight приложении
                    }
Что бы получить доступ к переменной Silverlight приложении нужно ее обьявить в приложении
 [ScriptableMemberAttribute]
        public string SomeProperty { get; set; }

И доступ к ней будет осуществляться через control.content.Page.SomeProperty
Этот инструмент помогает сделать прочную связь между js и Silverlight а так же обойти ошибку компилятора при передачи кода html в js функцию в Silverlight приложении.
Спасибо!