{"id":9299,"date":"2020-06-18T09:55:31","date_gmt":"2020-06-18T07:55:31","guid":{"rendered":"https:\/\/sii.pl\/blog\/?p=9299"},"modified":"2023-01-20T12:22:27","modified_gmt":"2023-01-20T11:22:27","slug":"jak-uniknac-bledow-podczas-programowania-na-platforme-ms-sharepoint-2016","status":"publish","type":"post","link":"https:\/\/sii.pl\/blog\/jak-uniknac-bledow-podczas-programowania-na-platforme-ms-sharepoint-2016\/","title":{"rendered":"Jak unikn\u0105\u0107 b\u0142\u0119d\u00f3w podczas programowania na platform\u0119 MS SharePoint 2016"},"content":{"rendered":"\n<p>Pocz\u0105tki cz\u0119sto bywaj\u0105 trudne. Pocz\u0105tek nauki nowej technologii tak\u017ce bywa trudny i nie jest wolny od b\u0142\u0119d\u00f3w.&nbsp;Na b\u0142\u0119dach mo\u017cna si\u0119 sporo nauczy\u0107, nie tylko na swoich. W dzisiejszym artykule przestawi\u0119 kilka porad, co robi\u0107, aby unikn\u0105\u0107 pomy\u0142ek, kt\u00f3re mog\u0105 pojawi\u0107 si\u0119 podczas programowania aplikacji na platform\u0119 SharePoint, szczeg\u00f3lnie na pocz\u0105tku tej pasjonuj\u0105cej przygody.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Nazewnictwo<\/h2>\n\n\n\n<p>SharePoint ma szereg wbudowanych kolumn i typ\u00f3w zawarto\u015bci, z pomoc\u0105 kt\u00f3rych u\u017cytkownik mo\u017ce budowa\u0107 w\u0142asne listy (ang. Custom Lists). Jednak zazwyczaj, szczeg\u00f3lnie w du\u017cych projektach, tworzy si\u0119 w\u0142asne typy i kolumny (ang. Custom Content Types, Custom Columns).<\/p>\n\n\n\n<p>Tworz\u0105c nowy typ zawarto\u015bci (ang. Content Type) musimy mu przypisa\u0107 unikatowe ID oraz nazw\u0119 (ang. Name). Sama idea jest bardzo prosta, jednak stwarza sytuacj\u0119, w kt\u00f3rej bardzo \u0142atwo pope\u0142ni\u0107 b\u0142\u0105d. Istnieje bowiem mo\u017cliwo\u015b\u0107, \u017ce nadamy nowemu typowi nazw\u0119, kt\u00f3ra istnieje ju\u017c w\u015br\u00f3d wbudowanych typ\u00f3w zawarto\u015bci. Podczas pr\u00f3by instalacji takiego rozwi\u0105zania w \u015brodowisku SharePointa, dostaniemy b\u0142\u0105d. Nale\u017cy zatem zadba\u0107, aby nazwa w tworzonym typie zawarto\u015bci by\u0142a unikatowa. Warto sprawdzi\u0107 list\u0119 istniej\u0105cych typ\u00f3w zawarto\u015bci za pomoc\u0105 interpretera polece\u0144 PowerShell, wpisuj\u0105c np. nast\u0119puj\u0105ce komendy:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n$web = Get-SPWeb -Identity http:\/\/&#x5B;tutaj podajemy URL naszej Site Collection, bez u\u017cycia cudzys\u0142owu]\n$contentTypes = $web.ContentTypes\n$web.Dispose()\n$contentTypes | Select Name | Sort Name\n<\/pre><\/div>\n\n\n<p>Podobnie jest z tworzeniem nowej kolumny. Dodaj\u0105c now\u0105 kolumn\u0119, uzupe\u0142niamy jej nazw\u0119 wy\u015bwietlan\u0105 (ang. Title) i nazw\u0119 wewn\u0119trzn\u0105 (ang. Internal Name). Nazwa wewn\u0119trzna musi by\u0107 unikatowa.<\/p>\n\n\n\n<p>Poni\u017cej znajduje si\u0119 przyk\u0142ad b\u0142\u0119du, jaki pojawi\u0142 si\u0119 przy pr\u00f3bie instalacji rozwi\u0105zania zawieraj\u0105cego kod tworz\u0105cy now\u0105 kolumn\u0119 z istniej\u0105c\u0105 ju\u017c nazw\u0105 wewn\u0119trzn\u0105 \u2013 EmailBody. Mo\u017cna zauwa\u017cy\u0107, \u017ce w tre\u015bci b\u0142\u0119du nie pojawia si\u0119 ta nazwa, kt\u00f3rej u\u017cycie powodowa\u0142o b\u0142\u0105d. Tre\u015b\u0107 m\u00f3wi natomiast, \u017ce bezpo\u015bredni\u0105 przyczyn\u0105 b\u0142\u0119du by\u0142a pr\u00f3ba zmiany atrybutu Hidden istniej\u0105cej ju\u017c kolumny \u2013 nowa kolumna mia\u0142a domy\u015blnie ustawiony atrybut Hidden na \u2018false\u2019, a przez ustawienie InternalName na istniej\u0105c\u0105 ju\u017c nazw\u0119 EmailBody, zosta\u0142o to potraktowane jako pr\u00f3ba modyfikacji atrybutu istniej\u0105cej ju\u017c ukrytej kolumny EmailBody.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2020\/06\/R1-1.png\"><img decoding=\"async\" width=\"952\" height=\"269\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2020\/06\/R1-1.png\" alt=\"Rysunek 1. B\u0142\u0105d, jaki pojawia si\u0119 podczas instalacji rozwi\u0105zania, kt\u00f3re zawiera tworzenie nowej kolumny z istniej\u0105c\u0105 ju\u017c nazw\u0105 wewn\u0119trzn\u0105\" class=\"wp-image-18652\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2020\/06\/R1-1.png 952w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2020\/06\/R1-1-300x85.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2020\/06\/R1-1-768x217.png 768w\" sizes=\"(max-width: 952px) 100vw, 952px\" \/><\/a><figcaption>Rysunek 1. B\u0142\u0105d, jaki pojawia si\u0119 podczas instalacji rozwi\u0105zania, kt\u00f3re zawiera tworzenie nowej kolumny z istniej\u0105c\u0105 ju\u017c nazw\u0105 wewn\u0119trzn\u0105<\/figcaption><\/figure><\/div>\n\n\n\n<p>Je\u015bli chodzi o nazw\u0119 wy\u015bwietlan\u0105, to w przypadku kolumn nazwa ta nie musi by\u0107 unikatowa, ale lepiej nie powiela\u0107 istniej\u0105cych ju\u017c nazw, je\u015bli nie ma takiej potrzeby. Zdarza si\u0119, \u017ce u\u017cycie istniej\u0105cej ju\u017c nazwy wy\u015bwietlanej dla nowej kolumny powoduje nie do ko\u0144ca poprawne dzia\u0142anie aplikacji. Wprawdzie nie dostaniemy jawnie \u017cadnego b\u0142\u0119du, ale mo\u017cemy nie osi\u0105gn\u0105\u0107 zamierzonego efektu. Warto wi\u0119c zapozna\u0107 si\u0119 z nazwami istniej\u0105cych ju\u017c kolumn, \u017ceby unikn\u0105\u0107 b\u0142\u0119du podczas instalacji rozwi\u0105zania.<\/p>\n\n\n\n<p>Nazwy istniej\u0105cych ju\u017c kolumn mo\u017cna sprawdzi\u0107 dwiema metodami. Je\u015bli interesuje nas sprawdzenie nazwy konkretnego pola, mo\u017cna sprawdzi\u0107 jego nazw\u0119 wewn\u0119trzn\u0105 w Centralnej Administracji platformy SharePoint: Site Settings -&gt; Web Designer Galleries -&gt; Site Columns.<\/p>\n\n\n\n<p>Poni\u017cej znajduje si\u0119 przyk\u0142ad, na kt\u00f3rym zaznaczone zosta\u0142y: nazwa wewn\u0119trzna (w adresie URL: field=WorkAddress) oraz nazwa wy\u015bwietlana (Column name: Address).<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2020\/06\/R2-1.png\"><img decoding=\"async\" width=\"1024\" height=\"602\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2020\/06\/R2-1-1024x602.png\" alt=\"Rysunek 2. Nazwa wy\u015bwietlana kolumny oraz jej nazwa wewn\u0119trzna\" class=\"wp-image-18654\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2020\/06\/R2-1-1024x602.png 1024w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2020\/06\/R2-1-300x176.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2020\/06\/R2-1-768x451.png 768w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2020\/06\/R2-1.png 1210w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption>Rysunek 2. Nazwa wy\u015bwietlana kolumny oraz jej nazwa wewn\u0119trzna<\/figcaption><\/figure><\/div>\n\n\n\n<p>Jednak lepszym sposobem jest u\u017cycie do tego celu PowerShella, poniewa\u017c za jego pomoc\u0105 mo\u017cna otrzyma\u0107 posortowan\u0105 list\u0119 sk\u0142adaj\u0105c\u0105 si\u0119 z nazw wy\u015bwietlanych wszystkich kolumn istniej\u0105cych w obr\u0119bie danej kolekcji stron (ang. Site Collection). Wystarczy u\u017cy\u0107 nast\u0119puj\u0105cych przyk\u0142adowych komend:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n$web = Get-SPWeb -Identity http:\/\/&#x5B;tutaj podajemy URL naszej Site Collection, bez u\u017cycia cudzys\u0142owu]\n$siteFields = $web.Fields\n$web.Dispose()\n$siteFields | Select InternalName | Sort InternalName\n<\/pre><\/div>\n\n\n<p>W przypadku, gdy chcemy sprawdzi\u0107 tak\u017ce nazwy wy\u015bwietlane danych kolumn, w komendach nale\u017cy u\u017cy\u0107 Title zamiast InternalName. Mo\u017cna te\u017c doda\u0107 Title do polecenia Select, wtedy dostaniemy list\u0119 kolumn z ich nazwami wy\u015bwietlanymi oraz wewn\u0119trznymi.<\/p>\n\n\n\n<p>Kiedy potrzebujemy za pomoc\u0105 naszego kodu przeczyta\u0107 lub ustawi\u0107 warto\u015bci danej kolumny, musimy si\u0119 odpowiednio do tej kolumny odwo\u0142a\u0107. Najlepiej odwo\u0142a\u0107 si\u0119 do nazwy wewn\u0119trznej, poniewa\u017c ta nazwa jest niezmienna. Nazw\u0119 wy\u015bwietlan\u0105 mo\u017cna \u0142atwo zmieni\u0107 w interfejsie u\u017cytkownika, natomiast nazwa wewn\u0119trzna jest nadawana podczas tworzenia kolumny i nie mo\u017cna jej zmieni\u0107 z poziomu interfejsu u\u017cytkownika. Dlatego w\u0142a\u015bnie najbezpieczniej jest u\u017cywa\u0107 nazwy wewn\u0119trznej podczas pracy z warto\u015bciami kolumny.<\/p>\n\n\n\n<p>Kolejn\u0105 kwesti\u0105, o kt\u00f3rej warto wspomnie\u0107, jest d\u0142ugo\u015b\u0107 nazwy wewn\u0119trznej. Dopuszczalna liczba znak\u00f3w takiej nazwy dla kolumny dodawanej do listy SharePointowej to 32. Pr\u00f3ba dodania do listy kolumny o d\u0142u\u017cszej nazwie zako\u0144czy si\u0119 uci\u0119ciem nadmiarowych znak\u00f3w dla zapisu nazwy wewn\u0119trznej. Je\u015bli chodzi o limit nazwy wewn\u0119trznej dla kolumny dodawanej do biblioteki SharePointowej, to mamy do dyspozycji 256 znak\u00f3w.<\/p>\n\n\n\n<p>Poni\u017cej przedstawione zostan\u0105 przyk\u0142ady nazw (wy\u015bwietlanej oraz wewn\u0119trznej) dla listy<br>i biblioteki.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2020\/06\/R3-1.png\"><img decoding=\"async\" width=\"925\" height=\"296\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2020\/06\/R3-1.png\" alt=\"Rysunek 3. Nazwa wy\u015bwietlana pola znajduj\u0105cego si\u0119 na li\u015bcie sk\u0142ada si\u0119 z 46 znak\u00f3w\" class=\"wp-image-18656\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2020\/06\/R3-1.png 925w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2020\/06\/R3-1-300x96.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2020\/06\/R3-1-768x246.png 768w\" sizes=\"(max-width: 925px) 100vw, 925px\" \/><\/a><figcaption>Rysunek 3. Nazwa wy\u015bwietlana pola znajduj\u0105cego si\u0119 na li\u015bcie sk\u0142ada si\u0119 z 46 znak\u00f3w<\/figcaption><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2020\/06\/R4-1.png\"><img decoding=\"async\" width=\"1024\" height=\"48\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2020\/06\/R4-1-1024x48.png\" alt=\"R4 - Jak unikn\u0105\u0107 b\u0142\u0119d\u00f3w podczas programowania na platform\u0119 MS SharePoint 2016\" class=\"wp-image-18658\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2020\/06\/R4-1-1024x48.png 1024w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2020\/06\/R4-1-300x14.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2020\/06\/R4-1-768x36.png 768w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2020\/06\/R4-1.png 1031w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption>Rysunek 4. Nazwa wewn\u0119trzna pola znajduj\u0105cego si\u0119 na li\u015bcie zosta\u0142a automatycznie skr\u00f3cona do 32 znak\u00f3w<\/figcaption><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2020\/06\/R5-1.png\"><img decoding=\"async\" width=\"931\" height=\"298\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2020\/06\/R5-1.png\" alt=\"Rysunek 5. Nazwa wy\u015bwietlana pola znajduj\u0105cego si\u0119 w bibliotece sk\u0142ada si\u0119 z 46 znak\u00f3w\" class=\"wp-image-18660\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2020\/06\/R5-1.png 931w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2020\/06\/R5-1-300x96.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2020\/06\/R5-1-768x246.png 768w\" sizes=\"(max-width: 931px) 100vw, 931px\" \/><\/a><figcaption>Rysunek 5. Nazwa wy\u015bwietlana pola znajduj\u0105cego si\u0119 w bibliotece sk\u0142ada si\u0119 z 46 znak\u00f3w<\/figcaption><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2020\/06\/R6-1.png\"><img decoding=\"async\" width=\"1024\" height=\"39\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2020\/06\/R6-1-1024x39.png\" alt=\"R6 - Jak unikn\u0105\u0107 b\u0142\u0119d\u00f3w podczas programowania na platform\u0119 MS SharePoint 2016\" class=\"wp-image-18662\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2020\/06\/R6-1-1024x39.png 1024w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2020\/06\/R6-1-300x11.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2020\/06\/R6-1-768x29.png 768w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2020\/06\/R6-1.png 1113w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption>Rysunek 6. Nazwa wewn\u0119trzna pola znajduj\u0105cego si\u0119 w w bibliotece sk\u0142ada si\u0119 z 46 znak\u00f3w \u2013 tak jak nazwa wy\u015bwietlana<\/figcaption><\/figure><\/div>\n\n\n\n<p>Kolejnym zagadnieniem w ramach niniejszej sekcji jest nazewnictwo list. Generalnie lista nie ma nazwy wewn\u0119trznej w takim rozumieniu, jak w przypadku kolumny. Jednak mechanizm tworzenia instancji listy w SharePoincie pozwala na nadanie jej takiej nazwy, kt\u00f3ra b\u0119dzie niezmienna. Wraz z list\u0105 tworzony jest bowiem folder g\u0142\u00f3wny (ang. Root Folder), kt\u00f3rego nazwa (ang. Root Folder Name) jest sta\u0142a i znajduje si\u0119 w URL tej listy. Nazwa folderu g\u0142\u00f3wnego listy powinna by\u0107 kr\u00f3tka, a zarazem dobrze opisuj\u0105ca przeznaczenie danej listy. Podobnie jak w przypadku wewn\u0119trznych nazw dla kolumn, nie powinni\u015bmy u\u017cywa\u0107 ani spacji, ani znak\u00f3w szczeg\u00f3lnych, tworz\u0105c nazw\u0119 folderu g\u0142\u00f3wnego listy.Podczas ustalania nazwy wewn\u0119trznej dla tworzonej kolumny, nale\u017cy tak\u017ce zwr\u00f3ci\u0107 uwag\u0119 na spacj\u0119 oraz znaki specjalne. Dobr\u0105 praktyk\u0105 jest u\u017cywanie ci\u0105g\u00f3w liter bez spacji czy znak\u00f3w specjalnych, poniewa\u017c ka\u017cda u\u017cyta spacja (lub znak specjalny) zostanie automatycznie zakodowana odpowiednim kodem. Cyfry mog\u0105 by\u0107 u\u017cywane w nazwie wewn\u0119trznej, aczkolwiek lepiej trzyma\u0107 si\u0119 nazw sk\u0142adaj\u0105cych si\u0119\u00a0 z samych liter. Poni\u017cej znajduje si\u0119 przyk\u0142ad, w jaki spos\u00f3b przypisana do kolumny nazwa zosta\u0142a zmodyfikowana do postaci nazwy wewn\u0119trznej:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2020\/06\/R7-1.png\"><img decoding=\"async\" width=\"950\" height=\"396\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2020\/06\/R7-1.png\" alt=\"Rysunek 7. Nazwa wewn\u0119trzna, dla kt\u00f3rej zosta\u0142o dokonane automatyczne kodowanie spacji\" class=\"wp-image-18664\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2020\/06\/R7-1.png 950w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2020\/06\/R7-1-300x125.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2020\/06\/R7-1-768x320.png 768w\" sizes=\"(max-width: 950px) 100vw, 950px\" \/><\/a><figcaption>Rysunek 7. Nazwa wewn\u0119trzna, dla kt\u00f3rej zosta\u0142o dokonane automatyczne kodowanie spacji<\/figcaption><\/figure><\/div>\n\n\n\n<p>Opr\u00f3cz nazwy folderu g\u0142\u00f3wnego, lista ma tak\u017ce sw\u00f3j tytu\u0142 (ang. Title), kt\u00f3ry jest nazw\u0105 wy\u015bwietlan\u0105 dla listy, czyli jest widoczny przy ka\u017cdym wyst\u0105pieniu listy na poziomie kolekcji stron. Tytu\u0142 powinien by\u0107 bardziej czyteln\u0105 i eleganck\u0105 wersj\u0105 nazwy folderu g\u0142\u00f3wnego listy. Na przyk\u0142ad dla nazwy folderu g\u0142\u00f3wnego \u201eWorkflowHistory\u201d odpowiednim tytu\u0142em listy b\u0119dzie \u201eWorkflow History\u201d.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Dostarczanie funkcjonalno\u015bci<\/h2>\n\n\n\n<p>Dostarczanie funkcjonalno\u015bci (ang. Provisioning) to proces tworzenia poszczeg\u00f3lnych element\u00f3w aplikacji na platformie SharePoint. Zawiera si\u0119 w nim tworzenie typ\u00f3w zawarto\u015bci, kolumn, list, bibliotek, dodawanie ich do poszczeg\u00f3lnych logicznych cz\u0119\u015bci funkcjonalno\u015bci (ang. Features), a nast\u0119pnie, za pomoc\u0105 aktywowania odpowiednich funkcji, dodawanie tych element\u00f3w do wybranej kolekcji stron. Cz\u0119st\u0105 przyczyn\u0105 pocz\u0105tkowo niezrozumia\u0142ych b\u0142\u0119d\u00f3w z dostarczaniem funkcjonalno\u015bci jest niew\u0142a\u015bciwa praca z polami typu Lookup. Pole typu Lookup to taka kolumna na li\u015bcie, kt\u00f3rej warto\u015b\u0107 odnosi si\u0119 do innej listy. Przyk\u0142ad: maj\u0105c na li\u015bcie A kolumn\u0119, kt\u00f3ra jest odniesieniem (ang. Lookup Field) do listy B, automatycznie dostajemy dost\u0119p do tych w\u0142a\u015bciwo\u015bci danego obiektu z listy B, kt\u00f3re s\u0105 wspierane przez owo odniesienie. M\u00f3wi\u0105c inaczej, pole typu Lookup zapewnia nam dost\u0119p do okre\u015blonych w\u0142a\u015bciwo\u015bci obiektu znajduj\u0105cego si\u0119 na li\u015bcie B z poziomu listy A. Jednak zawsze przed dodaniem kolumny do listy musimy tak\u0105 kolumn\u0119 stworzy\u0107. Kolumn\u0119 typu Lookup tworzy si\u0119 nieco inaczej ni\u017c pozosta\u0142e kolumny. Do jej stworzenia potrzebna jest lista \u017ar\u00f3d\u0142owa, na kt\u00f3r\u0105 wskazuje dane odniesienie.<\/p>\n\n\n\n<p>Z poziomu kodu, tworzenie pola polega po prostu na stworzeniu nowego obiektu i uzupe\u0142nieniu jego w\u0142a\u015bciwo\u015bci odpowiednimi warto\u015bciami. W przypadku pola typu Lookup opr\u00f3cz Title i InternalName musimy tak\u017ce wskaza\u0107 wspomnian\u0105 wcze\u015bniej list\u0119 \u017ar\u00f3d\u0142ow\u0105. Uzupe\u0142niamy tak\u017ce LookupField, wybieraj\u0105c w ten spos\u00f3b pole na li\u015bcie \u017ar\u00f3d\u0142owej, na kt\u00f3rego warto\u015b\u0107 b\u0119dzie wskazywa\u0142a kolumna typu Lookup.<\/p>\n\n\n\n<p>Dlatego w\u0142a\u015bnie wa\u017cne jest, aby kod tworz\u0105cy list\u0119, do kt\u00f3rej ma si\u0119 odwo\u0142ywa\u0107 dane pole typu Lookup, by\u0142 wykonywany przed kodem tworz\u0105cym sam\u0105 kolumn\u0119. Jednak je\u015bli w trakcie wykonywania kodu tworz\u0105cego pole typu Lookup oka\u017ce si\u0119, \u017ce odwo\u0142ujemy si\u0119 do listy \u017ar\u00f3d\u0142owej, kt\u00f3ra nie istnieje (np. przez podanie niew\u0142a\u015bciwej nazwy listy), otrzymamy b\u0142\u0105d:<\/p>\n\n\n\n<p><em>Error Message: The lookup field refers to a list that cannot be found.<\/em><\/p>\n\n\n\n<p>Natomiast usuni\u0119cie listy \u017ar\u00f3d\u0142owej w trakcie dzia\u0142ania aplikacji bez usuni\u0119cia pola typu Lookup spowoduje brak mo\u017cliwo\u015bci okre\u015blenia warto\u015bci pola typu Lookup dla nowo tworzonych element\u00f3w (ang. Items) na li\u015bcie. Dla element\u00f3w stworzonych wcze\u015bniej, warto\u015bci kolumny odnosz\u0105cej si\u0119 do listy \u017ar\u00f3d\u0142owej b\u0119d\u0105 nadal widoczne, ale nie b\u0119d\u0105 ju\u017c warto\u015bciami typu Lookup (mog\u0105 by\u0107 traktowane np. jako pole tekstowe).<\/p>\n\n\n\n<p>U\u017cywanie kolumn typu Lookup niesie za sob\u0105 tak\u017ce ograniczenia ilo\u015bciowe. Na widoku listy mo\u017ce znajdowa\u0107 si\u0119 maksymalnie 12 p\u00f3l typu Lookup (dotyczy to tak\u017ce p\u00f3l typu Managed Metadata czy People Group). Wi\u0119c je\u015bli mamy rozbudowany obiekt (w kt\u00f3rego sk\u0142ad wchodzi wi\u0119cej ni\u017c 12 p\u00f3l typu Lookup) i wszystkie jego pola chcemy zawrze\u0107 w widoku listy, spotkamy si\u0119 z b\u0142\u0119dem:<\/p>\n\n\n\n<p><em>Error loading content. Value does not fall within the expected range. This error could be caused by having more lookup columns in the list than the \u2018Lookup View Threshold Setting\u2019 in Central Administration.<\/em><\/p>\n\n\n\n<p>Aby tego unikn\u0105\u0107 nale\u017cy uwzgl\u0119dnia\u0107 powy\u017csze ograniczenie w trakcie tworzenia klas obiekt\u00f3w, kt\u00f3re b\u0119d\u0105 wy\u015bwietlanie na widoku listy. Teoretycznie, w opcjach mo\u017cna zwi\u0119kszy\u0107 dopuszczaln\u0105 na widoku liczb\u0119 p\u00f3l typu Lookup, jednak\u017ce nie jest to zalecane, poniewa\u017c takie dzia\u0142ania mog\u0105 znacznie zmniejszy\u0107 wydajno\u015b\u0107 aplikacji.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Mapowanie<\/h2>\n\n\n\n<p>Je\u015bli w naszej aplikacji SharePointowej u\u017cywamy Web Services, dobr\u0105 praktyk\u0105 jest stworzenie modelu dla Obiekt\u00f3w Transferu Danych (ang. Data Transfer Object \u2013 DTO). Jedynym zadaniem modelu DTO jest przekazywanie obiekt\u00f3w pomi\u0119dzy warstwami aplikacji (pomi\u0119dzy modelem domenowym a serwisem). Nie znajdziemy tu \u017cadnej logiki biznesowej. Do poprawnego dzia\u0142ania Web Services aplikacji potrzebne jest dok\u0142adnie odzwierciedlenie modelu domenowego na DTO. Konwersji mo\u017cna dokona\u0107 r\u0119cznie, ale w du\u017cych projektach cz\u0119sto u\u017cywa si\u0119 AutoMappera. Kiedy wykorzystujemy rozwi\u0105zanie automatyczne, nale\u017cy pami\u0119ta\u0107 o odpowiednim przygotowaniu danych do mapowania. Po pierwsze, musimy skonfigurowa\u0107 mapowanie poprzez wskazanie, kt\u00f3re klasy b\u0119d\u0105 w nim uczestniczy\u0142y. Je\u015bli typy i w\u0142a\u015bciwo\u015bci klasy DTO s\u0105 wiernym odzwierciedleniem klasy domenowej (nazwy s\u0105 identyczne, a typy si\u0119 pokrywaj\u0105), wtedy wystarczy stworzenie mapy. W przypadku, kiedy mamy do czynienia z tzw. sp\u0142aszczeniem obiekt\u00f3w (ang. Flattening) \u2013 czyli z upraszczaniem rozbudowanych obiekt\u00f3w do prostego modelu DTO z zachowaniem odpowiedniej konwencji dotycz\u0105cej nazewnictwa (np. je\u015bli mamy klas\u0119 Book, kt\u00f3ra zawiera w\u0142a\u015bciwo\u015b\u0107 nosz\u0105c\u0105 nazw\u0119 Name, w klasie BookDTO mo\u017cna stworzy\u0107 w\u0142a\u015bciwo\u015b\u0107 o nazwie BookName), wtedy tak\u017ce wystarczy samo stworzenie mapy bez u\u017cycia metody ForMember.<\/p>\n\n\n\n<p>Jednak, je\u015bli nazwy odpowiadaj\u0105cych sobie w\u0142a\u015bciwo\u015bci r\u00f3\u017cni\u0105 si\u0119 lub nie jest mo\u017cliwa automatyczna konwersja typ\u00f3w, nale\u017cy wyszczeg\u00f3lni\u0107, w jaki spos\u00f3b chcemy dokona\u0107 mapowania poprzez u\u017cycie metody ForMember. Poni\u017cej przedstawiony jest kod, zawieraj\u0105cy tworzenie mapy<br>z uwzgl\u0119dnieniem mapowania pola, kt\u00f3rego nazwa r\u00f3\u017cni si\u0119 pomi\u0119dzy klasami domenow\u0105 i DTO:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nprivate void ConfigureMappings()\n{\nCreateMap&amp;lt;Book, BookDTO&gt;()\n.ForMember(x =&gt; x.Print, opt =&gt; opt.MapFrom(y =&gt; y.PublishingHouse));\n}\n<\/pre><\/div>\n\n\n<p>Je\u015bli wcze\u015bniej nie pracowali\u015bmy z AutoMapperem, mog\u0105 zdarza\u0107 si\u0119 b\u0142\u0119dy wynikaj\u0105ce<br>z niew\u0142a\u015bciwego przygotowania klas do mapowania. Wtedy mo\u017cemy otrzyma\u0107 niew\u0142a\u015bciwe lub niepe\u0142ne dane, kt\u00f3re zosta\u0142y wystawione do WebService. Mo\u017ce tak\u017ce pojawi\u0107 si\u0119 b\u0142\u0105d, gdy nie uwzgl\u0119dnimy mapowania w\u0142a\u015bciwo\u015bci, kt\u00f3re r\u00f3\u017cni\u0105 si\u0119 nazw\u0105 czy typem lub gdy przeprowadzimy mapowanie w niew\u0142a\u015bciwy spos\u00f3b. Przyk\u0142adowy fragment tre\u015bci b\u0142\u0119du mapowania:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n{&quot;GetBooksResult&quot;:{&quot;ErrorMessage&quot;:&quot;\\u000aUnmapped members were found. \n\nReview the types and members below.\\u000aAdd a custom mapping expression, ignore, add a custom resolver, or modify the source\\\/destination \n\ntype\\u000aFor no matching constructor, add a no-arg ctor, add optional arguments, or map all of the constructor parameters\\u000a\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\">Logika biznesowa<\/h2>\n\n\n\n<p>Tworz\u0105c aplikacj\u0119 SharePointow\u0105 z poziomu kodu, potrzebujemy mechanizmu do zarz\u0105dzania znajduj\u0105cymi si\u0119 na niej danymi. Platforma .NET udost\u0119pnia model kliencki CSOM (ang. Client-Side Object Model), dla JavaScript modelem tym jest JSOM lub\/i REST. Tworz\u0105c mniej lub bardziej rozbudowan\u0105 infrastruktur\u0119 logiki biznesowej, mo\u017cemy operowa\u0107 na danych SharePointowych, uzyskuj\u0105c do nich dost\u0119p poprzez kontekst (np. ClientContext). Odwo\u0142uj\u0105c si\u0119 do obiekt\u00f3w utworzonych w kolekcji stron musimy zachowa\u0107 odpowiedni schemat. Jest to bardzo wa\u017cne, poniewa\u017c specyfika pracy z modelem CSOM wymaga zdefiniowania danych, kt\u00f3re chcemy pobra\u0107 i kt\u00f3re nast\u0119pnie b\u0119dzie mo\u017cna przetwarza\u0107. Kolejno\u015b\u0107 dzia\u0142a\u0144 przestawia si\u0119 nast\u0119puj\u0105co: najpierw pobierany jest kontekst dla naszej strony na podstawie podanego adresu URL. Nast\u0119pnie, z kontekstu pobieramy Web, kt\u00f3ry jest nadrz\u0119dn\u0105 stron\u0105 (ang. Root Site) w naszej kolekcji stron. Je\u015bli chcemy operowa\u0107 na listach, to je tak\u017ce musimy za\u0142adowa\u0107. Mo\u017cemy te\u017c pobra\u0107 konkretn\u0105 list\u0119 po jej nazwie wy\u015bwietlanej (Title). Nazw\u0119 t\u0119, podobnie jak w przypadku kolumn, mo\u017cna modyfikowa\u0107 z poziomu interfejsu u\u017cytkownika, zatem nie mamy pewno\u015bci, czy takie odwo\u0142anie zostanie poprawnie wykonane. Drugim sposobem jest odwo\u0142anie si\u0119 do listy za pomoc\u0105 nazwy jej folderu g\u0142\u00f3wnego (kwestia tworzenia nazw dla listy zosta\u0142\u0105 poruszona na ko\u0144cu sekcji \u201eNazewnictwo\u201d). Nazw\u0119 folderu g\u0142\u00f3wnego mo\u017cna odczyta\u0107 w\u0142a\u015bnie z adresu URL lub odwo\u0142uj\u0105c si\u0119 do w\u0142a\u015bciwo\u015bci listy, a konkretnie do RootFolder.Name. Kiedy lista jest ju\u017c pobrana, mo\u017cna wyci\u0105gn\u0105\u0107 z niej dane. Do tego celu s\u0142u\u017cy zapytanie (ang. Query). Na platformie .NET mamy dost\u0119pn\u0105 bibliotek\u0119 Camlex, dzi\u0119ki kt\u00f3rej mo\u017cna budowa\u0107 zapytania w prosty spos\u00f3b za pomoc\u0105 wyra\u017ce\u0144, kt\u00f3re zostan\u0105 przekonwertowane na j\u0119zyk zapyta\u0144 w\u0142a\u015bciwy dla SharePointowej bazy danych (ang. Collaborative Application Markup Language \u2013 CAML).<\/p>\n\n\n\n<p>Podczas pr\u00f3by operacji na danych z listy musimy pami\u0119ta\u0107 o sprawdzeniu, czy wraz z list\u0105 dostali\u015bmy jakiekolwiek elementy. Przed wykonaniem operacji na obiektach zwracanych z listy, nale\u017cy sprawdzi\u0107, czy mamy na czym operowa\u0107, czyli czy lista nie by\u0142a pusta lub czy zapytanie wykonywane na li\u015bcie zwr\u00f3ci\u0142o jakie\u015b elementy. W przeciwnym razie, mo\u017cemy otrzyma\u0107 b\u0142\u0105d zwi\u0105zany z pr\u00f3b\u0105 odwo\u0142ania si\u0119 do pustego obiektu.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2020\/06\/R8-1.png\"><img decoding=\"async\" width=\"401\" height=\"243\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2020\/06\/R8-1.png\" alt=\"Rysunek 8. Przyk\u0142adowy b\u0142\u0105d spowodowany pr\u00f3b\u0105 odwo\u0142ania si\u0119 do w\u0142a\u015bciwo\u015bci pustego obiektu\" class=\"wp-image-18666\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2020\/06\/R8-1.png 401w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2020\/06\/R8-1-300x182.png 300w\" sizes=\"(max-width: 401px) 100vw, 401px\" \/><\/a><figcaption>Rysunek 8. Przyk\u0142adowy b\u0142\u0105d spowodowany pr\u00f3b\u0105 odwo\u0142ania si\u0119 do w\u0142a\u015bciwo\u015bci pustego obiektu<\/figcaption><\/figure><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Testy deweloperskie<\/h2>\n\n\n\n<p>Kiedy pracujemy nad aplikacj\u0105, w kt\u00f3rej dost\u0119pno\u015b\u0107 funkcjonalno\u015bci zale\u017cy od nadanych r\u00f3l, nale\u017cy testowa\u0107 swoje rozwi\u0105zania dla u\u017cytkownik\u00f3w z r\u00f3\u017cnymi uprawnieniami. Cz\u0119stym b\u0142\u0119dem jest sprawdzanie dzia\u0142ania kodu tylko z poziomu administratora. Je\u015bli chodzi o SharePointa, to najcz\u0119\u015bciej tylko administrator (lub Site Owner) posiada dost\u0119p do wszystkich dodawanych list, zawarto\u015bci, opcji itp. Dlatego, je\u015bli chcemy sprawdzi\u0107, czy dana kolumna zosta\u0142a stworzona i poprawnie dodana do odpowiedniej listy, to owszem, sprawdzimy to, loguj\u0105c si\u0119 na konto z uprawnieniami administratora. Jednak je\u015bli chcemy testowa\u0107 zagadnienia zwi\u0105zane z samym przep\u0142ywem pracy (ang. Workflow), dobrze jest wcieli\u0107 si\u0119 w role u\u017cytkownik\u00f3w z r\u00f3\u017cnymi uprawnieniami. Czasami w bazie testowej istniej\u0105 ju\u017c odpowiednie konta, czasami trzeba doda\u0107 takie konto samodzielnie.<\/p>\n\n\n\n<p>Cz\u0119sto aplikacje SharePointowe s\u0105 u\u017cywane do zarz\u0105dzania r\u00f3\u017cnymi rodzajami formularzy. Zazwyczaj dost\u0119pne opcje zale\u017c\u0105 od poziomu uprawnie\u0144 w procesie przep\u0142ywu pracy. Administrator ma uprawnienia nadrz\u0119dne w stosunku do wszystkich innych funkcji. Dlatego te\u017c zawsze b\u0119dzie mia\u0142 dost\u0119p do takiego formularza. Cz\u0119sto, w zale\u017cno\u015bci od tego, czy zalogowany u\u017cytkownik jest administratorem, wywo\u0142ywana jest (lub nie) odpowiednia metoda do czytania element\u00f3w z bazy. Dla administratora zazwyczaj czytamy wszystkie elementy, a dla innych u\u017cytkownik\u00f3w elementy b\u0119d\u0105 odpowiednio filtrowane. Dlatego te\u017c, testuj\u0105c stworzone metody tylko dla administratora, nie b\u0119dziemy w stanie sprawdzi\u0107, czy stworzyli\u015bmy odpowiednie zapytanie filtruj\u0105ce wyniki.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Podsumowanie<\/h2>\n\n\n\n<p>SharePoint jest pot\u0119\u017cn\u0105, wielozadaniow\u0105 platform\u0105, kt\u00f3ra u\u0142atwia zarz\u0105dzanie przep\u0142ywem danych i pracy w sieciach korporacyjnych. Dlatego te\u017c poznanie jego struktury, specyfiki, a tak\u017ce metod tworzenia oprogramowania w ramach tej platformy wymaga czasu i cierpliwo\u015bci, a przede wszystkim praktyki. Mam nadziej\u0119, \u017ce ten artyku\u0142 b\u0119dzie wsparciem w zdobywaniu do\u015bwiadczenia w tworzeniu aplikacji na platform\u0119 SharePoint.<\/p>\n\n\n<div class=\"kk-star-ratings kksr-auto kksr-align-left kksr-valign-bottom\"\n    data-payload='{&quot;align&quot;:&quot;left&quot;,&quot;id&quot;:&quot;9299&quot;,&quot;slug&quot;:&quot;default&quot;,&quot;valign&quot;:&quot;bottom&quot;,&quot;ignore&quot;:&quot;&quot;,&quot;reference&quot;:&quot;auto&quot;,&quot;class&quot;:&quot;&quot;,&quot;count&quot;:&quot;6&quot;,&quot;legendonly&quot;:&quot;&quot;,&quot;readonly&quot;:&quot;&quot;,&quot;score&quot;:&quot;4.3&quot;,&quot;starsonly&quot;:&quot;&quot;,&quot;best&quot;:&quot;5&quot;,&quot;gap&quot;:&quot;11&quot;,&quot;greet&quot;:&quot;&quot;,&quot;legend&quot;:&quot;4.3\\\/5 ( votes: 6)&quot;,&quot;size&quot;:&quot;18&quot;,&quot;title&quot;:&quot;Jak unikn\u0105\u0107 b\u0142\u0119d\u00f3w podczas programowania na platform\u0119 MS SharePoint 2016&quot;,&quot;width&quot;:&quot;119.2&quot;,&quot;_legend&quot;:&quot;{score}\\\/{best} ( {votes}: {count})&quot;,&quot;font_factor&quot;:&quot;1.25&quot;}'>\n            \n<div class=\"kksr-stars\">\n    \n<div class=\"kksr-stars-inactive\">\n            <div class=\"kksr-star\" data-star=\"1\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"2\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"3\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"4\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"5\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n    <\/div>\n    \n<div class=\"kksr-stars-active\" style=\"width: 119.2px;\">\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n    <\/div>\n<\/div>\n                \n\n<div class=\"kksr-legend\" style=\"font-size: 14.4px;\">\n            4.3\/5 ( votes: 6)    <\/div>\n    <\/div>\n","protected":false},"excerpt":{"rendered":"<p>Pocz\u0105tki cz\u0119sto bywaj\u0105 trudne. Pocz\u0105tek nauki nowej technologii tak\u017ce bywa trudny i nie jest wolny od b\u0142\u0119d\u00f3w.&nbsp;Na b\u0142\u0119dach mo\u017cna si\u0119 &hellip; <a class=\"continued-btn\" href=\"https:\/\/sii.pl\/blog\/jak-uniknac-bledow-podczas-programowania-na-platforme-ms-sharepoint-2016\/\">Continued<\/a><\/p>\n","protected":false},"author":253,"featured_media":9314,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_editorskit_title_hidden":false,"_editorskit_reading_time":0,"_editorskit_is_block_options_detached":false,"_editorskit_block_options_position":"{}","inline_featured_image":false,"footnotes":""},"categories":[1314],"tags":[56],"class_list":["post-9299","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-development-na-twardo","tag-sharepoint"],"acf":[],"aioseo_notices":[],"republish_history":[],"featured_media_url":"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2020\/06\/sharepoint.jpg","category_names":["Development na twardo"],"_links":{"self":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/9299"}],"collection":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/users\/253"}],"replies":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/comments?post=9299"}],"version-history":[{"count":3,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/9299\/revisions"}],"predecessor-version":[{"id":18669,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/9299\/revisions\/18669"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/media\/9314"}],"wp:attachment":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/media?parent=9299"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/categories?post=9299"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/tags?post=9299"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}