Pavel Novotný

avatar

Email: novotny@pavelnovotny.info
Telefon: +420 732376206
Skype: pavelnovotny.info
Messenger: novotny@pavelnovotny.info
ICQ: 167-272-595
Web: www.pavelnovotny.info


Tags

Kategorie

Navigation

Stránky

    Archiv

    Odkazy

    Document ID v SharePointu 2010 (DMS v SharePointu 2010)

    Seznamy/knihovny v produktu SharePoint 2007 obsahují pouze "ID" sloupce, což je celé číslo, které se neustále zvyšuje. Ve skutečném světě však tento identifikátor zdaleka nedostačuje potřebám společnosti a je potřeba využít mnohem sofistikovanějšího systému pro globální určení dokumentu.

    Pro tuto potřebu globálně identifikovat dokument v rámci společnosti vzniknul systém Document ID v SharePointu 2010, který otevře dokument nebo soubor dokumentů souvisejících s ID, bez ohledu na umístění dokumentu.

     

    Pro aktivaci systému stačí aktivovat feature:

    image

     

    Po aktivaci této feature Document ID vznikne nové DMSID při vložení nového dokumentu do knihovny zcela automatizovaně podle vstupního schématu DMSID řetězce:

     image

    SharePoint 2010 si Document ID pamatuje, je zcela jedno zda tento dokument přesouváte do jiných knihoven nebo adresářů, vždy je možné se k němu snadno dostat pomocí stejné URL adresy, která se po celou dobu životnosti dokumentu nemění.

    Vytvořeno: 01.02.2010 03:56 uživatelem novotny | Komentáře (0) RSS comment feed |
    • Currently 0/5 Stars.
    • 1
    • 2
    • 3
    • 4
    • 5
    Kategorie: .NET | Sharepoint

    BlogEngine.NET Extension: nastavení data vytvoření a popisku galerie

    O původním rozšíření galerie pro BlogEngine.NET načítané z Sharepointu se dočtete zde:

    http://www.pavelnovotny.info/post/BlogEngineNET-Extension-zobrazeni-lightbox-galerie-obrazku-ziskane-z-Sharepointu-(WSS-MOSS).aspx

     

    Nyní jsem projekt malinko upravil tak, aby bylo možné uložit ke každé galerii popisek a její datum vytvoření, protože v předchozí verzi se jako datum vytvoření zobrazoval pouze datum vytvoření samotné knihovny, nešlo tedy alespoň trošku intuitivně nastavit zpětný datum.

    Nyní je to možné v nastavení knihovny:

    image

    image

    Zde je možné stejně jako přes menu akcí povolit přístup k vybrané galerii, nastavit datum pořízení + víceřádkový popis galerie. Výsledné zobrazení je možné si prohlédnout zde:

    http://www.pavelnovotny.info/SharepointExtensions/Gallery.aspx

     

    Aktualizovaná verze zdrojových souborů a instalačního balíku je opět zde:

    http://www.pavelnovotny.info/public/BlogEngineExtensions.zip

    Vytvořeno: 10.08.2009 14:42 uživatelem novotny | Komentáře (0) RSS comment feed |
    • Currently 0/5 Stars.
    • 1
    • 2
    • 3
    • 4
    • 5

    BlogEngine.NET Extension: zobrazení lightbox galerie obrázků získané z Sharepointu (WSS/MOSS)

    Úvodem bych chtěl upozornit, že tento post byl v úplném počátku motivován soutěží MSDN - "Dokážeš to", později při vývoji rozšíření jsem si ale uvědomil, že něco takového jsem vlastně stejně potřeboval a v mém případě /možná trošku už šílenství/, kdy Sharepoint používám i pro domácí účely /výpočty příjmů/nákladů domácnosti, daní, katalogu e-books, diskusím v rámci rodiny, sdílení kontaktů atd), se mi velice hodí, protože mohu takto jednoduše bez opuštění domácího portálu publikovat fotografie na internet = a nejen já, ale i další rodinný příslušníci (ty ale radši mají aktivované schvalovací workflow :). Na různých místech kódu je patrné, že jsem si také připravoval půdu pro publikování dokumentů, to jsem do této verze nestihl = což by ale nemuselo této ukázce možné integrace nijak vadit. Tento post se pokusím napsat tak, aby byl pochopitelný i pro neznalce Sharepointu, ale když tak pište.

    O čem je Sharepoint nebudu zdlouhavě popisovat a vypůjčím si z webu MS tento odstavec:

    Microsoft Windows SharePoint Services je univerzální technologie, která umožňuje organizacím a obchodním jednotkám všech velikostí zvýšit efektivitu obchodních procesů a zlepšit produktivitu týmů. Díky nástrojům pro spolupráci, které uživatelům umožňují zůstat připojeni i za geografickými hranicemi a hranicemi organizace, poskytuje služba Windows SharePoint Services uživatelům přístup k informacím, které potřebují.

    http://www.microsoft.com/cze/office/technologies/sharepointtechnology/highlights.mspx

     

    V Sharepointu existují knihovny dokumentů specializované pro galerie obrázků/fotek:

    Toto rozšíření načítá z této galerie obrázky přes vlastní webservices, která řeší logiku povolení/zákazu přístupu k této galerii obrázku. U každé galerie je možné externí přístup aktivovat v menu Akce:

    Menu je dvoustavové, pokud tedy přístup aktivujete, zobrazí se v menu deaktivace (to je realizováno formou CustomAction ve WebControl):

    Po povolení přístupu bude galerie ihned dostupná v BlogEngine.NET:

     

    V galerii je, už jak titulek tohoto postu napovídá, implementovaný Lightbox 2:

    Pokud aktivujete více galerií, jsou zobrazeny na této stránce všechny, seřazeny podle data vytvoření sestupně.

    Jednotlivé galerie lze vkládat i do samotného postu, stačí na to jednoduchý zápis přímo do těla postu (je v obrázku, aby se mi také nepřidala galerie):

    Stačí tedy copy&paste relativní url adresy k dané SITE.

    Není to hezké? :)

     

    Při inline galerii stále platí, že je použit Lightbox stejně jako na stránce zobrazující všechny galerie, galerie také musí být povolena /bez povolení nebude galerie otevřena/.

    Klíčové vlastnosti

    • zobrazuje galerie načítané z Sharepointu
    • skutečná adresa WSS portálu není nikde vidět, obrázky načítá speciální handler
    • obrázky mají primitivní cache na straně BlogEngine v handleru (ten provádí i resizing)
    • zobrazují se pouze explicitně povolené galerie, jiné nejsou dostupné
    • pro zobrazení je použit Lightbox 2
    • demo je na tomto webu
    • dávám k tomu i zdrojové kódy :)

    Do budoucna bych chtěl přidat i knihovny dokumentů.

    Zdrojové kódy

    http://www.pavelnovotny.info/public/BlogEngineExtensions.zip

    Budete potřebovat Visual Studio 2008 + WSP Builder

    Demo

    Demo je přímo na tomto webu zde:

    http://www.pavelnovotny.info/SharepointExtensions/Gallery.aspx

    Ukázka inline galerie je zde:

    microsoft-office-sharepoint-logo.jpg Office SharePoint Designer.png sharepoint.jpg screenshot_2007.jpg wss-moss-diff.jpg

    Instalace

    Nejprve je nutné provést deploy WSP balíčku na Sharepoint server, k tomu jsem připravil dávku "DeploySolutionPackage.cmd", v té je potřeba změnit akorát url adresu.  Po úspěšné instalaci feature je nutné jí aktivovat na úrovní SITE kolekce:

    Hotovo! :) Pokud se teď přesunete do jakékoliv galerie, uvidíte v menu akci pro povolení přístupu z BlogEngine.NET:

    Následuje instalace rozšíření do BlogEngine.NET, to je opět jednoduché, stačí kompletní obsah <BlogEngineExtension.zip\BlogEngine> zkopírovat do rootu Vaší aplikace BlogEngine.

    Po přihlášení do administrace bude v záložce Extensions nové rozšíření:

    Před prvním použitím je nutné toto rozšíření ještě nakonfigurovat, do následující stránky je nutné vložit URL adresu SITE Vašeho Sharepoint portálu.

    POZOR: uživatelské jméno ani heslo není nutné vyplňovat, pokud aplikace BlogEngine.NET beží pod účtem uživatele, který má do daného webu přístup. Pokud nemá, počítače například nejsou ve stejné doméně, je nutné specifikovat uživatele ručně /toto řešení je vhodné pouze a jen ve vývojovém prostředí, za každou cenu se vyhněte vyplnění hesla na hostingu !!!/.

    I v případě, že máte obě aplikace na stejném severu a nemusíte tedy heslo vyplňovat, důrazně doporučuji použít pro pool nového uživatele, tomu povolit přístup pouze do jednoho webu, určeného pouze pro externí obsah, tedy nikoliv použít uživatele, který může přistupovat do všech webů!!! A i v tomto jednom webu nastavit práva uživatele pouze pro čtení! Nezapomeňte však povolit čtení i na skrytém listu pro konfigurace "/Lists/BlogEngineExtensionLists/AllItems.aspx"

    V neposlední řadě si do menu skinu přidejte položku pro zobrazení všech galerii:

    <li><a href="~/SharepointExtensions/Gallery.aspx" runat="server">Galerie</a></li>

     

    Kompletní balík včetně zdrojových kódů je zde:

    http://www.pavelnovotny.info/public/BlogEngineExtensions.zip

    Vytvořeno: 11.03.2009 12:20 uživatelem novotny | Komentáře (0) RSS comment feed |
    • Currently 5/5 Stars.
    • 1
    • 2
    • 3
    • 4
    • 5
    Kategorie: .NET | Sharepoint

    MOSS: nastavení práv pro guest uživatele u publishing site

    Aby nemohl anonymní uživatel přistupující k publishing site portálu prohlížet všechny listy, formuláře, položky ve standardních formulářích listů WSS, je potřeba pro příslušnou site nastavit práva pro uživatele guest. Nastavit práva je samozřejmě možné přes administraci, lepším a spolehlivějším řešením je určitě takové nastavení provést při aktivaci feature našeho projektu /omezující lidskou chybu/.

    internal static void LockDownViewFormPages(SPWeb web)
    {
        RunWithWebCulture(web, delegate
        {
            ConfirmNotCentralAdminWebApp(web);
            SPRoleDefinition byType = web.RoleDefinitions.GetByType(SPRoleType.Guest);
            byType.BasePermissions = SPBasePermissions.BrowseDirectories |
                                     SPBasePermissions.Open |
                                     SPBasePermissions.OpenItems |
                                     SPBasePermissions.ViewPages;
            byType.Update();
        });
    }

    Takto to lze samozřejmě použít i v "pouhém" WSS pro jiné účely/skupiny uživatelů.

    Poznámka: SPBasePermissions.BrowseDirectories je potřeba, jinak nejde zjistit default stránka pomocí "PublishingWeb.DefaultPage"

    Vytvořeno: 05.02.2009 18:04 uživatelem novotny | Komentáře (0) RSS comment feed |
    • Currently 0/5 Stars.
    • 1
    • 2
    • 3
    • 4
    • 5
    Kategorie: .NET | Sharepoint

    WSS: Hromadné odstranění záznamů v listu

    Pokud jste někdy potřebovali kompletně vyprázdnit list/knihovnu dokumentů, určitě jste rychle narazili, stejně jako já, na neexistenci takové funkce. Samozřejmě je možné mazat jednotlivé záznamy v iteraci, to je ale velice časově nákladná operace, kterou nejde použít ani na desítkách záznamů :( Smazání jednoho záznamu trvá klidně i 500ms, 1000 záznamů by se tedy mazalo 5-10 minut.

    Nakonec jsem našel trošku krkolomné řešení, které je však řádově rychlejší než mazání v iteraci. Základem celé akce je složení velkého XML balíku hromadného příkazu pro smazání jednotlivých záznamů v jednom volání. Vtip je v tom, že i když toto řešení také iteruje celým seznamem v listu, property ID je u SPListItem už přednačtena v cache Sharepointu, ten tedy nemusí pro každou iteraci sahat do DB, složení tak může proběhnout rychle. Výsledný balík se už jen předhodí enginu WSS, který jej interně zpracuje. Po ukončení ještě v mém případě volám vyprázdnění koše aktuálně přihlášeného uživatele, to samozřejmě není nutné a může být v některých případech i kontraproduktivní při volání pod "real-life" uživatelem.

    Pokud existuje lepší cesta, určitě bych se nechal rád inspirovat :)

    private static void BatchListItemsDelete(SPList spList)
    {
        StringBuilder sbDelete = new StringBuilder();
        sbDelete.Append("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Batch>");
        string command = "<Method><SetList Scope=\"Request\">" + spList.ID +
            "</SetList><SetVar Name=\"ID\">{0}</SetVar><SetVar Name=\"Cmd\">Delete</SetVar></Method>";

        foreach (SPListItem item in spList.Items)
            sbDelete.Append(string.Format(command, item.ID.ToString()));

        sbDelete.Append("</Batch>");

        spList.ParentWeb.ProcessBatchData(sbDelete.ToString());
        spList.ParentWeb.RecycleBin.DeleteAll();
    }

    Vytvořeno: 04.02.2009 22:53 uživatelem novotny | Komentáře (0) RSS comment feed |
    • Currently 0/5 Stars.
    • 1
    • 2
    • 3
    • 4
    • 5
    Kategorie: .NET | Sharepoint

    Zobrazení aktuálních aktivit Microsoft CRM 4 v Sharepointu + zdrojové kódy

    Na tomto příspěvku jsem chtěl demonstrovat jednoduchost a vůbec možnost provázání různých aplikací s Sharepointem. Rozhodl jsem se pro vytvoření webparty, zobrazující aktuálně přiřazené a nesplněné aktivity v Microsoft CRM 4, protože to bude určitě užitečná featura pro spoustu lidí využívajících firemní intranet.

    Takto vypadá výsledný webpart (po kliknutí na daný předmět aktivity se otevře přímo v editačním okně CRM):

     



    Takto jsou zobrazeny aktivity v CRM:

    Zdrojové kódy i WSP balíček je přiložen na konci tohoto postu.

    Načítání aktivit z CRM serveru probíhá přes webservice, url adresa webové služby je vždy ve formátu:

    http://server:port/MSCRMServices/2007/CrmService.asmx

    Pokud používáte Visual Studio 2008, je potřeba vygenerovat klientský wrapper až v "Advance" dialogu jako na následujícím screenshotu:

     

    Aby bylo možné rozlišit aktuálně používanou organizaci zavedenou v CRM, je potřeba ještě provést nastavení objektu CrmAuthenticationToken jako na následujícím příkladu:

            public static CrmService GetCrmService(string crmServerUrl, string organizationName)
            {
                if (string.IsNullOrEmpty(crmServerUrl)) throw new ArgumentNullException("crmServerUrl");
                if (string.IsNullOrEmpty(organizationName)) throw new ArgumentNullException("organizationName");

                CrmSdk.CrmAuthenticationToken token = new CrmSdk.CrmAuthenticationToken();
                token.OrganizationName = organizationName;

                CrmService service = new CrmService();
                UriBuilder builder = new UriBuilder(crmServerUrl);
                builder.Path = "//MSCRMServices//2007//CrmService.asmx";
                service.Url = builder.Uri.ToString();
               
                service.Credentials = System.Net.CredentialCache.DefaultCredentials;
                service.CrmAuthenticationTokenValue = token;

                return service;
            }

     

    Aby jsme mohli vyhledat svoje aktivity, je nejprve nutné zjistit identifikátor přihlášeného uživatele:

                WhoAmIRequest request = new WhoAmIRequest();
                WhoAmIResponse response = (WhoAmIResponse)service.Execute(request);
                Guid userId = response.UserId;

    Pak už jen stačí vyhledat aktivity s přiřazeným vlastníkem na sebe sama a nastaveným status kódem - open nebo scheduled.

            private static BusinessEntityCollection GetAssignedActivities(CrmService crmService, Guid userId)
            {
                // budeme nacitat aktivity prirazene prihlasenemu uzivateli
                ConditionExpression condition = new ConditionExpression();
                condition.AttributeName = "ownerid";
                condition.Operator = ConditionOperator.Equal;
                condition.Values = new object[] { userId };

                // potrebujeme pouze otevrene aktivity
                ConditionExpression condition2 = new ConditionExpression();
                condition2.AttributeName = "statecode";
                condition2.Operator = ConditionOperator.Equal;
                condition2.Values = new object[] { (int)ActivityPointerState.Open };
                ConditionExpression condition3 = new ConditionExpression();
                condition3.AttributeName = "statecode";
                condition3.Operator = ConditionOperator.Equal;
                condition3.Values = new object[] { (int)ActivityPointerState.Scheduled };

                FilterExpression filterState = new FilterExpression();
                filterState.FilterOperator = LogicalOperator.Or;
                filterState.Conditions = new ConditionExpression[] { condition2, condition3 };

                FilterExpression filterRequired = new FilterExpression();
                filterRequired.FilterOperator = LogicalOperator.And;
                filterRequired.Conditions = new ConditionExpression[] { condition };

                FilterExpression filter = new FilterExpression();
                filter.FilterOperator = LogicalOperator.And;
                filter.Filters = new FilterExpression[] { filterRequired, filterState };

                // seradime podle konce aktivity
                OrderExpression order = new OrderExpression();
                order.AttributeName = "scheduledstart";
                order.OrderType = OrderType.Ascending;
               
                // vytvoreni vyhledavaciho dotazu - potrebujeme vsechny aktivity
                QueryExpression query = new QueryExpression();
                query.EntityName = EntityName.activitypointer.ToString();
                query.ColumnSet = new AllColumns();
                query.Criteria = filter;
                query.Orders = new OrderExpression[] { order };

                // vykonani samotneho dotazu
                return crmService.RetrieveMultiple(query);
            }

     

     Následně již stačí vyrenderovat všechny položky do HTML. Prosté, ale dobré :)


    Instalace feature:

    cd C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\BIN

    stsadm -o addsolution -filename crm4connector.wsp

    stsadm -o deploysolution -name crm4connector.wsp -immediate -allcontenturls -allowGacDeployment -allowCasPolicies

    následně aktivujte feature ve správě webu:

     

    Přidejte feature "Activities in CRM" na libovolnou stránku:

     

    V nastavení feature je nutné ještě nastavit url adresu serveru s Microsoft CRM 4 a název organizační jednotky: 

    (níže je také možné upravit obecné texty podle potřeby - podle aktuálně používaném jazyku)

     

    Hotovo, po potvrzení by se měl zobrazit seznam aktivit aktuálně přihlášeného uživatele. Pokud je něco špatně, budete upozorněni:


    Ke stažení:

    sources.zip (272,14 kb)

    bin.zip (244,01 kb)

    Vytvořeno: 24.01.2009 10:33 uživatelem novotny | Komentáře (0) RSS comment feed |
    • Currently 4/5 Stars.
    • 1
    • 2
    • 3
    • 4
    • 5

    Visual Studio 2008 extensions for SharePoint v1.3 - CTP

    http://blogs.msdn.com/vyvojari/archive/2009/01/16/visual-studio-2008-extensions-for-sharepoint-v1-3-ctp.aspx

    Vytvořeno: 21.01.2009 20:36 uživatelem novotny | Komentáře (0) RSS comment feed |
    • Currently 0/5 Stars.
    • 1
    • 2
    • 3
    • 4
    • 5
    Kategorie: .NET | Sharepoint

    Nastavení XML-RPC.NET programově bez nutnosti existence konfiguračního souboru

    Jelikož se mi v aktuálním projektu nehodila existence konfiguračního souboru aplikace (app.config) pro zajištění konfigurace XML RPC serveru ve vlastní assembly, potřeboval jsem stejné parametry nastavit programově.

    Nakonec jsem narazil na odpověď:

    ListDictionary prop = new ListDictionary();

    prop.Add("port", 1971);

    HttpChannel channel = new HttpChannel( prop, null, new XmlRpcServerFormatterSinkProvider(null, null));

    ChannelServices.RegisterChannel(channel);

    RemotingConfiguration.RegisterWellKnownServiceType( typeof(Server), "myApp/anURI", WellKnownObjectMode.Singleton);

     

    Vytvořeno: 04.01.2009 14:52 uživatelem novotny | Komentáře (0) RSS comment feed |
    • Currently 0/5 Stars.
    • 1
    • 2
    • 3
    • 4
    • 5
    Kategorie: .NET | XML-RPC

    Programové nastavení UseUnsafeHeaderParsing

    Vzhledem k častému rozpadání spojení při volání některých java webservices serverů je nutné buď vypnout keep alive nebo nastavit useUnsafeHeaderParsing. První metoda výrazným způsobem ovlivní výkon, protože se při každém requestu znovu navazuje tcp spojení, druhá se zase doporučuje pouze u "bezpečných" serverů, u kterých nehrozí nebezpečí útoků pomocí přetečení bufferu.

    V případě projektů, při kterých je i server v naší režii, je určitě lepší cesta nastavením useUnsafeHeaderParsing, to je možné jak v app.config, tak i programově pomocí reflexe:

    Nastavení v app.config:

    <system.net>
    <settings>
    <httpWebRequest useUnsafeHeaderParsing = "true"/>
    </settings>
    </system.net>

    Programové nastavení pomocí reflexe:

            public static bool SetAllowUnsafeHeaderParsing()
            {
                Assembly aNetAssembly = Assembly.GetAssembly(
                  typeof(System.Net.Configuration.SettingsSection));
                if (aNetAssembly != null)
                {
                    Type aSettingsType = aNetAssembly.GetType(
                      "System.Net.Configuration.SettingsSectionInternal");
                    if (aSettingsType != null)
                    {
                        object anInstance = aSettingsType.InvokeMember("Section",
                          BindingFlags.Static | BindingFlags.GetProperty
                          | BindingFlags.NonPublic, null, null, new object[] { });
                        if (anInstance != null)
                        {
                            FieldInfo aUseUnsafeHeaderParsing = aSettingsType.GetField(
                              "useUnsafeHeaderParsing",
                              BindingFlags.NonPublic | BindingFlags.Instance);
                            if (aUseUnsafeHeaderParsing != null)
                            {
                                aUseUnsafeHeaderParsing.SetValue(anInstance, true);
                                return true;
                            }
                        }
                    }
                }
                return false;
            }

    Více zde: http://msdn.microsoft.com/en-us/library/system.net.configuration.httpwebrequestelement.useunsafeheaderparsing.aspx

    Vytvořeno: 16.05.2008 15:16 uživatelem novotny | Komentáře (0) RSS comment feed |
    • Currently 0/5 Stars.
    • 1
    • 2
    • 3
    • 4
    • 5
    Kategorie: .NET

    DirectorySearcher vrací maximálně 1000 záznamů

    MSDN dokumentace neobsahuje příliš mnoho informací k tomuto problému, naštěstí v diskustní skupině to již někdo řešil.

    Objekt DirectorySearcher obsahuje dvě klíčové vlastnosti:

    PageSize - defaultně nastaveno na 0 - bez stránkování, určuje počet záznamů v jednom interním requestu na server, o "stránkování" se stará sám objekt vyhledávače.

    SizeLimit - defaultně 1000, maximální počet vrácených záznamů

    Při defaultním nastavení nikdy nevrátí více než 1000 záznamů, protože v tom případě vyhledávač nestránkuje. Pokud jste si mysleli, že stačí SizeLimit změnit na vyšší hodnotu, tak jste se spletli. Snad jediná možná cesta je změnit PageSize, aby došlo ke stránkování, ale zde je další vtip dokumentace, nikde nenajdete, ze PageSize musí být z intervalu 0-1000 a už vůbec to, že pokud nastavíte hodnotu 1000, opět nedojde ke stránkování a DS vrátí pouze 1000 záznamů - to považuji snad za bug... Správna cesta je nastavit PageSize na menší hodnotu, například 999, následně již obdržíte záznamy všechny...

    Příklad načtení všech uživatelů z LDAPu:

    DirectorySearcher mySearcher = new DirectorySearcher(rootEntry);

    mySearcher.Filter = "(&(objectCategory=Person)(objectClass=User))";
    mySearcher.PropertiesToLoad.Add("cn");
    mySearcher.PropertiesToLoad.Add("objectClass");
    mySearcher.PropertiesToLoad.Add("sAMAccountName");
    mySearcher.PageSize = 999;

    SearchResultCollection mySearcherSearchResult = mySearcher.FindAll();

    Vytvořeno: 27.06.2007 00:58 uživatelem novotny | Komentáře (0) RSS comment feed |
    • Currently 5/5 Stars.
    • 1
    • 2
    • 3
    • 4
    • 5
    Kategorie: .NET