Merge remote-tracking branch 'origin/APIHelpPages' into CreateStaticFileHost

This commit is contained in:
chris.watts90@outlook.com 2017-01-30 20:39:20 +00:00
commit dcd99faa25
13 changed files with 465 additions and 2 deletions

View File

@ -0,0 +1,28 @@
@using System.Web.Http.Description
@using DalSoft.WebApi.HelpPage
@model IGrouping<string, ApiDescription>
<h2 id="@Model.Key">@Model.Key</h2>
<table class="help-page-table">
<thead>
<tr><th>API</th><th>Description</th></tr>
</thead>
<tbody>
@foreach (var api in Model)
{
<tr>
<td class="api-name"><a href="@ViewBag.HelpRoute/api?apiId=@api.GetFriendlyId()">@api.HttpMethod.Method @api.RelativePath</a></td>
<td class="api-documentation">
@if (api.Documentation !=null)
{
<p>@api.Documentation</p>
}
else
{
<p>No documentation available.</p>
}
</td>
</tr>
}
</tbody>
</table>

View File

@ -0,0 +1,49 @@
@using System.Collections.Generic
@using System.Net.Http.Headers
@using DalSoft.WebApi.HelpPage.Models
@model HelpPageApiModel
@{
var description = Model.ApiDescription;
var hasParameters = description.ParameterDescriptions.Count > 0;
var hasRequestSamples = Model.SampleRequests.Count > 0;
var hasResponseSamples = Model.SampleResponses.Count > 0;
}
<h1>@description.HttpMethod.Method @description.RelativePath</h1>
<div>
@{
if (description.Documentation != null)
{
<p>@description.Documentation</p>
}
else
{
<p>No documentation available.</p>
}
if (hasParameters || hasRequestSamples)
{
<h2>Request Information</h2>
if (hasParameters)
{
<h3>Parameters</h3>
@Include("Parameters.cshtml", Model, typeof(HelpPageApiModel))
}
if (hasRequestSamples)
{
<h3>Request body formats</h3>
var ModelSamples = Model.SampleRequests;
@Include("Samples.cshtml", ModelSamples, typeof(IDictionary<MediaTypeHeaderValue, object>))
}
}
if (hasResponseSamples)
{
<h2>Response Information</h2>
<h3>Response body formats</h3>
var ModelSamples = Model.SampleResponses;
@Include("Samples.cshtml", ModelSamples, typeof(IDictionary<MediaTypeHeaderValue, object>))
}
}
</div>

View File

@ -0,0 +1,55 @@
@using System.Collections.ObjectModel
@using System.Threading
@using System.Web.Http.Description
@{ Collection<ApiParameterDescription> parameters = Model.ApiDescription.ParameterDescriptions; }
@if (parameters.Count > 0)
{
<table class="help-page-table">
<thead>
<tr><th>Name</th><th>Description</th><th>Additional information</th></tr>
</thead>
<tbody>
@{
foreach (ApiParameterDescription parameter in parameters)
{
var parameterDocumentation = parameter.Documentation ?? "No documentation available.";
// Don't show CancellationToken because it's a special parameter
if (!typeof (CancellationToken).IsAssignableFrom(parameter.ParameterDescriptor.ParameterType))
{
<tr>
<td class="parameter-name">@parameter.Name</td>
<td class="parameter-documentation">
<p>@parameterDocumentation</p>
</td>
<td class="parameter-type">
@{
switch (parameter.Source)
{
case ApiParameterSource.FromBody:
<p>Define this parameter in the request <b>body</b>.
</p>
break;
case ApiParameterSource.FromUri:
<p>Define this parameter in the request <b>URI</b>.
</p>
break;
case ApiParameterSource.Unknown:
default:
<p>None.</p>
break;
}
}
</td>
</tr>
}
}
}
</tbody>
</table>
}
else
{
<p>None.</p>
}

View File

@ -0,0 +1,37 @@
@using System.Net.Http.Headers
@using DalSoft.WebApi.HelpPage.SampleGeneration
@model IDictionary<MediaTypeHeaderValue, object>
@{
// Group the samples into a single tab if they are the same.
var samples = Model.GroupBy(x => x.Value).ToDictionary(x => string.Join(", ", x.Select(m => m.Key.ToString()).ToArray()), x => x.Key);
var mediaTypes = samples.Keys;
}
<div>
@{
foreach (var mediaType in mediaTypes)
{
<h4 class="sample-header">@mediaType</h4>
<div class="sample-content">
<span><b>Sample:</b></span>
@{ var sample = samples[mediaType]; }
@if (sample == null)
{
<p>Sample not available.</p>
}
else if (sample is TextSample)
{
<pre class="wrapped">@(((TextSample)sample).Text)</pre>
}
else if (sample is ImageSample)
{
<img src="@(((ImageSample)sample).Src)"/>
}
else if (sample is InvalidSample)
{
<div class="warning-message-container">@(((InvalidSample)sample).ErrorMessage)</div>
}
</div>
}
}
</div>

View File

@ -0,0 +1,134 @@
.help-page h1,
.help-page .h1,
.help-page h2,
.help-page .h2,
.help-page h3,
.help-page .h3,
#body.help-page,
.help-page-table th,
.help-page-table pre,
.help-page-table p {
font-family: "Segoe UI Light", Frutiger, "Frutiger Linotype", "Dejavu Sans", "Helvetica Neue", Arial, sans-serif;
}
.help-page pre.wrapped {
white-space: -moz-pre-wrap;
white-space: -pre-wrap;
white-space: -o-pre-wrap;
white-space: pre-wrap;
}
.help-page .warning-message-container {
margin-top: 20px;
padding: 0 10px;
color: #525252;
background: #EFDCA9;
border: 1px solid #CCCCCC;
}
.help-page-table {
width: 100%;
border-collapse: collapse;
text-align: left;
margin: 0px 0px 20px 0px;
border-top: 1px solid #D4D4D4;
}
.help-page-table th {
text-align: left;
font-weight: bold;
border-bottom: 1px solid #D4D4D4;
padding: 5px 6px 5px 6px;
}
.help-page-table td {
border-bottom: 1px solid #D4D4D4;
padding: 10px 8px 10px 8px;
vertical-align: top;
}
.help-page-table pre,
.help-page-table p {
margin: 0px;
padding: 0px;
font-family: inherit;
font-size: 100%;
}
.help-page-table tbody tr:hover td {
background-color: #F3F3F3;
}
.help-page a:hover {
background-color: transparent;
}
.help-page .sample-header {
border: 2px solid #D4D4D4;
background: #00497E;
color: #FFFFFF;
padding: 8px 15px;
border-bottom: none;
display: inline-block;
margin: 10px 0px 0px 0px;
}
.help-page .sample-content {
display: block;
border-width: 0;
padding: 15px 20px;
background: #FFFFFF;
border: 2px solid #D4D4D4;
margin: 0px 0px 10px 0px;
}
.help-page .api-name {
width: 40%;
}
.help-page .api-documentation {
width: 60%;
}
.help-page .parameter-name {
width: 20%;
}
.help-page .parameter-documentation {
width: 40%;
}
.help-page .parameter-type {
width: 20%;
}
.help-page .parameter-annotations {
width: 20%;
}
.help-page h1,
.help-page .h1 {
font-size: 36px;
line-height: normal;
}
.help-page h2,
.help-page .h2 {
font-size: 24px;
}
.help-page h3,
.help-page .h3 {
font-size: 20px;
}
#body.help-page {
font-size: 14px;
line-height: 143%;
color: #333;
}
.help-page a {
color: #0000EE;
text-decoration: none;
}

View File

@ -0,0 +1,28 @@
@using DalSoft.WebApi.HelpPage.Models
@model HelpPageApiModel
@{
var description = Model.ApiDescription;
var title = description.HttpMethod.Method + " " + description.RelativePath;
}
<!DOCTYPE html>
<html>
<head>
<title>@title</title>
<link type="text/css" href="@ViewBag.HelpRoute/HelpPage_css" rel="stylesheet" />
</head>
<body>
<div id="body" class="help-page">
<section class="featured">
<div class="content-wrapper">
<p>
<a href="/@ViewBag.HelpRoute">Help Page Home</a>
</p>
</div>
</section>
<section class="content-wrapper main-content clear-fix">
@Include("HelpPageApiModel.cshtml", Model, typeof(HelpPageApiModel))
</section>
</div>
</body>
</html>

View File

@ -0,0 +1,43 @@
@using System.Web.Http.Description
@using System.Collections.ObjectModel
@using System.Linq
@model Collection<ApiDescription>
@{
ViewBag.Title = "ASP.NET Web API Help Page";
// Group APIs by controller
ILookup<string, ApiDescription> apiGroups = Model.ToLookup(api => api.ActionDescriptor.ControllerDescriptor.ControllerName);
}
<!DOCTYPE html>
<html>
<head>
<title>@ViewBag.Title</title>
<link type="text/css" href="@ViewBag.HelpRoute/HelpPage_css" rel="stylesheet" />
</head>
<body>
<header class="help-page">
<div class="content-wrapper">
<div class="float-left">
<h1>@ViewBag.Title</h1>
</div>
</div>
</header>
<div id="body" class="help-page">
<section class="featured">
<div class="content-wrapper">
<h2>Introduction</h2>
<p>
Provide a general description of your APIs here.
</p>
</div>
</section>
<section class="content-wrapper main-content clear-fix">
@foreach (IGrouping<string, ApiDescription> controllerGroup in apiGroups)
{
@Include("ApiGroup.cshtml", controllerGroup, typeof (IGrouping<string, ApiDescription>))
}
</section>
</div>
</body>
</html>

View File

@ -11,6 +11,7 @@ using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Web.Http; using System.Web.Http;
using DalSoft.WebApi.HelpPage;
using Microsoft.Owin.FileSystems; using Microsoft.Owin.FileSystems;
using Microsoft.Owin.Hosting; using Microsoft.Owin.Hosting;
using Microsoft.Owin.StaticFiles; using Microsoft.Owin.StaticFiles;
@ -84,6 +85,11 @@ namespace WindowsDataCenter
appBuilder.UseWebApi(config); appBuilder.UseWebApi(config);
#if DEBUG
//Add the help-pages extension only in Debug mode.
appBuilder.UseWebApiHelpPage(config, "help-pages");
#endif
var fileSystem = new PhysicalFileSystem(@"./www"); var fileSystem = new PhysicalFileSystem(@"./www");
var options = new FileServerOptions var options = new FileServerOptions
{ {

View File

@ -22,6 +22,7 @@
<DefineConstants>DEBUG;TRACE</DefineConstants> <DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<DocumentationFile>bin\Debug\WindowsDataCenter.XML</DocumentationFile>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget> <PlatformTarget>AnyCPU</PlatformTarget>
@ -33,6 +34,10 @@
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="DalSoft.WebApi.HelpPage, Version=0.0.7.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\DalSoft.WebApi.HelpPage.0.0.7.0\lib\net451\DalSoft.WebApi.HelpPage.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Owin, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> <Reference Include="Microsoft.Owin, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll</HintPath> <HintPath>..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll</HintPath>
<Private>True</Private> <Private>True</Private>
@ -61,6 +66,10 @@
<HintPath>..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath> <HintPath>..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath>
<Private>True</Private> <Private>True</Private>
</Reference> </Reference>
<Reference Include="RazorEngine, Version=3.7.2.0, Culture=neutral, PublicKeyToken=9ee697374c7e744a, processorArchitecture=MSIL">
<HintPath>..\packages\RazorEngine.3.7.2\lib\net45\RazorEngine.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />
<Reference Include="System.Net.Http.Formatting, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> <Reference Include="System.Net.Http.Formatting, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
@ -80,6 +89,10 @@
<HintPath>..\packages\Microsoft.AspNet.WebApi.WebHost.5.2.3\lib\net45\System.Web.Http.WebHost.dll</HintPath> <HintPath>..\packages\Microsoft.AspNet.WebApi.WebHost.5.2.3\lib\net45\System.Web.Http.WebHost.dll</HintPath>
<Private>True</Private> <Private>True</Private>
</Reference> </Reference>
<Reference Include="System.Web.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.Razor.3.0.0\lib\net45\System.Web.Razor.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Xml.Linq" /> <Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" /> <Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" /> <Reference Include="Microsoft.CSharp" />
@ -102,6 +115,24 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="App.config" /> <None Include="App.config" />
<Content Include="Help\DalSoft.WebApi.HelpPage.Views\api.cshtml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Help\DalSoft.WebApi.HelpPage.Views\DisplayTemplates\ApiGroup.cshtml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Help\DalSoft.WebApi.HelpPage.Views\DisplayTemplates\HelpPageApiModel.cshtml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Help\DalSoft.WebApi.HelpPage.Views\DisplayTemplates\Parameters.cshtml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Help\DalSoft.WebApi.HelpPage.Views\DisplayTemplates\Samples.cshtml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Help\DalSoft.WebApi.HelpPage.Views\index.cshtml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<None Include="packages.config" /> <None Include="packages.config" />
<None Include="www\css\bootstrap-grid.css.map"> <None Include="www\css\bootstrap-grid.css.map">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
@ -123,6 +154,9 @@
</None> </None>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="Help\DalSoft.WebApi.HelpPage.Views\HelpPage.css">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="www\css\bootstrap-grid.css"> <Content Include="www\css\bootstrap-grid.css">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>

View File

@ -1,5 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="DalSoft.WebApi.HelpPage" version="0.0.7.0" targetFramework="net452" />
<package id="Microsoft.AspNet.Razor" version="3.0.0" targetFramework="net452" />
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net452" /> <package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net452" />
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net452" /> <package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net452" />
<package id="Microsoft.AspNet.WebApi.Owin" version="5.2.3" targetFramework="net452" /> <package id="Microsoft.AspNet.WebApi.Owin" version="5.2.3" targetFramework="net452" />
@ -12,4 +14,5 @@
<package id="Microsoft.Owin.StaticFiles" version="3.0.1" targetFramework="net452" /> <package id="Microsoft.Owin.StaticFiles" version="3.0.1" targetFramework="net452" />
<package id="Newtonsoft.Json" version="6.0.4" targetFramework="net452" /> <package id="Newtonsoft.Json" version="6.0.4" targetFramework="net452" />
<package id="Owin" version="1.0" targetFramework="net452" /> <package id="Owin" version="1.0" targetFramework="net452" />
<package id="RazorEngine" version="3.7.2" targetFramework="net452" />
</packages> </packages>

View File

@ -33,13 +33,41 @@
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="Microsoft.Owin, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Owin.Host.HttpListener, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> <Reference Include="Microsoft.Owin.Host.HttpListener, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.Host.HttpListener.3.0.1\lib\net45\Microsoft.Owin.Host.HttpListener.dll</HintPath> <HintPath>..\packages\Microsoft.Owin.Host.HttpListener.3.0.1\lib\net45\Microsoft.Owin.Host.HttpListener.dll</HintPath>
<Private>True</Private> <Private>True</Private>
</Reference> </Reference>
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.6.0.4\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5, processorArchitecture=MSIL">
<HintPath>..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="RazorEngine, Version=3.7.2.0, Culture=neutral, PublicKeyToken=9ee697374c7e744a, processorArchitecture=MSIL">
<HintPath>..\packages\RazorEngine.3.7.2\lib\net45\RazorEngine.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />
<Reference Include="System.Net.Http.Formatting, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.ServiceProcess" /> <Reference Include="System.ServiceProcess" />
<Reference Include="System.Web.Http, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Web.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.Razor.3.0.0\lib\net45\System.Web.Razor.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Xml.Linq" /> <Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" /> <Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" /> <Reference Include="Microsoft.CSharp" />

View File

@ -1,4 +1,11 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="Microsoft.AspNet.Razor" version="3.0.0" targetFramework="net452" />
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net452" />
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net452" />
<package id="Microsoft.Owin" version="3.0.1" targetFramework="net452" />
<package id="Microsoft.Owin.Host.HttpListener" version="3.0.1" targetFramework="net452" /> <package id="Microsoft.Owin.Host.HttpListener" version="3.0.1" targetFramework="net452" />
<package id="Newtonsoft.Json" version="6.0.4" targetFramework="net452" />
<package id="Owin" version="1.0" targetFramework="net452" />
<package id="RazorEngine" version="3.7.2" targetFramework="net452" />
</packages> </packages>

View File

@ -1,8 +1,17 @@
module.exports = function(){ module.exports = function(){
var fakeTimeDataCount = 4000, maxUserCount = 120, unassignedCardCount = 4; var fakeTimeDataCount = 4000, maxUserCount = 120, unassignedCardCount = 4, maxValidCardCount = 150;
var faker = require("faker"); var faker = require("faker");
var _ = require("lodash"); var _ = require("lodash");
var directions = ["in", "out"]; var directions = ["in", "out"];
var validCards = _.times(maxValidCardCount, function(n){
return{
id:n,
Id:n,
UserId_FK: faker.random.number(maxUserCount),
IsSelected: true,
CardUId: faker.random.uuid()
};
});
var usersData = _.times(maxUserCount, function (n) var usersData = _.times(maxUserCount, function (n)
{ {
return { return {
@ -11,7 +20,9 @@ module.exports = function(){
UserId: n, UserId: n,
FirstName: faker.name.firstName(), FirstName: faker.name.firstName(),
LastName: faker.name.lastName(), LastName: faker.name.lastName(),
HoursPerWeek: 37.0 HoursPerWeek: 37.0,
AssociatedCardCount: _.filter(validCards, {'UserId_FK': n}).length,
AssociatedCards: _.filter(validCards, {'UserId_FK': n})
} }
} }
); );