A Microsoft.AspNet.WebApi.HelpPage NuGet csomag segítségével nagyon könnyen generálhatunk egészen barátságos dokumentációt a WebAPI-nkhoz. A megoldás alapja, hogy a WebAPI projekt kommentjeiből a C# fordítót felhasználva XML fájlt készítünk, amit aztán egy MVC controller felolvas, és barátságos HTML oldalakká fordít.
A problémák akkor jönnek, ha a a REST API publikus interfészén olyan típusok találhatóak, amik nem a WebAPI projektben vannak, hanem egy másik DLL-ben, ugyanis a másik DLL – tipikusan library – kommentjeiből generált XML fájl ugyan bekerül az API bin mappájába, de a webdeploy már nem viszi magával, tehát futási időben nem lesz ott a megfelelő helyen.
A probléma két lépésben orvosolható:
- A library XML fájljának bele kell kerülnie a webdeploy csomagba.
- A controllert át kell írni, hogy több XML fájllal is működjön.
A webdeploy csomag kiegészítése
A webdeploy csomag úgy készül, hogy fordítás után összemásolódik az összes fájl egy mappába, majd ennek a mappának a tartalmából áll össze a csomag. Mivel ezt a folyamatot az MSBuild vezérli, kis trükkel újabb fájlt is be tudunk tenni ebbe az ideiglenes mappába. Mindössze a WebAPI projekthez tartozó .csproj fájlt kell kiegészítenünk:
<Target Name="CopyAdditionalFiles"> <Message Text="Copy additional files..." Importance="high"/> <ItemGroup> <_CustomFiles Include="$(ProjectDir)bin\MyLib.xml" /> <FilesForPackagingFromProject Include="%(_CustomFiles.Identity)"> <DestinationRelativePath>bin\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath> </FilesForPackagingFromProject> </ItemGroup> </Target> <PropertyGroup> <CopyAllFilesToSingleFolderForMsdeployDependsOn> CopyAdditionalFiles; $(CopyAllFilesToSingleFolderForMsdeployDependsOn); </CopyAllFilesToSingleFolderForMsdeployDependsOn> </PropertyGroup>
A fenti módosítás Visual Studio 2012-től kezdve működik, a korábbi verziókhoz képest ugyanis átnevezték a CopyAllFilesToSingleFolderForMsdeployDependsOn elemet.
Dokumentáció generálása több XML fájlból
A fent említett NuGet csomag egyetlen XML fájlból tud dokumentációt előállítani. Ha azt szeretnénk, hogy több fájllal is megbirkózzon, akkor módosítanunk kell az XmlDocumentationProvider osztály konstruktorát:
public XmlDocumentationProvider(IEnumerable<string> documentPaths) { if (documentPaths == null) { throw new ArgumentNullException("documentPaths"); } XDocument finalDoc = null; foreach (string documentPath in documentPaths) { if (finalDoc == null) { finalDoc = XDocument.Load(File.OpenRead(documentPath)); } else { XDocument additionalDoc = XDocument.Load(File.OpenRead(documentPath)); finalDoc.Root.XPathSelectElement("/doc/members") .Add(additionalDoc.Root.XPathSelectElement("/doc/members").Elements()); } } _documentNavigator = finalDoc.CreateNavigator(); }
A módosítás eredményeként a konstruktornak már több fájl útvonalát kell átadni a korábbi egy helyett. Az elsőt ugyanúgy fogja betölteni, mint korábban, a többit pedig utána fogja fűzni a memóriában. A végeredmény egyetlen nagy XML dokumentum, így a NuGet csomag többi részét nem is kell módosítanunk.
Természetesen a HelpPageConfig.cs-ben már tömb paraméterrel kell meghívnunk a konstruktort, például:
string[] documentPaths = { HttpContext.Current.Server.MapPath("~/bin/MyAPI.xml"), HttpContext.Current.Server.MapPath("~/bin/MyLib.xml") }; config.SetDocumentationProvider(new XmlDocumentationProvider(documentPaths));