Vítejte na blog.vyvojar.cz Přihlásit | Registrovat | Pomoc
Titulní Blogy Fotky Soubory

Mazinův blog o SharePointu

  • MVP certifikace

    S radostí vám chci napsat, že se mi podařilo dosáhnout MVP certifikace pro oblast SharePointu. Udělám, co budu moci, abych ji udržel. Tedy mimo jiné pokračovat v psaní tohoto blogu. Smile

    Děkuji vám za přízeň.

  • Problematická trojka – workflow, úkol a correlation token

    Před časem jsem psal článek o detailech implementace SharePoint workflow. Dnes se podíváme na praktické důsledky. Jde zejména o práci s úkoly a položkami, nad nimiž běží workflow, a problémy s tím spojenými.

    Zmiňoval jsem se o tom, že pro “publikaci” událostí o změnách nad položkami se používají event receivery. Ty jsou zodpovědné za automatické spouštění workflow a předávání informací o změnách na úkolech a položkách do spuštěných workflow. To ale není vše, co se na pozadí děje. A nutno také říct, že o mnohém z dále uvedeného MSDN mlží, nebo přímo neříká pravdu.

    Práce s úkoly

    Proto, aby si SharePoint udržel přehled o tom, že změna na úkolu byla zpracována workflow, mají workflow úkoly (typy obsahu odvozené od Workflow Task) definovaný sloupec WorkflowVersion. Ten nevyjadřuje verzi workflow, které úkol vygenerovalo, jak se můžete občas na internetu dočíst. Sloupec funguje jako zámek. Jeho výchozí hodnota je 1. Update metody (včetně SystemUpdate) nejprve kontrolují:

    1. jestli daný úkol je součástí běžícího workflow.
    2. jestli není vypnutý EventFiring. Když je vypnutý, že nehrozí, že by na změnu mohlo reagovat workflow (posouvané pomocí event receiverů).

    V případě, že oba testy jsou pozitivní, kontroluje se hodnot sloupce WorkflowVersion. Pokud je vyšší než 1, vyhodí známou vyjímku “This task is currently locked by a running workflow and cannot be edited”. V opačném případě se provede aktualizace úkolu. Na aktualizaci reaguje systémový event receiver a nastaví hodnotu sloupce na 512. Obsluha události ve workflow, tedy  aktivita onWorkflowTaskChanged, nastaví hodnotu sloupce WorkflowVersion opět na 1, tedy uvolní zámek pro další změny úkolu. V ideálním případě se informace o změně úkolu dostane do workflow téměř ihned. Může se ale stát (některé situaci si popíšeme dále), že informace do workflow je doručena jobem. Jeho spouštění je standardně naplánováno v 5 minutových intervalech. A během té doby je úkol uzamčen pro veškeré úpravy. Vhodnější je při úpravách workflow úkolů volat SPWorkflowTask.AlterTask(). Ta sice vnitřně také volá SPListItem.Update(), který může vyvolat vyjímku. Ale na svém začátku volá SPWorkflowTask.SetWorkflowData(), čímž posílá informace o změně přímo do workflow subsystému. Navíc v případě synchronního volání (parametr metody) počká před updatem až 30s na případné uvolnění zámku. Metodu AlterTask volá i editform úkolů.

    Podle MSDN by se měly event receivery pro sběr událostí o úkolech a položkách registrovat až v okamžiku, kdy se začne na tyto události čekat (workflow ve svém běhu dojde do aktivit onWorkflowTaskChanged, onWorkflowItemChanged, …). Naopak by se receivery měly deregistrovat po jejich dokončení, tedy obsluze odpovídajících událostí.

    Bohužel to celé nefunguje úplně dobře. Například když workflow vytvoří úkol a skončí (nebude čekat na změnu), vznikne nepříjemná situace. Úkol můžete editovat. Na tuto změnu zareaguje event receiver a nastaví hodnotu workflowversion na 512. Další pokusy o změnu už skončí neúspěchem. Zafunguje totiž kontrola v SPListItem.Update(). Problém je v tom, že chybí onWorkflowTaskChanged aktivita, která by hodnotu vrátila na 1.

    Correlation tokeny

    Correlation tokeny vytváří vazbu mezi aktivitami, které pracují s úkoly případně s položkou, nad níž workflow běží. Díky tomu může být ve workflow několik aktivit, které vytváří úkoly, mění je, čekají na jejich změnu a to celé souběžně a propleteně. Proto může workflow obsahovat více CreateTask aktivit a po nich několik onWorkflowTaskChanged, které budou reagovat na změnu “toho svého” úkolu. Workflow runtime je používá k určení místa, kam má v běžícím workflow doručit informaci o změně úkolu, nebo položky.

    Důležitou vlastností correlation tokenu je parent activity. Ta definuje rozsah platnosti tokenu, resp. toho, kde se pracuje s úkoly s ním svázanými. Pro práci s položkou (aktivity UpdateItem, onWorkflowItemChanged, …) se používá přímo token workflow, protože jeho parent aktivitou je workflow samotné. Pro práci s úkoly (CreateTask, onWorkflowTaskChanged, …) se definují vlastní tokeny s parent aktivitou zvolenou tak, aby objímala všechny operace, které se s jedním úkolem dějí. Někdy se vkládá do workflow uměle sequence aktivita právě pro definici rozsahu platnosti tokenu.

    A opět musím napsat, že to nefunguje úplně dobře. Correlation tokeny mohou způsobit dead-locky workflow, které workflow zcela zablokují. Nebo se může workflow chovat velmi nečekaně.

    Kombinace práce s úkolem a položkou v 1 workflow

    Člověk by řekl, že na workflow, které čeká na změnu položky, nad níž běží, vytváří úkoly a čeká na jejich dokončení, nemůže být nic dramatického. Zejména proto, že jde o běžný scénář. Pravda je to jen částečně. Změna položky a změna úkolu mohou vést k zámku workflow. To se programově pozná tak, že je nastavena vlastnost SPWorkflow.IsLocked na true. V UI to poznáte tak, že v detailu workflow uvidíte následující hlášku: Z důvodu velkého zatížení byla nejnovější operace pracovního postupu zařazena do fronty. K pokusu o její obnovení dojde později. Tím workflow runtime říká, že má několik konfliktních změn, které není schopen vyřídit live a proto je zařadil do fronty a vyřeší je job posouvající workflow kupředu. Z uživatelského pohledu to znamená, že workflow se zpracuje provedené změny se zpožděním odvislým od toho, jak je naplánovaná perioda toho jobu (standardně 5 min).

    Pojďme si na zjednodušených příkladech ukázat některé problémové situace, a jak se jim případně vyhnout.

    Příklad 1

    Začneme jednoduchým příkladem. Nejprve se čeká na změnu položky. Pak se vytvoří úkol a čeká se na jeho změnu. Tím workflow končí. Prosté a funkční.

    Příklad 2

    Nejprve se vytvoří úkol (CreateTask1), pak se čeká na jeho změnu (onTaskChanged1) a následně na změnu položky, nad níž úkol běží (onWorkflowItemChanged1). Úkolové aktivity mají vlastní token, onWorkflowItemChanged1 používá workflowToken. Jednoduché workflow, na kterém není nic složitého. Ale pozor! Workflow se totiž dokončí i v následujícím scénáři: Nejprve změním položku. Protože se hned na začátku registruje event receiver pro registraci změn položky a současně onWorkflowItemChanged1 používá workflowToken, který je platný od rozběhnutí workflow, tak se informace o změně položky uschová. Pak se vytvoří úkol, počká se na jeho změnu a ihned se z šuplíku vytáhne událost změny položky workflow, obslouží se a workflow skončí.

    Příklad 3

    Využití aktivity InitializeWorkflow a použití stejného correlation tokenu pro ni a aktivitu onWorkflowItemChanged1. Toto workflow už se opět chová očekávaně. Tedy změna položky provedená ještě v době před aktivitou InitializeWorkflow se nebere v úvahu.

    Příklad 4

    Komplikovanější scénář, ale stejný výsledek. Pokud provedete změnu záznamu ještě během úvodního čekání před vytvořením úkolu, listen aktivita proběhne větví s onWorkflowItemChanged1 aktivitou. Takže nestihnete reagovat na změnu úkolu.

    Příklad 5

    Řešení předchozího příkladu. Před listen aktivitu umístíme InitializeWorkflow a použijeme nový (jiný než WorkflowToken) token. Stejný pak použijeme v onWorkflowItemChanged1 aktivitě.

    Příklad 6

    Poslední příklad. Nejsložitější, ale nejreálnější. Čekání na změny je obalenou while aktivitou, která zajistí to, že dojde ke změně (úkolu, nebo položky), na kterou čekáme. Např. to, že úkol je dokončen, nebo že je nastavena požadovaná hodnota v nějakém sloupci. Pokud je registrována jiná změna, smyčka se vrátí zpět a čeká se znovu.

    V tomto případě jsem ještě přidal updatetask1 aktivitu do větve reagující na změnu položky. Po změně položky se tedy provede okamžitě změna úkolu a jde se na čekání na změnu. A dojde k zamknutí workflow. Tzn. další změny řeší job se zpožděním. Ale ať už provedete dále změnu úkolu z UI, nebo změnu položky, průběh workflow bude stejný. Poté, co se spustí workflow job, zpracuje se událost o změně úkolu (tu, kterou provedlo workflow samotné).

    Troubleshooting

    Chyby ve Workflow subsystému se logují do ULS logu v kategorii Workflow Infrastructure.

    Pokud ani to nestačí a potřebujete se podívat problému opravdu na kost. Můžete zapnout logování na úrovni Windows Workflow Runtime, nad kterým jsou SharePoint worklfow postavena. To uděláte úpravou konfigurace. Protože workflow je hostováno do první dehydratace v procesu W3WP.exe a po rehydrataci v procesu OWSTIMER.exe, musíte konfiguraci upravit, jak ve web.configu příslušné aplikace, tak v souboru owstimer.exe.config. Např. následující konfigurace bude do souboru WFtrace.log ukládat logování na úrovni Windows Workflow Foundation.

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <system.diagnostics>
        <sources>
          <source name="System.Workflow.Runtime" >
            <listeners>
              <add name = "System.Workflow"/>
            </listeners>
          </source>
          <source name="System.Workflow.Runtime.Hosting">
            <listeners>
              <add name="System.Workflow"/>
            </listeners>
          </source>
          <source name="System.Workflow.Activities">
            <listeners>
              <add name="System.Workflow"/>
            </listeners>
          </source>
        </sources>
        <sharedListeners>
          <add name="System.Workflow"
               type="System.Diagnostics.TextWriterTraceListener"
               initializeData="c:\WFTrace.log"
               traceOutputOptions="DateTime,ProcessId"/>
        </sharedListeners>
        <switches>
          <add name="System.Workflow.LogToTraceListeners" value="1"/>
          <add name="System.Workflow.Runtime" value="All" />
          <add name="System.Workflow.Runtime.Hosting" value="All" />
          <add name="System.Workflow.Runtime.Tracking" value="All" />
          <add name="System.Workflow.Activities" value="All" />
          <add name="System.Workflow.Activities.Rules" value="All" />
        </switches>
      </system.diagnostics>
    </configuration>

    Závěr

    Workflow ve SharePointu jsou užitečným nástrojem. Je potřeba jim ale věnovat pozornost, protože se může na první pohled chovat “podivně”. Z pohledu kolize změn a zamykání workflow je problematický souběh změn úkolu workflow a položky. Doporučuju předřazovat aktivitu InitializeWokflow všem onWorkflowItemChanged aktivitám, aby se eliminovaly některé z problematických situací. Díky tomu se z uživatelského pohledu budou posouvat workflow kupředu ihned a ne se zpožděním. Stejně tak pro úpravy úkolů doporučuji používat metodu SPWorkflowTask.AlterTask().

  • Centra schůzek a malý trik než úplně vyhynou

    Microsoft centra schůzek postupně odsouval do pozadí, až je nejspíš zařízne úplně. Pracuje na tom už od SharePointu 2010 a zejména Outlooku 2010. V Outlooku 2007 byla ikona pro připojení schůzky k centru schůzek normálně v menu. V Outlooku 2010 tam už nebyla, ale bylo možné ji tam přidat. V Outlooku 2013 už není vůbec. Existují sice komponenty 3. stran, které ji umí nahradit, ale směřování Microsoftu je zřejmé.

    Podobně je to v SharePointu samotném. Do SharePointu 2010 můžete centra normálně vytvářet. Obsahuje hned několik šablon těchto webů. V SharePointu 2013 ty šablony jsou ještě také a použitelné, ale nejsou viditelné a slouží zejména k usnadnění migrace SharePointu 2010 na novou verzi. Funkcionalita center schůzek je označená jako obsolete. Jak to dopadne v další verzi SharePointu je asi jasné, že.

    Microsoftí vysvětlení je založeno na tom, že centra schůzek jsou dnes překonaná. Doporučuje pro podporu spolupráce týmu použít normální týmový web v kombinaci se sdíleným OneNotem a Lyncem. Ideálně v prostředí Office365.

    Pro ty, kterým ale centra schůzek vyhovují, existují klony microsoftích šablon, např. na Codeplexu nebo postupy, jak si vyrobit vlastní šablony webů podobné těm standardním.

    Teď slibovaný trik. Pro mnoho uživatelů je problém připojit organizovanou schůzku k centru schůzek. A to, ať už centrum existuje, nebo si uživatel chce vytvořit nové. Problém je zejména v tom, že musí zadat URL existujícího centra, nebo webu, pod nímž se má centrum vytvořit. Problém je v tom, že obvykle nezná URL centra schůzek. Zejména, pokud k němu zatím žádnou schůzku nepřipojoval. V případě vytváření nového centra je to podobné s webem, kam centrum schůzek umístit. Situaci mu můžete zjednodušit tím, že připravíte centra pro očekávané schůzky (např. víte, že se budou ve firmě pořádat schůzky marketingového týmu). To je ale jen půlka problému. Ta další je v tom, jak uživatelům zjednodušit připojení 1. plánované schůzky v Outlooku k tomuto centru. Outlook si pamatuje, když už to uživatel jednou udělá a nabízí mu seznam. Ten je uložen v registrech, a proto s ním můžete manipulovat. Například pomocí připravených reg souborů, které distribuujete příslušným uživatelům. Ještě lepší je to pomocí doménových politik. Ty můžete cílit na skupiny uživatelů. V našem případě to budou členové marketingového týmu, zejména ti, kteří plánují schůzky. Stejně tak můžete uživateli tento seznam pročistit od už nepoužívaných center.

    Jsou v registrech na cestě HKEY_CURRENT_USER\Software\Microsoft\Office\14.0\Meetings\Profile klíč MRUInternal, typ REG_SZ a hodnota http://sp/schuzky|Schůzky|||||http://sp/schuzky/marketing|marketing||||| pro Outlook 2010. V Outlooku 2007 je tam 12.0 Nejprve je URL, pak oddělovač v podobě | , pak jméno centra a nakonec |||||.

  • Hostování workflow v SharePointu 2010 a SharePointu 2013 v modelu 2010

    V tomto článku bych se chtěl podívat blíže na to, jak jsou workflow hostována v SharePointu. Dlouho mi zůstávaly některé věci záhadou. Navíc se o nich různě píše různých místech na internetu a MSDN je na slovo skoupá. Proto jsem strávil několik večerů s iLspy v ruce a výsledky se pokusím shrnout do několika článků. Snad vám to pomůže vysvětlit některé věci a chování, které jsou jinak obtížně uchopitelné.

    Architektura

    SharePoint 2010 hostuje workflow pomocí implementace Windows Workflow Foundation z .NET frameworku 3.5. Tady si Microsoft snědl to, co si sám uvařil. A protože jsem Workflow Runtime implementoval i samostatně, tak si troufnu říct, že docela dobře.

    SharePoint 2013 uvádí jako jednu z novinek podporu Workflow Runtime z .NET frameworku 4.5. Je to řešeno externě pomocí samostatného Workflow Manageru. Bohužel je dostupný pouze v SharePoint Serveru 2013. V SharePoint Foundation 2013 máte smůlu. Nicméně SharePoint 2013 obsahuje i model provozování workflow z SharePointu 2010. Je tam z kompatibilních důvodů, ale v SharePoint Foundation 2013 nemáte ani jinou možnost.

    Tento článek je proto platný i pro SharePoint 2013. Pro SharePoint Foundation 2013 zcela a pro SharePoint Server 2013 pro workflow provozovaná v modelu 2010.

    Z obrázku je vidět, že SharePoint funguje z pohledu Windows Workflow Runtime dvěmi způsoby:

    • Jednak implementuje služby jako PersistenceService, která se stará o dehydrataci (tedy persistenci workflow po dobu, kdy aktivně neběží) a o rehydrataci, tedy o nahrání workflow z úložiště do paměti.
    • A také jako externí služba. Externí služby obecně slouží pro volání externího kódu, který není přímo součástí workflow, ale také pro registraci událostí, které až nastanou, tak se ve workflow obslouží.

    Pro persistenci instance běžícího workflow do databáze (tzv. dehydrataci) se používá XML serializace. Rehydratace odpovídá pro změnu XML deserializaci. Při deserializaci instance workflow z databáze do paměti je nezbytné, aby persistovaný tvar odpovídal tomu, co má SharePoint k dispozici. Jinými slovy XML uložené v databázi musí odpovídat třídě, která reprezentuje workflow v DLL. Může se vám stát, že provedete změny kódu workflow, které povedou k tomu, že SharePoint nedokáže pomocí definice třídy v DLL a XML v databázi znovuvytvořit objekt workflow. V takovém případě workflow zůstane ve stavu Probíhá a už se nikdy nepohne z místa. Situace je o to horší, že se o tom nedozvíte a SharePoint se bude v pravidelných intervalech, bez naděje na úspěch, pokoušet workflow oživovat.

    SharePoint workflow mohou pracovat s daty (vytvářet, měnit a mazat položky a úkoly) v SharePointu a reagovat na události (změna položky, změna úkolu), které se v něm nastanou. Slouží k tomu aktivity:

    • CreateTask, CreateTaskWithContentType, UpdateTask, DeleteTask, UpdateItem, … - pro manipulaci s daty workflow
    • OnWorkflowItemChanged, OnTaskCreated, OnTaskChanged, … - pro obsluhu událostí v SharePointu

    Zmíněné aktivity využívají služeb SPWinOeTaskService a SPWinOeWSSService obě jako potomci třídy ExternalDataExchangeService. Obě komunikují s SPWinOeHostService což je SharePointí interface pro komunikaci s Workflow Runtime.

    Event receivery

    Jako zdroje událostí používá SharePoint event receivery. Stejně tak je využívá pro automatické spouštění workflow při založení nebo změně položky. Když se seznamem asociujete workflow, SharePoint na tomto seznamu registruje SPWorkflowAutostartEventReceiver, který obsluhuje události ItemAdded a ItemUpdated a v nich podle definice prostřednictvím objektu SPWorkflowManager spouští instance workflow. K zachycení událostí o změně úkolů nebo položky, nad níž běží, registruje SharePoint při spuštění workflow SPWinOEItemEventReceiver.

    Proto, aby se nestalo, že při výpadku systému dojde ke ztrátě informací o událostech v SharePointu, jsou informace uloženy v tabulce SheduledWorkitems v obsahové databázi. Po doručení je smažou.

    Joby

    Může se stát, že informaci o události není možné doručit instanci workflow “online”. Pro tyto situace má SharePoint naplánovaný job (SPWorkflowJobDefinition), který frontu událostí zpracovává asynchronně. Tento job je standardně naplánovaný každých 5 minut. Proto může workflow za určitých okolností reagovat na události se zpožděním.

    Dále SharePoint používá SPWorkflowFailOverJobDefinition. Tento job se pokouší rozběhnout instance workflow, které selhaly z “vnějších” příčin. Tedy např. neběžící SQL, síťové problémy a podobně.

    Posledním jobem souvisejícím s workflow je poněkud kontroverzní job SPWorkflowAutoCleanJobDefinition. Cílem tohoto jobu je mazat informace workflow, které byly ukončeny (doběhly, nebo spadly), a uvolnit prostor v databázi. Standardně se tak děje po 60 dnech od ukončení. Nepříjemné na tom je, že jsou smazány informace o běhu workflow, ale i vytvořené úkoly. Pokud chcete po 60 dnech něco z toho dohledat, máte smůlu. Perličkou je, že historie běhu workflow v databázi zůstane, ale už se k ní jinak než v databázi nedostanete. A hromadí se v tabulce alluserdata s ostatními užitečnými položkami. Záznamy historie workflow jsou totiž také položky v seznamu. Sice v trochu speciálním seznamu, ale seznamu.

     

    Zajímavostí pro mě bylo zjištění, že úkoly vytvořené pomocí CreateTaskActivity se fakticky vytvoří až v okamžiku dehydratace workflow.

    Workflow může během svého života vytvořit, měnit a případně reagovat na změnu mnoha úkolů. K tomu, aby si SharePoint udržel vazbu mezi aktivitami, které pracují se stejným úkolem, používá tzv. correlation tokeny. S nimi je spojena celá řada potíží a na ně se, stejně jako na další věci, které se mohou pokazit, podíváme v dalším článku.

  • Různé metody aktualizace položek SharePointu v kódu

    SharePoint nabízí hned několik metod pro aktualizaci záznamů. Pokud se budeme bavit o serverovém objektovém modelu, tak tři. Tedy metody třídy SPListItem:

    • Update()
    • SystemUpdate(bool incrementListItemVersion)
    • UpdateOverwriteVersion()

    Protože se o nich nejen v MSDN píše celá řada různých informací často si protiřečících informací, rozhodl jsem se je prozkoumat a navzájem porovnat jejich chování.

    Můžeme začít pohledem dovnitř:

            public override void Update()
            {
                this.UpdateInternal(false, false, Guid.Empty, false, false, false, false, false, false, false);
            }
            public void SystemUpdate()
            {
                this.UpdateInternal(true, false, Guid.Empty, false, false, false, false, false, false, false);
            }
            public void SystemUpdate(bool incrementListItemVersion)
            {
                this.UpdateInternal(true, !incrementListItemVersion, Guid.Empty, false, false, false, false, false, false, false);
            }
            public void UpdateOverwriteVersion()
            {
                this.UpdateInternal(false, false, Guid.Empty, false, false, true, false, false, false, true);
            }

    Když byste postupovali dále, zjistíte, že i další zanořování je stejné a končí u volání nemanageovaného kódu.

    Zkoumal jsem zmíněné metody z pohledu zvedání verze, změny informace o čase poslední změny a informace o tom, kdo ji provedl. Dále pak, jestli se při použití odešle notifikace, spustí zaregistrovaný event receiver a posune běžící workflow.

    Všechny testy jsem dělal jak nad seznamem, tak nad knihovnou dokumentů, protože jsem se opakovaně přesvědčil, že některé věci na nich fungují různě.

    A zde je výsledek. X znamená, že daná metoda způsobí sledované chování.

      Zvednutí verze Změna modified Odeslání notifikace Posunutí workflow Reakce EventReceiverů
    Update

    X

    X

    X

    X

    X

    SystemUpdate    

    při přidání

    X

    X

    SystemUpdate(true)    

    při přidání

    X

    X

    UpdateOverwriteVersion

     

    X

    X

    X

    X

    EventFiringEnabled = false; a Update()

    X

    X

         

    Zhodnocení

    1. SystemUpdate se chová stejně, ať mu pošlete jakýkoliv parametr. S parametrem true by měl zvednout verzi, ale nedělá to.
    2. Protože posunutí workflow je vnitřně implementováno pomocí event receiverů, mají oba sloupce (Posunutí workflow a Reakce Eventreceiverů) stejné hodnoty v jednotlivých řádcích.
    3. Jako zajímavost hodnotím chování metody SystemUpdate. Neměla by posílat notifikace, ale když ji použijete pro vytvoření položky, notifikace se pošle. Při aktualizaci položky touto metodou se notifikace nepošle.

    Závěr

    Každá metoda se chová trochu jinak a hodí se proto v jiných situacích.

    Z pohledu uživatele je důležité, jestli dostávám notifikace o důležitých změnách. O změnách položek nutných pro běh systému ale mě nepostřehnutelných naopak nechci být informován. Mohou mě to přímo spamovat.

    Také je důležité si při provádění změn rozmyslet, jestli se má jako reakce na změnu posouvat, či spouštět workflow. Pokud ne, je potřeba kód změny zavolat s nastavením EventFiringEnabled na false.

  • Zrušení autohosted módu pro SharePoint apps

    Tohle je téměr měsíc stará informace, která by mohla docela dobře zapadnout. Vzhledem k tomu, že SharePoint 2013 v ČR moc rozšířený zatím není a autohosted mod nebyl nijak rozšířený ani celosvětově, tak se u nás moc "truchlících" asi nenajde.

    Jen pro připomenutí. Autohosted apps byly ty apps, které v sobě obsahovaly kód, který se v rámci nasazení app nasazoval do Azure Web Sites. To s sebou přinášelo dost omezení.

    Pokud se SharePointem 2013 začínáte, tak tuto variantu můžete zatím přeskočit. Zatím píšu záměrně, protože blog Office 365 týmu, který informaci zveřejnil, naznačuje, že to nemusí být navždy. Budou totiž zapracovávat zpětnou vazbu vývojářů a do konce roku slibují něco nového.

    V případě, že nějakou takovou app máte, existuje popis, jak ji přepsat na provider hosted app. To znamená, že dále poběží v Azure, ale do SharePointu se bude instalovat v jiném režimu a její deploy do Azure budete muset řešit samostatně. I v tomto scénáři, tedy provider-hosted app běžící v Azure, slibují další rozvoj a vylepšení. Uvidíme, snad to bude stát za to.

    Běžící autohosted apps zatím nebudou vypínány ani omezovány.

  • Sloupce, vlastnosti a metadata dokumentů

    Tak jsem opět řešil technologickou výzvu SharePointu. Před časem jsem psal článek o procesu mapování sloupců na metadata souborů v SharePointu včetně hodnot. Tentokrát jsem potřeboval vyřešit otázku, jak do SharePointích metadat souboru uložit informace tak, aby neovlivnily obsah souboru. Cílem bylo neporušit elektronické podpisy souborů.

    Je totiž zřejmé, že některé typy sloupců SharePoint “nepropisuje”. Jedná se o typy jako stav workflow (SPFieldWorkflowStatus) a vypočítané sloupce (SPFiedlCalculated). Pokoušel jsem se proto vytvořit sloupce těchto typů, ale první z nich nelze přidat ani programově a do druhého nelze zapisovat hodnoty. Ani vytvoření potomků nepomohlo. U SPFiedlCalculated nelze potomka ani rozmně vytvořit, protože nemá žádný veřejný konstruktor.

    Jako další věc jsem zkoušel zpětně přeložit standardní SPDocumentParser, abych se podíval, čím a jak se řídí. Bohužel je to jen .NET obálka COM objektu a veškerá logika je nedostupná uvnitř COMu. Takže jsem se nic nedozvěděl.

    Použití propertybagu, tedy kolekce Properties taky nevedla k úspěchu ani u Itemu ani u File. V obou případech přidání nového páru klíč-hodnota vedlo k tomu, že pár byl přidán i do metadat souboru, což vedlo ke zneplatnění podpisu.

    Nakonec jsem si ale všiml, že některé vlastnosti z propertybagu mají různé předpony jako “ows_” a “vti_”. Tak jsem to zkusil taky a výsledek se podařil. Při použití prefixu “vti_” v klíči nedojde k přenosu vlastnosti do souboru. Zkusil jsem to i pro název sloupce, ale pokus o přidání sloupce s prefixem “vti_” skončí chybou, že takový sloupec už v seznamu existuje a nelze ho proto přidat. A to i v případě, že za předponou zadáte náhodnou posloupnost znaků, která v knihovně určitě není.

    Je potřeba si ale uvědomit, že jde o chování standardního SPDocumentParseru, který se týká Office dokumentů. Pokud máte v SharePointu registrovaný i jiný document parser, nemusí se chovat stejně. Záleží to na jeho implementaci.

  • Skupiny v SharePointu

    Skupiny mohou pocházet z 3 zdrojů:

    1. SharePointu samotného
    2. Active Directory
    3. Formulářového ověřování – role provider

    Každý z těchto zdrojů má určitá specifika.

    SharePoint skupiny

    Dají se spravovat v SharePointu, tzn., není potřeba práva správce AD. To je někdy výhoda (správci AD klidně spí), někdy nevýhoda. Nemají dosah jinam než v rámci kolekce webů. Pokud je chcete používat v různých kolekcích webů, musíte si je vytvořit několikrát a členy jejich skupin nějak synchronizovat. Časem se může ukázat, že pro vytvořenou skupinu potřebujete navíc nastavit i práva třeba na report serveru nebo disku a to s SP skupinou neuděláte. Můžete si sice vytvořit stejně pojmenovanou v AD, ale nebudou propojené. Skupiny v SP nemohou obsahovat jiné skupiny z SP, mohou ale obsahovat skupiny z AD nebo FBA.

    Active directory skupiny

    Dají se spravovat v AD a používat v několika systémech. Můžete mít jedné skupině udělit práva v SP, použít ji v nějakém procesu a současně jí nastavit práva na Report serveru. AD skupina může obsahovat jinou skupinu. AD skupiny se ještě mohou dělit na:

    • Tzv. security groups – “klasické” skupiny z AD. Primárně slouží k nastavování práv.
    • distribution groups – původně sloužily jako adresáti mailů nějaké skupině adresátů. Maily pak byly doručeny jejím členům. Pochází z Exchange serveru.

    Rozdělení dnes spíše historické, rozdíly mezi nimi se zmenšují. Security skupiny může mít email a sloužit k distribuci emailů a stejně tak dnes můžete distribuční skupině nastavit práva.

    Problém skupin z AD je v tom, že často nejsou v pořádku. Nejsou aktuální, nereflektují strukturu organizace, změny jsou pomalé, … To vede v úvahu spravovat si skupiny samostatně v SP. To ale vede k dalším problémům. Jednak je potřeba udržovat alespoň trochu podobnou strukturu 2x (AD a SP) a druhak se uživatelům nabízí potenciálně 2 stejně nebo podobně pojmenované skupiny. Jedna z AD a druhá z SP. To uživatele pochopitelně mate a zákonem schválnosti si stejně vyberou tu špatnou. Naštěstí se to dá vyřešit omezením nabízených skupin a uživatelů.

    FBA skupiny

    Za jejich správu je zodpovědný RoleProvider. SharePoint se k doménovým a FBA skupinám chová zvláštně. Vidíte je v seznamu skupin (poté, co ji někde v SP použijete), ale když na ni kliknete, zobrazí se vám detail uživatele (stránka /_layouts/userdisp.aspx). Zatímco detaily skupin zobrazuje stránka /_layouts/people.aspx. Souvisí to s tím, že k doménovým a FBA skupinám se SharePoint staví jako k uživatelům. Proto je nenajdete v kolekcích  nebo SPWeb.Groups. Místo toho je najdete v kolekci SPWeb.AllUsers a poznávacím znamením je vlastnost SPUser.IsDomainGroup. A u ní je ale problém v tom, že je true i pro FBA skupiny, takže by se spíše měla jmenovat IsNonSpGroup.

    Zvláštní disciplínou je zjišťování členů skupiny. U SharePoint skupin lze zjistit členy pomocí kolekce SPGroup.Users. Ale i u získaných uživatelů musíte zkontrolovat vlastnost IsDomainGroup, jestli jsou to opravdu uživatelé, nebo “převlečené” AD nebo FBA skupiny. SP skupiny to být naštěstí nemůžou.

    Pro zjišťování členů Active directory skupin a FBA skupin je možné použít metodu

    public static SPPrincipalInfo[] SPUtility.GetPrincipalsInGroup(SPWeb web, string input, int maxCount, out bool reachedMaxCount)
    .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

    input parametr je jméno skupiny. U AD skupin stačí zadat jejich jméno. U FBA skupin je potřeba předat v Claims tvaru, tedy: c:0-.f|provider|jménoskupiny, to proto, že z něj SharePoint určí Role providera, u kterého má členy zjistit. Uvedenou metodu lze použít i na SharePoint skupiny. Zmíněnou metodu je nutné volat rekurzivně tak dlouho, až si budete jisti, že vše, co vám vrátila, jsou uživatelé a ne další skupiny.

    Má ale jednu nepříjemnou vlastnost. Jedním z parametrů je maxCount. Tím je možné se bránit tomu, aby rozpad velkých AD skupin netrval nekontrolovaně dlouho. Takže zadáte, kolik jich chcete vrátit maximálně a v posledním out parametru vám SP dá vědět, jestli dosáhl onoho maxima. Bohužel udělá přesně toto. Tzn., pokud jako maxCount zadáte 30 a členů je přesně 30, vrátí vám reachedMaxCount true. Pokud jich bude existovat 31, bude výsledek stejný. Jinými slovy: z hodnoty reachedMaxCount nepoznáte, jestli vám nějaký člen unikl a je potřeba hledat dále, nebo jste je získali všechny a je jich přesně tolik, kolik jste hádali jako maximum. Sad smile

    Na závěr se ještě zmíním o “speciálních” skupinách, které reprezentují:

    • Všechny uživatele SP -
      c:0!.s|true
    • Všechny Windows uživatele -
      c:0!.s|windows
    • Všechny uživatele membership providera (FBA) -
      c:0!.s|forms:membershipprovider

    U nich se členové zmiňovanými způsoby zjišťovat nedají. O to se lze pokusit procházením kolekce SPWeb.AllUsers a testováním tvaru loginu. Jestli obsahuje stejný prefix. Nicméně takto nezjistíte všechny uživatele určitého typu, ale jen ty, kteří byli na webu někdy použiti (ve sloupci typu uživatel nebo mají nastavena práva), nebo na web jako autentizovaní přistoupili.

  • Anonymní přístup do SharePointu

    Anonymní přístup není úplně obvyklý scénář použití SharePointu ve firemním prostředí, ale jsou situace, kdy se bez něj neobejdete. Například v případě, že chcete SharePoint použít jako veřejně dostupný web. Anonymní přístup se dá kombinovat s Windows i formulářovým ověřováním (FBA), včetně jich obou. V takovém případě jste schopni dosáhnout situace, kdy některé části SharePointu jsou dostupné jen Windows ověřeným uživatelům (obvykle interním zaměstnancům), jiné mohou být přístupné uživatelům ověřeným pomocí FBA. A něco můžete zpřístupnit i uživatelům, kteří se nepřihlásí vůbec.

    V tomto článku si ukážeme, jak se anonymní přístup zapíná, konfiguruje a jaké má další vlastnosti.

    Konfigurace

    Zapíná se na úrovni webové aplikace, podobně jako jiná nastavení autentizace.


    Pak je potřeba zapnout přistup na webové aplikaci v Zásadách pro anonymní přístup. Tím se dá umožnit anonymní přístup pouze pro určité zóny. Dá se:

    • žádné - řešit si to budou jednotlivé weby, listy a položky.
    • odepřít zápis – v takovém případě mohou anonymní uživatelé pouze číst. Paušálně pro celou zónu aplikace.
    • odepřít vše - např. chci zakázat anonymní přístup uživatelům intranetu, ale v extranetu povolit.

     

    Nastavování oprávnění

    Na úrovni webů (sekce Oprávnění webů) můžete nastavovat práva jako obvykle.

    Nově ale najdete v ribbonu tlačítko anonymní přístup, které umožní nastavit obecně přístup. Máte následující možnosti:

    • Celý aktuální web – bez přihlášení mohou uživatelé přistupovat jak k seznamům, knihovnám i stránkám. Samozřejmě jen k těm, u kterých to nastavíte v oprávnění.
    • Seznamy a knihovny – anonymní přístup je povolen jen ke knihovnám dokumentů a seznamům. Stejně jako v předchozím bodě se konkrétní přístup nastavuje v oprávněních vybraných seznamů a knihoven.
    • Nic – nepřihlášení uživatelé nemají k této kolekci webů přístup.

    Dokud ho tady nepovolíte, na webech se v nastavení práv nic neobjeví a ani není možnost se na nich nepřihlásit.

     

    Nepřihlášení uživatelé mají v ribbonu nastavování práv seznamů a knihoven dokumentů zvláštní tlačítko Anonymní přístup, podobně jako při nastavování oprávnění webů.

    Na úrovni seznamů se dá nastavovat jen omezený výčet oprávnění:

    • Přidat položky
    • Upravit položky
    • Odstranit položky
    • Zobrazit položky

    Nelze využívat jiných natož vlastních úrovní oprávnění.

    V knihovně lze nastavit jen zobrazení položek.

    Anonymní uživatelé nemohou mít práva na jednotlivé položky. Lze ale využít následujícího triku:
    Anonymní uživatel má přístup na úrovni Omezený přístup. Pokud tedy na seznamu povolíte přístup anonymním uživatelům, ale na konkrétních položkách přerušíte dědění, nebudou mít k těmto položkám anonymní uživatelé přístup.

    Další postřehy:

    • Spuštění WF vyžaduje přihlášení. Jde o to, že stránky ohledně WF vyžadují autentizaci.
    • Anonymní uživatel sice vidí ikonu Otevřít v průzkumníkovi, ale bude ho to nutit přihlásit se.
    • Anonymní uživatel nemůže nastavovat pole uživatel nebo skupina, nemá tam totiž people picker, ale hlášku “Ovládací prvek není k dispozici, protože nemáte příslušná oprávnění”.

    Poznámky z pohledu programátora

    • Dejte si pozor na to, že pokud není uživatel přihlášen, v SPWeb.CurrentUser je null.
    • Jestliže potřebujete vytvořit aplikační stránku, která nebude vyžadovat přihlášení, musíte ji odvozovat od UnsecuredLayoutsBasePage místo LayoutsBasePage a je potřeba přetížit vlastnost AllowAnonymousAccess tak, aby vracela true.
    • Práva anonymním uživatelům se nastavují pomocí AnonymousPermMask64 - to je maska práv. V knihovnách dokumentů platí, že nelze povolit přidávání, editaci a mazáni. I když to v kódu nastavit lze, nebude to fungovat.
    • Vlastnost AnonymousPermMask64 je dostupná pouze na třídách SPWeb a SPList, viz informace o tom, že nelze nastavovat práva na jednotlivých položkách.
    • Pomocí SPList.AnonymousPermMask64 = SPBasePermissions.EmptyMask; odstraníte veškerá práva nepřihlášených uživatelů k objektu.
    • Použití <UserID>, tedy odkaz na aktuálního uživatele, v CAML dotazu způsobí výzvu k přihlášení uživatele.
    • Ve sloupcích Author a Editor jsou hodnoty "-1;#" ze které nevyrobíte objekt typu SPUser.
  • SharePoint 2013 ServicePack 1

    Před časem vyšel service pack pro Office 2013. V rámci balíku service packů vyšel i service pack 1 pro SharePoint.

    Stáhnout jej můžete z této stránky, kde najdete service packy pro jednotlivé verze:

    • SharePoint Foundation
    • SharePoint Server
    • Project Server
    • Office Web Apps

    Upřímně řečeno jsem docela zklamaný z toho, co obsahují. Pročítal jsem k němu KBčka, zkoušel jsem ho, ale nic zásadního z pohledu nových funkcí jsem nenašel. V podstatě jde o:

    • lepší podporu IE 11
    • propojení účtů uživatelů onpremise a OneDrive for Business
    • možnost instalace na Windows 2012 R2. To je ale zatím jen teoretická šance, protože jde o SP1. Takže byste museli nejprve nainstalovat SharePoint na Windows 2012 R2 bez SP, což se vám nepodaří. A pak na něj nainstalovat SP1. Dokud nebude dostupná instalace včetně SP1, není tato novinka použitelná. EDIT – tak instalace včetně SP1 jsou už dostupné viz komentáře. Díky za upozornění.

    Jinak jde vlastně o souhrn všech předchozích kumulativních updatů, tedy opravy chyb. Nicméně i za to jsem rád. Vzhledem ke svým špatným zkušenostem s instalací kumulativních updatů dávám přednost instalaci SP. Detailní popis změn (nejen SharePointu, ale i Office) najdete v tomto excelu.

    Protože už uplynulo několik týdnů od vydání, zdá se, že to dobře otestovali a že se nedočkáme opětovného vydání, případně stažení a opětovného vydání, jako se to stává u kumulativních updatů.

    Instalace sama je rychlá a nesetkal jsem se s žádnými potížemi.

    Takže zálohujte servery, proveďte instalaci na všech strojich ve farmě a nezapomeňte spustit PSConfig.

  • Konfigurace výběru uživatelů

    V Sharepointu mohou uživatelé vybírat jiné uživatele pomocí tzv. people pickeru, tedy prvku pro výběr uživatelů. Typicky při nastavování práv nebo v uživatelském sloupci Uživatel nebo skupina. Sloupec můžete nakonfigurovat aby umožnoval vložit jen uživatele, nebo uživatele a skupiny.

    Pokud máte na SharePointu zapnutou form based autentizaci (FBA) s membership providerem, mohou uživatelé pocházet z:
    • domény
    • FBA
    a skupiny z:
    • domény
    • FBA
    • SharePointu samotného

    Někdy je užitečné, nebo dokonce nutné omezit výběr nabízených skupin a uživatelů z domény. Např. pokud máte několik domén se stejnými uživateli, může se stát, že uživatel zadá do prvku pro výběr uživatele nebo skupiny jméno “Jan Novák” a nabídnou se mu 2. Jeden bude pocházet z domény A a druhý z domény B. Který je správný ale uživatel nepozná nepozná a může být problém.

    Pro omezení toho, co people picker nabízí má SharePoint několik nastavení. Dejte si pozor na to, že některá z nich ovlivňují chování pole pro zadávání uživatelů, jiná ovlivňují vyhledávací dialog a jiná obojí. Další problém je, že MSDN dokumentace je někdy zavádějící a na různých místech uvádí různý význam některých parametrů.

    Omezení výběru uživatelů jen na ty, kteří mají nějaká práva na kolekci webů

    Nastavení pro tlačítko Kontrola jmen:
    stsadm -o setproperty –pn peoplepicker-Peopleeditoronlyresolvewithinsitecollection –pv yes –url <URL webové aplikace>

    Nastavení pro okno Procházet:
    stsadm -o setproperty –pn peoplepicker-onlysearchwithinsitecollection –pv yes –url <URL webové aplikace>

     

    Omezení výběru uživatelů (a skupin) jen ze zadané organizační jednotce (organization unit)

    Užitečné, když chcete například zabránit používání AD skupin. Uživatele, které chcete používat, přesunete do k tomu účelu vytvořené organizační jednotky, ale nebude v ní mít žádné skupiny.

    stsadm -o setsiteuseraccountdirectorypath -path <Valid OU name> –url <Site Collection URL>

    Příklad: stsadm -o setsiteuseraccountdirectorypath -path "OU=Sales,DC=ContosoCorp,DC=local" –url http://Server/sites/sitecoll

    Oproti ostatním se nastavuje na úrovni kolekce webů. Pozor: hodnotou je jen 1 organizační jednotka, ne více!

    Toto nastavení ovlivňuje jak tlačítko Kontrola jmen, tak okno Procházet.

     

    Omezení výběru pomocí LDAP dotazu

    Někdy je potřeba omezit výběr např. jen na uživatele, ne skupiny a podobně. Toto je nejflexibilnější nastavění, ale pozor: Toto nastavení ovlivňuje pouze okno Procházet! Ne Kontrolu jmen. Sad smile 
    Tedy to tvrdí MSDN. Článek je sice o SP 2007, ale odkazují se na něj i články o SP 2010. Naštěstí to platí jak pro oba typy výběru uživatelů. Vyzkoušeno.

    Stsadm –o setproperty –pn peoplepicker-searchadcustomfilter -pv <LDAP dotaz> -url <URL webové aplikace>

    Základy LDAP můžete najít zde.

    Příklad (vrátí pouze aktivní uživatele, ne skupiny):

    stsadm -o setproperty -pn peoplepicker-searchadcustomfilter -pv "(&(objectCategory=person)(objectClass=user)(!userAccountControl:1.2.840.113556.1.4.803:=2))" -url http://Server

    Omezení výběru jen na FBA uživatele

    Hodí se v situaci, kdy máte SharePoint v doméně (téměř vždy, kvůli administraci), ale SharePoint uživatele spravujete pomocí FBA a jen s nimi chcete pracovat.

    stsadm -o setproperty -pn peoplepicker-nowindowsaccountsfornonwindowsauthenticationmode -pv yes -url <URL webové aplikace>

    Toto nastavení ovlivňuje jak tlačítko Kontrola jmen, tak okno Procházet.

     

    Než začnete některou z vlastností měnit, určitě si uložte původní hodnotu. Tu zjistíte příkazem:

    stsadm -o getproperty –pn <jméno vlastnosti>

  • Podivnosti metody EnsureUser

    EnsureUser je užitečná metoda objektu SPWeb, která vám najde uživatele podle zadaného jména. A nejen to, pokud není dosud v na webu evidovaný, tedy není v seznamu uživatelů webu, tak jej tam přidá.

    Její prototyp je SPWeb.EnsureUser(string logonname) s návratovou hodnotou typu SPUser. Podle MSDN má být logonname ve tvaru domain\username, a když uživatel neexistuje, vyhodí vyjímku. Jenže co při použití claims autentizace? A pokud navíc ještě mám vlastní membership provider?

    Pojďme se na podívat postupně.

    Pokud požíváte pouze Windows autentizaci, máte celkem klid, metoda se chová podle MSDN. Ověří, jestli uživatel existuje. Pokud ano, vrátí vám ho a případně (jestli už tam není) ho přidá do seznamu uživatelů webu.

    Pokud máte zapnuté claims identity a FBA, začne se to komplikovat:

    1. Ve webpartech a jiném webovém kódu metoda funguje dobře. Ověří login pomocí membership providera a domény, jestli uživatel existuje a případně ho přidá mezi uživatele webu. V parametru snese oba formáty loginu, tedy claims(”i:0#.f|mymembershipprovider|username” – ”i:0#.w|domain\username”) i jednoduchý (”login” -”domain\username”).
    2. V event receiverech, jobech a PowerShellu se začne chovat divně. Když použijete jednoduchý formát, bude vám o všech FBA uživatelích tvrdit, že neexistují. Takže musíte použít claims tvar. Pak ale přestane existenci uživatele kontrolovat a přidá uživatele do seznamu uživatelů webu, i když neexistuje. A vrátí vám spokojeně jeho objekt. Takto “založený” uživatel se nemůže přihlásit, protože neexistuje v doméně ani v membership provideru. Uživatelé ho nemohou použít v people pickeru, ale váš kód s ním pracovat může a například takovému uživateli vytvoří úkol. Sad smile

    Při analýze vykonávaného kódu jsem zjistil, že v prvním případě se SharePoint snaží najít uživatele nejen v doméně, ale i u membership providera voláním metod GetUser, FindUsersByEmail a FindUsersByName. Z toho plyne, že parametrem metody nemusí být nutně jen username. V druhém případě se metody membership providera nevolají.

    Závěr:

    Při použití FBA autentizace a uživatelů si musíte nejprve sami prostřednictvím membership providera ověřit, jestli daný uživatel existuje. A teprve v kladném případě můžete zavolat EnsureUser metodu. Ta vám jej ”zaeviduje” na webu a vrátí jeho SPUser objekt. Můžete si na to vytvořit vlastní Ensure metodu, ideálně jako extension metodu SPWeb objektu.

  • Potíže s datovým listem

    Datový list je oblíbeným způsobem jak provádět hromadné úpravy v seznamech a knihovnách dokumentů. Má ale několik omezení:

    1. Pro práci s ním musíte mít lokálně nainstalovaný Access – je to totiž vlastně jen Access zobrazení SharePointího seznamu, resp. datový zdroj otevřený v Accessu.
    2. Prohlížeč musí podporovat ActiveX (takže jen Internet Explorer) a musí odpovídat bitová verze prohlížeče a Accessu, tedy 64b - 64b a 32b – 32b. O těchto potížích jsem psal dříve.
    3. Omezeně pracuje s vlastními typy sloupců – pokud máte naprogramovaný vlastní prvek pro práci s hodnotou, bude vám v tomto případě k ničemu.
    4. Nereflektuje úpravy formulářů ani vlastní formuláře – jde totiž o syrovou úpravu dat.
    5. Má potíže s povinnými poli v typech obsahu – problém se projevuje, když máte v seznamu několik typů obsahu s různými povinnými poli. Datový list požaduje vyplnění všech, bez ohledu na to, že typ obsahu aktuálního řádku požadovaný sloupec neobsahuje. Řešení, které se nabízí, je dočasně nastavit všechny sloupce jako nepovinné. Ale ani to není tak jednoduché. Nastavení na úrovni seznamu totiž u webových typů obsahů (a tedy i webových sloupců) nezabere. Dokonce ani nastavení povinnosti na úrovni webového typu obsahu (resp. jeho sloupců) nepomůže. Až nastavení webového samotného sloupce řeší náš problém. Má to ale neduh. Změna webového sloupce ovlivní všechna jeho použití, tedy nejen náš typ obsahu, ale i všechny ostatní typy obsahu a všechny seznamy, kde je sloupec použitý.
  • Odkazy v datech SharePointu a maily

    SharePoint umožňuje vkládat do uživatelských dat odkazy. Jednak do sloupců typu odkaz, ale i do sloupců typu víceřádkový text. Má to ale několik záludností. Jednou z nich je fakt, že pokud SharePoint usoudí, že odkaz směřuje do něj samotného, odřízne z odkazu serverovou část. Udělá z něj tedy relativní odkaz (server relative). To je důležité proto, že každá webová aplikace SharePointu může mít několik adres. Ty se nastavují v centrální administraci v sekci Mapování alternativních adres URL. A aby odkazy fungovaly ze všech, nesmí být absolutní. Ve webovém rozhraní to funguje dobře. Problém nastává v okamžiku, kdy se takto upravené odkazy mají objevit např. v emailech. V notifikacích to má SharePoint vyřešeno tak, že při vytvoření notifikace si uloží i právě použitou adresu serveru a tu pak použije v okamžiku odesílání emailu. Tomuto chování jsem se věnoval dříve. Pokud ale chcete emaily odesílat vy, například v jobu, musíte to vyřešit vlastním způsobem. Pro inspiraci nabízím:
    Regex r = new Regex("href=\u0022/");
    string output = r.Replace(inputString, "href=\u0022" + site.WebApplication.Sites[0].Url + "/");

    Nicméně toto řešení není 100%, protože relativní odkazy doplní o výchozí adresu webové aplikace z níž položka pochází, což nemusí vyhovovat všem uživatelům. Obecně je problém v tom, že nevíte jakou adresu používá uživatel, kterému notifikaci posíláte, k přístupu na SharePoint.

  • Propojení metadat dokumentů a sloupců knihoven dokumentů v SharePointu

     

    SharePoint umožnuje ukládat do knihoven dokumentů soubory a definovat jim vlastnosti (metadata), které je pak možné využít k organizaci souborů, vyhledávání a ve workflow. Tato metadata se nestávají součástí dokumentů. Jsou uložené v databázi SharePointu. Mnoho formátů souborů má vlastní metadata, uložená přímo v nich. U obrázků to jsou typicky souřadnice pořízení, datum pořízení, expozice a mnoho dalších. U Office dokumentů jsou to pro změnu klíčová slova, autor, počet stránek, nadpis dokumentu, popis, … Můžete si dokonce definovat vlastní metadata a od formátu 2007 (tedy přípony jako jsou DOCX, XSLX, PPTX) můžete tato metadata umístit do těla dokumentu. Takže, když budete mít svou vlastnost např. číslo faktury, tak se to číslo může objevit přímo v textu dokumentu. A v případě změny vlastnosti dokumentu dojde při prvním otevření dokumentu k aktualizaci I v textu. Může to fungovat i obráceně. Tedy, že se text vepsaný na určité místo “propíše” do vlastnosti dokumentu.

    Jak jsem se zmínil, SharePoint automaticky nepropojuje vlastnosti, které u souborů eviduje, s vlastnostmi dokumentů samotných. Je to hlavně proto, že způsob ukládání vlastností v dokumentech se liší formát od formátu. Nicméně v případě Office formátů k tomu dochází. To znamená, že pokud do knihovny dokumentů uložíte Office dokument a určíte mu vlastnosti (typicky určením typu obsahu) SharePoint je automaticky přidá k uživatelským vlastnostem dokumentu. Totéž se stane v okamžiku, kdy typu obsahu definujete nějaký Office dokument jako jeho šablonu.

    Při stažení (otevření) dokumentu se pak aktualizuje nejen seznam vlastností Office dokumentu, ale i jejich hodnoty. Jinými slovy, při stažení dokumentu SharePoint provede kontrolu uživatelských vlastností dokumentu a doplní k nim chybějící z knihovny dokumentů. Současně aktualizuje hodnoty těchto vlastností tak, aby odpovídaly hodnotám vlastností daného dokumentu v knihovně. Při nahrání dokumentu do SharePointu probíhá aktualizace vlastností stejně, ale přenos hodnot je opačný, tedy z metadat dokumentu do vlastností v SharePointu.

    Ukládání vlastností u Office dokumentů je vyřešeno tak, že se u každé vlastnosti kromě jejího InternalName a DisplayName ukládá její “původ”. Tím je GUID typu obsahu, nebo GUID seznamu. Díky tomu je zajištěno, že i kdyby dokument prošel několika SharePointy a ty měly stejně pojmenované sloupce, SharePoint s nimi bude zacházet jako s různými vlastnostmi. Díky tomu schválení dokumentu v jednom SharePointu nebude znamenat, že je dokument schválený i v druhém. SharePoint připouští, aby dokument měl jen 1 sadu vlastností. Pokud tedy zjistí, že už nějakou obsahuje, smaže ji a nahradí aktuální. Sloupce, které reprezentují stav workflow se do dokumentu “nepropisují”.

    Důležitým aspektem tohoto mechanizmu je, že se spouští asynchronně po nahrání dokumentu do knihovny. Z toho plyne fakt, že se může stát (a mě se opakovaně stávalo např. u InfoPath dokumentů) situace, kdy se vám spustí např. workflow při vložení dokumentu, ale ve SharePointích vlastnostech dokumentu ještě nejsou aktualizovány hodnoty z vlastností dokumentu samotného.

    Dalším důležitým důsledkem propojení vlastností z SharePoint knihovny (typu obsahu) a vlastností dokumentů včetně hodnot je to, že si dokument své vlastnosti uchovává i mimo SharePoint. To je většinou užitečné, ale je potřeba to mít na paměti, protože jinak si člověk může způsobit horké chvilky. Představme si následující situaci: Máme knihovnu dokumentů pro evidenci smluv, která mimo jiné se obsahuje sloupec stav smlouvy. Tento sloupec vyjadřuje stav přípravy, schvalování a nakonec i podpisu smlouvy. A v této knihovně mějme jednu smlouvu, která prošla všemi fázemi. Pak přijde požadavek na přípravu nové smlouvy, která bude velmi podobná té už existující. Proto by logickým krokem mohlo být to, že vezmeme původní smlouvu a zkopírujeme ji pod jménem druhé smlouvy. Následně bychom mohli upravit její text. Protože jsou ale součástí dokumentu i metadata, máme rázem i druhou smlouvu kompletně schválenou, ačkoliv ji nikdo neviděl. To je samozřejmě špatně. Kdyby se metadata z SharePointu nepropagovala do dokumentu a zpět chovalo by se to v tomto okamžiku logičtěji.

    Popsané chování (provázání vlastností SharePointu a vlastností dokumentů jako takových) je out-of-the-box u Office dokumentů a obrázků. SharePoint na to má obecný mechanizmus tzv. document parserů. Jsou to COM objekty, které implementují ISPDocumentParser rozhranní. Dají se naprogramovat v .NETu (viz. MSDN Custom Document Parsers). V SharePointu jsou registrovány na objektu SPWebService v kolekci PluggableParsers. Jde v podstatě o mapovací tabulku přípony dokumentu a odpovídajícího parseru. Stejnou tabulku můžete v XML podobě najít na disku v souboru DOCPARSE.XML. Editace dokumentu ale sama o sobě nefunguje, musíte provést změnu vlastnosti webové aplikace, např. PowerShellem nebo SharePoint Managerem.

    Další možností, jak tento přenos vlastností a jejich hodnot mezi SharePointem a dokumenty ovlivňovat je vlastnost ParserEnabled na objektu SPWeb. Tím můžete na úrovni jednotlivých webů přenos “globálně” zapnout, nebo vypnout. Bohužel to nejde na úrovni jednotlivých knihoven dokumentů.

Více článků Další stránka »

Syndication

News

  • Web Developer
  • Enterprise Application Developer

  • Microsoft Office SharePoint Server 2007, Application Development
  • Microsoft Windows SharePoint Services 3.0, Application Development
  • Microsoft Office SharePoint Server 2007, Configuration
  • Microsoft Windows SharePoint Services 3.0, Configuration
  • .Net Framework 2.0, Distributed Applications
  • .Net Framework 2.0, Web Applications
  • .Net Framework 2.0, Windows Applications
Powered by Community Server (Personal Edition), by Telligent Systems