This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{9003B29C-AC1D-444E-8FE2-201F76D848A5}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Ewide.Core.Arguments</RootNamespace>
|
||||
<AssemblyName>Ewide.Core.Arguments</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<Deterministic>true</Deterministic>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
@@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// 有关程序集的一般信息由以下
|
||||
// 控制。更改这些特性值可修改
|
||||
// 与程序集关联的信息。
|
||||
[assembly: AssemblyTitle("Ewide.Core.Arguments")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Ewide.Core.Arguments")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2021")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// 将 ComVisible 设置为 false 会使此程序集中的类型
|
||||
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
|
||||
//请将此类型的 ComVisible 特性设置为 true。
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
|
||||
[assembly: Guid("9003b29c-ac1d-444e-8fe2-201f76d848a5")]
|
||||
|
||||
// 程序集的版本信息由下列四个值组成:
|
||||
//
|
||||
// 主版本
|
||||
// 次版本
|
||||
// 生成号
|
||||
// 修订号
|
||||
//
|
||||
// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
|
||||
//通过使用 "*",如下所示:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
50
Api/Ewide.Core/Ewide.Core.Common/BaseDisplayJSON.cs
Normal file
50
Api/Ewide.Core/Ewide.Core.Common/BaseDisplayJSON.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ewide.Core.Common
|
||||
{
|
||||
public class BaseDisplayJSON
|
||||
{
|
||||
public static object Display(HttpStatusCode status, object result)
|
||||
{
|
||||
return new
|
||||
{
|
||||
Status = status,
|
||||
Result = result
|
||||
};
|
||||
}
|
||||
|
||||
public static object Display(HttpStatusCode status, string message)
|
||||
{
|
||||
return new
|
||||
{
|
||||
Status = status,
|
||||
Message = message
|
||||
};
|
||||
}
|
||||
|
||||
public static object Ok(object result)
|
||||
{
|
||||
return Display(HttpStatusCode.OK, result);
|
||||
}
|
||||
|
||||
public static object Ok(string message)
|
||||
{
|
||||
return Display(HttpStatusCode.OK, message);
|
||||
}
|
||||
|
||||
public static object Error(string message)
|
||||
{
|
||||
return Display(HttpStatusCode.InternalServerError, message);
|
||||
}
|
||||
|
||||
public static object Unauthorized(string message)
|
||||
{
|
||||
return Display(HttpStatusCode.Unauthorized, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
20
Api/Ewide.Core/Ewide.Core.Common/EnumCode/ResponseStatus.cs
Normal file
20
Api/Ewide.Core/Ewide.Core.Common/EnumCode/ResponseStatus.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ewide.Core.Common
|
||||
{
|
||||
public enum ResponseStatus
|
||||
{
|
||||
// 权限验证失败
|
||||
Unauthorized = 401,
|
||||
// 未找到
|
||||
NotFound = 404,
|
||||
// 接口错误
|
||||
Error = 500,
|
||||
// 接口成功
|
||||
Success = 200
|
||||
}
|
||||
}
|
||||
49
Api/Ewide.Core/Ewide.Core.Common/Ewide.Core.Common.csproj
Normal file
49
Api/Ewide.Core/Ewide.Core.Common/Ewide.Core.Common.csproj
Normal file
@@ -0,0 +1,49 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{C7E2AC14-AC20-4552-A5B8-08B650AC8416}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Ewide.Core.Common</RootNamespace>
|
||||
<AssemblyName>Ewide.Core.Common</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<Deterministic>true</Deterministic>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="BaseDisplayJSON.cs" />
|
||||
<Compile Include="EnumCode\ResponseStatus.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
36
Api/Ewide.Core/Ewide.Core.Common/Properties/AssemblyInfo.cs
Normal file
36
Api/Ewide.Core/Ewide.Core.Common/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// 有关程序集的一般信息由以下
|
||||
// 控制。更改这些特性值可修改
|
||||
// 与程序集关联的信息。
|
||||
[assembly: AssemblyTitle("Ewide.Core.Common")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Ewide.Core.Common")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2021")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// 将 ComVisible 设置为 false 会使此程序集中的类型
|
||||
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
|
||||
//请将此类型的 ComVisible 特性设置为 true。
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
|
||||
[assembly: Guid("c7e2ac14-ac20-4552-a5b8-08b650ac8416")]
|
||||
|
||||
// 程序集的版本信息由下列四个值组成:
|
||||
//
|
||||
// 主版本
|
||||
// 次版本
|
||||
// 生成号
|
||||
// 修订号
|
||||
//
|
||||
// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
|
||||
//通过使用 "*",如下所示:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
47
Api/Ewide.Core/Ewide.Core.Model/Ewide.Core.Model.csproj
Normal file
47
Api/Ewide.Core/Ewide.Core.Model/Ewide.Core.Model.csproj
Normal file
@@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{31C3CA3D-14A1-453A-866D-76D4C74A9BDC}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Ewide.Core.Model</RootNamespace>
|
||||
<AssemblyName>Ewide.Core.Model</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<Deterministic>true</Deterministic>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
36
Api/Ewide.Core/Ewide.Core.Model/Properties/AssemblyInfo.cs
Normal file
36
Api/Ewide.Core/Ewide.Core.Model/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// 有关程序集的一般信息由以下
|
||||
// 控制。更改这些特性值可修改
|
||||
// 与程序集关联的信息。
|
||||
[assembly: AssemblyTitle("Ewide.Core.Model")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Ewide.Core.Model")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2021")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// 将 ComVisible 设置为 false 会使此程序集中的类型
|
||||
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
|
||||
//请将此类型的 ComVisible 特性设置为 true。
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
|
||||
[assembly: Guid("31c3ca3d-14a1-453a-866d-76d4c74a9bdc")]
|
||||
|
||||
// 程序集的版本信息由下列四个值组成:
|
||||
//
|
||||
// 主版本
|
||||
// 次版本
|
||||
// 生成号
|
||||
// 修订号
|
||||
//
|
||||
// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
|
||||
//通过使用 "*",如下所示:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
57
Api/Ewide.Core/Ewide.Core.Service/Ewide.Core.Service.csproj
Normal file
57
Api/Ewide.Core/Ewide.Core.Service/Ewide.Core.Service.csproj
Normal file
@@ -0,0 +1,57 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{34AE80C2-5C37-4B6C-AAC3-F52C06928721}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Ewide.Core.Service</RootNamespace>
|
||||
<AssemblyName>Ewide.Core.Service</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<Deterministic>true</Deterministic>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Ewide.Core.Model\Ewide.Core.Model.csproj">
|
||||
<Project>{31c3ca3d-14a1-453a-866d-76d4c74a9bdc}</Project>
|
||||
<Name>Ewide.Core.Model</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Ewide.Core.Utility\Ewide.Core.Utility.csproj">
|
||||
<Project>{d5c48d01-5ab1-44c9-8709-d4a336d19e9f}</Project>
|
||||
<Name>Ewide.Core.Utility</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
36
Api/Ewide.Core/Ewide.Core.Service/Properties/AssemblyInfo.cs
Normal file
36
Api/Ewide.Core/Ewide.Core.Service/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// 有关程序集的一般信息由以下
|
||||
// 控制。更改这些特性值可修改
|
||||
// 与程序集关联的信息。
|
||||
[assembly: AssemblyTitle("Ewide.Core.Service")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Ewide.Core.Service")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2021")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// 将 ComVisible 设置为 false 会使此程序集中的类型
|
||||
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
|
||||
//请将此类型的 ComVisible 特性设置为 true。
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
|
||||
[assembly: Guid("34ae80c2-5c37-4b6c-aac3-f52c06928721")]
|
||||
|
||||
// 程序集的版本信息由下列四个值组成:
|
||||
//
|
||||
// 主版本
|
||||
// 次版本
|
||||
// 生成号
|
||||
// 修订号
|
||||
//
|
||||
// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
|
||||
//通过使用 "*",如下所示:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
47
Api/Ewide.Core/Ewide.Core.Utility/Ewide.Core.Utility.csproj
Normal file
47
Api/Ewide.Core/Ewide.Core.Utility/Ewide.Core.Utility.csproj
Normal file
@@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{D5C48D01-5AB1-44C9-8709-D4A336D19E9F}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Ewide.Core.Utility</RootNamespace>
|
||||
<AssemblyName>Ewide.Core.Utility</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<Deterministic>true</Deterministic>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
36
Api/Ewide.Core/Ewide.Core.Utility/Properties/AssemblyInfo.cs
Normal file
36
Api/Ewide.Core/Ewide.Core.Utility/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// 有关程序集的一般信息由以下
|
||||
// 控制。更改这些特性值可修改
|
||||
// 与程序集关联的信息。
|
||||
[assembly: AssemblyTitle("Ewide.Core.Utility")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Ewide.Core.Utility")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2021")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// 将 ComVisible 设置为 false 会使此程序集中的类型
|
||||
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
|
||||
//请将此类型的 ComVisible 特性设置为 true。
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
|
||||
[assembly: Guid("d5c48d01-5ab1-44c9-8709-d4a336d19e9f")]
|
||||
|
||||
// 程序集的版本信息由下列四个值组成:
|
||||
//
|
||||
// 主版本
|
||||
// 次版本
|
||||
// 生成号
|
||||
// 修订号
|
||||
//
|
||||
// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
|
||||
//通过使用 "*",如下所示:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
27
Api/Ewide.Core/Ewide.Core.WebApi/App_Start/BundleConfig.cs
Normal file
27
Api/Ewide.Core/Ewide.Core.WebApi/App_Start/BundleConfig.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using System.Web;
|
||||
using System.Web.Optimization;
|
||||
|
||||
namespace Ewide.Core.WebApi
|
||||
{
|
||||
public class BundleConfig
|
||||
{
|
||||
// 有关捆绑的详细信息,请访问 https://go.microsoft.com/fwlink/?LinkId=301862
|
||||
public static void RegisterBundles(BundleCollection bundles)
|
||||
{
|
||||
bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
|
||||
"~/Scripts/jquery-{version}.js"));
|
||||
|
||||
// 使用要用于开发和学习的 Modernizr 的开发版本。然后,当你做好
|
||||
// 生产准备就绪,请使用 https://modernizr.com 上的生成工具仅选择所需的测试。
|
||||
bundles.Add(new ScriptBundle("~/bundles/modernizr").Include(
|
||||
"~/Scripts/modernizr-*"));
|
||||
|
||||
bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include(
|
||||
"~/Scripts/bootstrap.js"));
|
||||
|
||||
bundles.Add(new StyleBundle("~/Content/css").Include(
|
||||
"~/Content/bootstrap.css",
|
||||
"~/Content/site.css"));
|
||||
}
|
||||
}
|
||||
}
|
||||
13
Api/Ewide.Core/Ewide.Core.WebApi/App_Start/FilterConfig.cs
Normal file
13
Api/Ewide.Core/Ewide.Core.WebApi/App_Start/FilterConfig.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using System.Web;
|
||||
using System.Web.Mvc;
|
||||
|
||||
namespace Ewide.Core.WebApi
|
||||
{
|
||||
public class FilterConfig
|
||||
{
|
||||
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
|
||||
{
|
||||
filters.Add(new HandleErrorAttribute());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using Ewide.Core.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Formatting;
|
||||
using System.Web;
|
||||
using System.Web.Http;
|
||||
using System.Web.Http.Controllers;
|
||||
|
||||
namespace Ewide.Core.WebApi
|
||||
{
|
||||
public class HttpNotFoundControllerActionSelector : ApiControllerActionSelector
|
||||
{
|
||||
public HttpNotFoundControllerActionSelector(HttpConfiguration configuration) { }
|
||||
public override HttpActionDescriptor SelectAction(HttpControllerContext controllerContext)
|
||||
{
|
||||
var formatter = new JsonMediaTypeFormatter();
|
||||
formatter.SerializerSettings.ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver();
|
||||
|
||||
HttpActionDescriptor decriptor = null;
|
||||
try
|
||||
{
|
||||
decriptor = base.SelectAction(controllerContext);
|
||||
}
|
||||
catch (HttpResponseException ex)
|
||||
{
|
||||
var code = ex.Response.StatusCode;
|
||||
var result = BaseDisplayJSON.Display(code, "请求方式错误");
|
||||
if (code == HttpStatusCode.NotFound || code == HttpStatusCode.MethodNotAllowed)
|
||||
{
|
||||
ex.Response.Content = new ObjectContent(result.GetType(), result, formatter);
|
||||
}
|
||||
ex.Response.StatusCode = HttpStatusCode.OK;
|
||||
throw ex;
|
||||
}
|
||||
return decriptor;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using Ewide.Core.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Formatting;
|
||||
using System.Web;
|
||||
using System.Web.Http;
|
||||
using System.Web.Http.Controllers;
|
||||
using System.Web.Http.Dispatcher;
|
||||
|
||||
namespace Ewide.Core.WebApi
|
||||
{
|
||||
public class HttpNotFoundDefaultHttpControllerSelector : DefaultHttpControllerSelector
|
||||
{
|
||||
public HttpNotFoundDefaultHttpControllerSelector(HttpConfiguration configuration) : base(configuration) { }
|
||||
public override HttpControllerDescriptor SelectController(HttpRequestMessage request)
|
||||
{
|
||||
var formatter = new JsonMediaTypeFormatter();
|
||||
formatter.SerializerSettings.ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver();
|
||||
|
||||
HttpControllerDescriptor decriptor = null;
|
||||
try
|
||||
{
|
||||
decriptor = base.SelectController(request);
|
||||
}
|
||||
catch (HttpResponseException ex)
|
||||
{
|
||||
var code = ex.Response.StatusCode;
|
||||
var result = BaseDisplayJSON.Display(code, "找不到接口,请确认接口地址是否正确");
|
||||
if (code == HttpStatusCode.NotFound || code == HttpStatusCode.MethodNotAllowed)
|
||||
{
|
||||
ex.Response.Content = new ObjectContent(result.GetType(), result, formatter);
|
||||
}
|
||||
ex.Response.StatusCode = HttpStatusCode.OK;
|
||||
throw ex;
|
||||
}
|
||||
return decriptor;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using Ewide.Core.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Formatting;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using System.Web.Http;
|
||||
using System.Web.Http.Controllers;
|
||||
|
||||
namespace Ewide.Core.WebApi
|
||||
{
|
||||
public class HttpWebApiControllerActionInvoker : ApiControllerActionInvoker
|
||||
{
|
||||
public HttpWebApiControllerActionInvoker(HttpConfiguration configuration) { }
|
||||
public override Task<HttpResponseMessage> InvokeActionAsync(HttpActionContext actionContext, CancellationToken cancellationToken)
|
||||
{
|
||||
var formatter = new JsonMediaTypeFormatter();
|
||||
formatter.SerializerSettings.ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver();
|
||||
|
||||
var responseMessage = base.InvokeActionAsync(actionContext, cancellationToken);
|
||||
|
||||
if (responseMessage.Exception != null)
|
||||
{
|
||||
var baseException = responseMessage.Exception.InnerExceptions[0];
|
||||
var message = baseException.Message;
|
||||
|
||||
var result = BaseDisplayJSON.Display(HttpStatusCode.InternalServerError, message);
|
||||
|
||||
if (baseException is TimeoutException)
|
||||
{
|
||||
result = BaseDisplayJSON.Display(HttpStatusCode.RequestTimeout, message);
|
||||
}
|
||||
|
||||
return Task.Run(() => new HttpResponseMessage()
|
||||
{
|
||||
Content = new ObjectContent(result.GetType(), result, formatter),
|
||||
StatusCode = HttpStatusCode.OK
|
||||
}, cancellationToken);
|
||||
}
|
||||
return responseMessage;
|
||||
}
|
||||
}
|
||||
}
|
||||
23
Api/Ewide.Core/Ewide.Core.WebApi/App_Start/RouteConfig.cs
Normal file
23
Api/Ewide.Core/Ewide.Core.WebApi/App_Start/RouteConfig.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Routing;
|
||||
|
||||
namespace Ewide.Core.WebApi
|
||||
{
|
||||
public class RouteConfig
|
||||
{
|
||||
public static void RegisterRoutes(RouteCollection routes)
|
||||
{
|
||||
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
|
||||
|
||||
routes.MapRoute(
|
||||
name: "Default",
|
||||
url: "{controller}/{action}/{id}",
|
||||
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
36
Api/Ewide.Core/Ewide.Core.WebApi/App_Start/WebApiConfig.cs
Normal file
36
Api/Ewide.Core/Ewide.Core.WebApi/App_Start/WebApiConfig.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web.Http;
|
||||
using System.Web.Http.Controllers;
|
||||
using System.Web.Http.Dispatcher;
|
||||
|
||||
namespace Ewide.Core.WebApi
|
||||
{
|
||||
public static class WebApiConfig
|
||||
{
|
||||
public static void Register(HttpConfiguration config)
|
||||
{
|
||||
// Web API 配置和服务
|
||||
|
||||
// Web API 路由
|
||||
config.MapHttpAttributeRoutes();
|
||||
|
||||
config.Services.Replace(typeof(IHttpControllerSelector), new HttpNotFoundDefaultHttpControllerSelector(config));
|
||||
config.Services.Replace(typeof(IHttpActionInvoker), new HttpWebApiControllerActionInvoker(config));
|
||||
config.Services.Replace(typeof(IHttpActionSelector), new HttpNotFoundControllerActionSelector(config));
|
||||
|
||||
config.Routes.MapHttpRoute(
|
||||
name: "DefaultApi",
|
||||
routeTemplate: "api/{controller}/{id}",
|
||||
defaults: new { id = RouteParameter.Optional }
|
||||
);
|
||||
|
||||
config.Routes.MapHttpRoute(
|
||||
name: "DefaultAreaApi",
|
||||
routeTemplate: "api/{area}/{controller}/{action}/{id}",
|
||||
defaults: new { id = RouteParameter.Optional }
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Web.Http;
|
||||
|
||||
namespace Ewide.Core.WebApi.Areas.Gate.Controllers
|
||||
{
|
||||
public class LoginController : BaseController
|
||||
{
|
||||
public IHttpActionResult Index()
|
||||
{
|
||||
return DisplayJSON("123");
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public IHttpActionResult Test()
|
||||
{
|
||||
throw new Exception("dsds");
|
||||
return DisplayJSON("123");
|
||||
}
|
||||
|
||||
public IHttpActionResult Aaa()
|
||||
{
|
||||
return DisplayJSON("aaa");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using System.Web.Mvc;
|
||||
|
||||
namespace Ewide.Core.WebApi.Areas.Gate
|
||||
{
|
||||
public class GateAreaRegistration : AreaRegistration
|
||||
{
|
||||
public override string AreaName
|
||||
{
|
||||
get
|
||||
{
|
||||
return "Gate";
|
||||
}
|
||||
}
|
||||
|
||||
public override void RegisterArea(AreaRegistrationContext context)
|
||||
{
|
||||
context.MapRoute(
|
||||
"Gate_default",
|
||||
"Gate/{controller}/{action}/{id}",
|
||||
new { action = "Index", id = UrlParameter.Optional }
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
36
Api/Ewide.Core/Ewide.Core.WebApi/Areas/Gate/Views/web.config
Normal file
36
Api/Ewide.Core/Ewide.Core.WebApi/Areas/Gate/Views/web.config
Normal file
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<configuration>
|
||||
<configSections>
|
||||
<sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
|
||||
<section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
|
||||
<section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
|
||||
</sectionGroup>
|
||||
</configSections>
|
||||
|
||||
<system.web.webPages.razor>
|
||||
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.4.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
|
||||
<pages pageBaseType="System.Web.Mvc.WebViewPage">
|
||||
<namespaces>
|
||||
<add namespace="System.Web.Mvc" />
|
||||
<add namespace="System.Web.Mvc.Ajax" />
|
||||
<add namespace="System.Web.Mvc.Html" />
|
||||
<add namespace="System.Web.Routing" />
|
||||
<add namespace="System.Web.Optimization" />
|
||||
<add namespace="Ewide.Core.WebApi" />
|
||||
|
||||
</namespaces>
|
||||
</pages>
|
||||
</system.web.webPages.razor>
|
||||
|
||||
<appSettings>
|
||||
<add key="webpages:Enabled" value="false" />
|
||||
</appSettings>
|
||||
|
||||
<system.webServer>
|
||||
<handlers>
|
||||
<remove name="BlockViewHandler"/>
|
||||
<add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
|
||||
</handlers>
|
||||
</system.webServer>
|
||||
</configuration>
|
||||
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
using System.Web.Http.Description;
|
||||
|
||||
namespace Ewide.Core.WebApi.Areas.HelpPage
|
||||
{
|
||||
public static class ApiDescriptionExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Generates an URI-friendly ID for the <see cref="ApiDescription"/>. E.g. "Get-Values-id_name" instead of "GetValues/{id}?name={name}"
|
||||
/// </summary>
|
||||
/// <param name="description">The <see cref="ApiDescription"/>.</param>
|
||||
/// <returns>The ID as a string.</returns>
|
||||
public static string GetFriendlyId(this ApiDescription description)
|
||||
{
|
||||
string path = description.RelativePath;
|
||||
string[] urlParts = path.Split('?');
|
||||
string localPath = urlParts[0];
|
||||
string queryKeyString = null;
|
||||
if (urlParts.Length > 1)
|
||||
{
|
||||
string query = urlParts[1];
|
||||
string[] queryKeys = HttpUtility.ParseQueryString(query).AllKeys;
|
||||
queryKeyString = String.Join("_", queryKeys);
|
||||
}
|
||||
|
||||
StringBuilder friendlyPath = new StringBuilder();
|
||||
friendlyPath.AppendFormat("{0}-{1}",
|
||||
description.HttpMethod.Method,
|
||||
localPath.Replace("/", "-").Replace("{", String.Empty).Replace("}", String.Empty));
|
||||
if (queryKeyString != null)
|
||||
{
|
||||
friendlyPath.AppendFormat("_{0}", queryKeyString.Replace('.', '-'));
|
||||
}
|
||||
return friendlyPath.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
// Uncomment the following to provide samples for PageResult<T>. Must also add the Microsoft.AspNet.WebApi.OData
|
||||
// package to your project.
|
||||
////#define Handle_PageResultOfT
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Reflection;
|
||||
using System.Web;
|
||||
using System.Web.Http;
|
||||
#if Handle_PageResultOfT
|
||||
using System.Web.Http.OData;
|
||||
#endif
|
||||
|
||||
namespace Ewide.Core.WebApi.Areas.HelpPage
|
||||
{
|
||||
/// <summary>
|
||||
/// Use this class to customize the Help Page.
|
||||
/// For example you can set a custom <see cref="System.Web.Http.Description.IDocumentationProvider"/> to supply the documentation
|
||||
/// or you can provide the samples for the requests/responses.
|
||||
/// </summary>
|
||||
public static class HelpPageConfig
|
||||
{
|
||||
[SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters",
|
||||
MessageId = "Ewide.Core.WebApi.Areas.HelpPage.TextSample.#ctor(System.String)",
|
||||
Justification = "End users may choose to merge this string with existing localized resources.")]
|
||||
[SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly",
|
||||
MessageId = "bsonspec",
|
||||
Justification = "Part of a URI.")]
|
||||
public static void Register(HttpConfiguration config)
|
||||
{
|
||||
//// Uncomment the following to use the documentation from XML documentation file.
|
||||
//config.SetDocumentationProvider(new XmlDocumentationProvider(HttpContext.Current.Server.MapPath("~/App_Data/XmlDocument.xml")));
|
||||
|
||||
//// Uncomment the following to use "sample string" as the sample for all actions that have string as the body parameter or return type.
|
||||
//// Also, the string arrays will be used for IEnumerable<string>. The sample objects will be serialized into different media type
|
||||
//// formats by the available formatters.
|
||||
//config.SetSampleObjects(new Dictionary<Type, object>
|
||||
//{
|
||||
// {typeof(string), "sample string"},
|
||||
// {typeof(IEnumerable<string>), new string[]{"sample 1", "sample 2"}}
|
||||
//});
|
||||
|
||||
// Extend the following to provide factories for types not handled automatically (those lacking parameterless
|
||||
// constructors) or for which you prefer to use non-default property values. Line below provides a fallback
|
||||
// since automatic handling will fail and GeneratePageResult handles only a single type.
|
||||
#if Handle_PageResultOfT
|
||||
config.GetHelpPageSampleGenerator().SampleObjectFactories.Add(GeneratePageResult);
|
||||
#endif
|
||||
|
||||
// Extend the following to use a preset object directly as the sample for all actions that support a media
|
||||
// type, regardless of the body parameter or return type. The lines below avoid display of binary content.
|
||||
// The BsonMediaTypeFormatter (if available) is not used to serialize the TextSample object.
|
||||
config.SetSampleForMediaType(
|
||||
new TextSample("Binary JSON content. See http://bsonspec.org for details."),
|
||||
new MediaTypeHeaderValue("application/bson"));
|
||||
|
||||
//// Uncomment the following to use "[0]=foo&[1]=bar" directly as the sample for all actions that support form URL encoded format
|
||||
//// and have IEnumerable<string> as the body parameter or return type.
|
||||
//config.SetSampleForType("[0]=foo&[1]=bar", new MediaTypeHeaderValue("application/x-www-form-urlencoded"), typeof(IEnumerable<string>));
|
||||
|
||||
//// Uncomment the following to use "1234" directly as the request sample for media type "text/plain" on the controller named "Values"
|
||||
//// and action named "Put".
|
||||
//config.SetSampleRequest("1234", new MediaTypeHeaderValue("text/plain"), "Values", "Put");
|
||||
|
||||
//// Uncomment the following to use the image on "../images/aspNetHome.png" directly as the response sample for media type "image/png"
|
||||
//// on the controller named "Values" and action named "Get" with parameter "id".
|
||||
//config.SetSampleResponse(new ImageSample("../images/aspNetHome.png"), new MediaTypeHeaderValue("image/png"), "Values", "Get", "id");
|
||||
|
||||
//// Uncomment the following to correct the sample request when the action expects an HttpRequestMessage with ObjectContent<string>.
|
||||
//// The sample will be generated as if the controller named "Values" and action named "Get" were having string as the body parameter.
|
||||
//config.SetActualRequestType(typeof(string), "Values", "Get");
|
||||
|
||||
//// Uncomment the following to correct the sample response when the action returns an HttpResponseMessage with ObjectContent<string>.
|
||||
//// The sample will be generated as if the controller named "Values" and action named "Post" were returning a string.
|
||||
//config.SetActualResponseType(typeof(string), "Values", "Post");
|
||||
}
|
||||
|
||||
#if Handle_PageResultOfT
|
||||
private static object GeneratePageResult(HelpPageSampleGenerator sampleGenerator, Type type)
|
||||
{
|
||||
if (type.IsGenericType)
|
||||
{
|
||||
Type openGenericType = type.GetGenericTypeDefinition();
|
||||
if (openGenericType == typeof(PageResult<>))
|
||||
{
|
||||
// Get the T in PageResult<T>
|
||||
Type[] typeParameters = type.GetGenericArguments();
|
||||
Debug.Assert(typeParameters.Length == 1);
|
||||
|
||||
// Create an enumeration to pass as the first parameter to the PageResult<T> constuctor
|
||||
Type itemsType = typeof(List<>).MakeGenericType(typeParameters);
|
||||
object items = sampleGenerator.GetSampleObject(itemsType);
|
||||
|
||||
// Fill in the other information needed to invoke the PageResult<T> constuctor
|
||||
Type[] parameterTypes = new Type[] { itemsType, typeof(Uri), typeof(long?), };
|
||||
object[] parameters = new object[] { items, null, (long)ObjectGenerator.DefaultCollectionSize, };
|
||||
|
||||
// Call PageResult(IEnumerable<T> items, Uri nextPageLink, long? count) constructor
|
||||
ConstructorInfo constructor = type.GetConstructor(parameterTypes);
|
||||
return constructor.Invoke(parameters);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using System.Web.Http;
|
||||
using System.Web.Mvc;
|
||||
using Ewide.Core.WebApi.Areas.HelpPage.ModelDescriptions;
|
||||
using Ewide.Core.WebApi.Areas.HelpPage.Models;
|
||||
|
||||
namespace Ewide.Core.WebApi.Areas.HelpPage.Controllers
|
||||
{
|
||||
/// <summary>
|
||||
/// The controller that will handle requests for the help page.
|
||||
/// </summary>
|
||||
public class HelpController : Controller
|
||||
{
|
||||
private const string ErrorViewName = "Error";
|
||||
|
||||
public HelpController()
|
||||
: this(GlobalConfiguration.Configuration)
|
||||
{
|
||||
}
|
||||
|
||||
public HelpController(HttpConfiguration config)
|
||||
{
|
||||
Configuration = config;
|
||||
}
|
||||
|
||||
public HttpConfiguration Configuration { get; private set; }
|
||||
|
||||
public ActionResult Index()
|
||||
{
|
||||
ViewBag.DocumentationProvider = Configuration.Services.GetDocumentationProvider();
|
||||
return View(Configuration.Services.GetApiExplorer().ApiDescriptions);
|
||||
}
|
||||
|
||||
public ActionResult Api(string apiId)
|
||||
{
|
||||
if (!String.IsNullOrEmpty(apiId))
|
||||
{
|
||||
HelpPageApiModel apiModel = Configuration.GetHelpPageApiModel(apiId);
|
||||
if (apiModel != null)
|
||||
{
|
||||
return View(apiModel);
|
||||
}
|
||||
}
|
||||
|
||||
return View(ErrorViewName);
|
||||
}
|
||||
|
||||
public ActionResult ResourceModel(string modelName)
|
||||
{
|
||||
if (!String.IsNullOrEmpty(modelName))
|
||||
{
|
||||
ModelDescriptionGenerator modelDescriptionGenerator = Configuration.GetModelDescriptionGenerator();
|
||||
ModelDescription modelDescription;
|
||||
if (modelDescriptionGenerator.GeneratedModels.TryGetValue(modelName, out modelDescription))
|
||||
{
|
||||
return View(modelDescription);
|
||||
}
|
||||
}
|
||||
|
||||
return View(ErrorViewName);
|
||||
}
|
||||
}
|
||||
}
|
||||
134
Api/Ewide.Core/Ewide.Core.WebApi/Areas/HelpPage/HelpPage.css
Normal file
134
Api/Ewide.Core/Ewide.Core.WebApi/Areas/HelpPage/HelpPage.css
Normal 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;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using System.Web.Http;
|
||||
using System.Web.Mvc;
|
||||
|
||||
namespace Ewide.Core.WebApi.Areas.HelpPage
|
||||
{
|
||||
public class HelpPageAreaRegistration : AreaRegistration
|
||||
{
|
||||
public override string AreaName
|
||||
{
|
||||
get
|
||||
{
|
||||
return "HelpPage";
|
||||
}
|
||||
}
|
||||
|
||||
public override void RegisterArea(AreaRegistrationContext context)
|
||||
{
|
||||
context.MapRoute(
|
||||
"HelpPage_Default",
|
||||
"Help/{action}/{apiId}",
|
||||
new { controller = "Help", action = "Index", apiId = UrlParameter.Optional });
|
||||
|
||||
HelpPageConfig.Register(GlobalConfiguration.Configuration);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,467 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Web.Http;
|
||||
using System.Web.Http.Controllers;
|
||||
using System.Web.Http.Description;
|
||||
using Ewide.Core.WebApi.Areas.HelpPage.ModelDescriptions;
|
||||
using Ewide.Core.WebApi.Areas.HelpPage.Models;
|
||||
|
||||
namespace Ewide.Core.WebApi.Areas.HelpPage
|
||||
{
|
||||
public static class HelpPageConfigurationExtensions
|
||||
{
|
||||
private const string ApiModelPrefix = "MS_HelpPageApiModel_";
|
||||
|
||||
/// <summary>
|
||||
/// Sets the documentation provider for help page.
|
||||
/// </summary>
|
||||
/// <param name="config">The <see cref="HttpConfiguration"/>.</param>
|
||||
/// <param name="documentationProvider">The documentation provider.</param>
|
||||
public static void SetDocumentationProvider(this HttpConfiguration config, IDocumentationProvider documentationProvider)
|
||||
{
|
||||
config.Services.Replace(typeof(IDocumentationProvider), documentationProvider);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the objects that will be used by the formatters to produce sample requests/responses.
|
||||
/// </summary>
|
||||
/// <param name="config">The <see cref="HttpConfiguration"/>.</param>
|
||||
/// <param name="sampleObjects">The sample objects.</param>
|
||||
public static void SetSampleObjects(this HttpConfiguration config, IDictionary<Type, object> sampleObjects)
|
||||
{
|
||||
config.GetHelpPageSampleGenerator().SampleObjects = sampleObjects;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the sample request directly for the specified media type and action.
|
||||
/// </summary>
|
||||
/// <param name="config">The <see cref="HttpConfiguration"/>.</param>
|
||||
/// <param name="sample">The sample request.</param>
|
||||
/// <param name="mediaType">The media type.</param>
|
||||
/// <param name="controllerName">Name of the controller.</param>
|
||||
/// <param name="actionName">Name of the action.</param>
|
||||
public static void SetSampleRequest(this HttpConfiguration config, object sample, MediaTypeHeaderValue mediaType, string controllerName, string actionName)
|
||||
{
|
||||
config.GetHelpPageSampleGenerator().ActionSamples.Add(new HelpPageSampleKey(mediaType, SampleDirection.Request, controllerName, actionName, new[] { "*" }), sample);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the sample request directly for the specified media type and action with parameters.
|
||||
/// </summary>
|
||||
/// <param name="config">The <see cref="HttpConfiguration"/>.</param>
|
||||
/// <param name="sample">The sample request.</param>
|
||||
/// <param name="mediaType">The media type.</param>
|
||||
/// <param name="controllerName">Name of the controller.</param>
|
||||
/// <param name="actionName">Name of the action.</param>
|
||||
/// <param name="parameterNames">The parameter names.</param>
|
||||
public static void SetSampleRequest(this HttpConfiguration config, object sample, MediaTypeHeaderValue mediaType, string controllerName, string actionName, params string[] parameterNames)
|
||||
{
|
||||
config.GetHelpPageSampleGenerator().ActionSamples.Add(new HelpPageSampleKey(mediaType, SampleDirection.Request, controllerName, actionName, parameterNames), sample);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the sample request directly for the specified media type of the action.
|
||||
/// </summary>
|
||||
/// <param name="config">The <see cref="HttpConfiguration"/>.</param>
|
||||
/// <param name="sample">The sample response.</param>
|
||||
/// <param name="mediaType">The media type.</param>
|
||||
/// <param name="controllerName">Name of the controller.</param>
|
||||
/// <param name="actionName">Name of the action.</param>
|
||||
public static void SetSampleResponse(this HttpConfiguration config, object sample, MediaTypeHeaderValue mediaType, string controllerName, string actionName)
|
||||
{
|
||||
config.GetHelpPageSampleGenerator().ActionSamples.Add(new HelpPageSampleKey(mediaType, SampleDirection.Response, controllerName, actionName, new[] { "*" }), sample);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the sample response directly for the specified media type of the action with specific parameters.
|
||||
/// </summary>
|
||||
/// <param name="config">The <see cref="HttpConfiguration"/>.</param>
|
||||
/// <param name="sample">The sample response.</param>
|
||||
/// <param name="mediaType">The media type.</param>
|
||||
/// <param name="controllerName">Name of the controller.</param>
|
||||
/// <param name="actionName">Name of the action.</param>
|
||||
/// <param name="parameterNames">The parameter names.</param>
|
||||
public static void SetSampleResponse(this HttpConfiguration config, object sample, MediaTypeHeaderValue mediaType, string controllerName, string actionName, params string[] parameterNames)
|
||||
{
|
||||
config.GetHelpPageSampleGenerator().ActionSamples.Add(new HelpPageSampleKey(mediaType, SampleDirection.Response, controllerName, actionName, parameterNames), sample);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the sample directly for all actions with the specified media type.
|
||||
/// </summary>
|
||||
/// <param name="config">The <see cref="HttpConfiguration"/>.</param>
|
||||
/// <param name="sample">The sample.</param>
|
||||
/// <param name="mediaType">The media type.</param>
|
||||
public static void SetSampleForMediaType(this HttpConfiguration config, object sample, MediaTypeHeaderValue mediaType)
|
||||
{
|
||||
config.GetHelpPageSampleGenerator().ActionSamples.Add(new HelpPageSampleKey(mediaType), sample);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the sample directly for all actions with the specified type and media type.
|
||||
/// </summary>
|
||||
/// <param name="config">The <see cref="HttpConfiguration"/>.</param>
|
||||
/// <param name="sample">The sample.</param>
|
||||
/// <param name="mediaType">The media type.</param>
|
||||
/// <param name="type">The parameter type or return type of an action.</param>
|
||||
public static void SetSampleForType(this HttpConfiguration config, object sample, MediaTypeHeaderValue mediaType, Type type)
|
||||
{
|
||||
config.GetHelpPageSampleGenerator().ActionSamples.Add(new HelpPageSampleKey(mediaType, type), sample);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specifies the actual type of <see cref="System.Net.Http.ObjectContent{T}"/> passed to the <see cref="System.Net.Http.HttpRequestMessage"/> in an action.
|
||||
/// The help page will use this information to produce more accurate request samples.
|
||||
/// </summary>
|
||||
/// <param name="config">The <see cref="HttpConfiguration"/>.</param>
|
||||
/// <param name="type">The type.</param>
|
||||
/// <param name="controllerName">Name of the controller.</param>
|
||||
/// <param name="actionName">Name of the action.</param>
|
||||
public static void SetActualRequestType(this HttpConfiguration config, Type type, string controllerName, string actionName)
|
||||
{
|
||||
config.GetHelpPageSampleGenerator().ActualHttpMessageTypes.Add(new HelpPageSampleKey(SampleDirection.Request, controllerName, actionName, new[] { "*" }), type);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specifies the actual type of <see cref="System.Net.Http.ObjectContent{T}"/> passed to the <see cref="System.Net.Http.HttpRequestMessage"/> in an action.
|
||||
/// The help page will use this information to produce more accurate request samples.
|
||||
/// </summary>
|
||||
/// <param name="config">The <see cref="HttpConfiguration"/>.</param>
|
||||
/// <param name="type">The type.</param>
|
||||
/// <param name="controllerName">Name of the controller.</param>
|
||||
/// <param name="actionName">Name of the action.</param>
|
||||
/// <param name="parameterNames">The parameter names.</param>
|
||||
public static void SetActualRequestType(this HttpConfiguration config, Type type, string controllerName, string actionName, params string[] parameterNames)
|
||||
{
|
||||
config.GetHelpPageSampleGenerator().ActualHttpMessageTypes.Add(new HelpPageSampleKey(SampleDirection.Request, controllerName, actionName, parameterNames), type);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specifies the actual type of <see cref="System.Net.Http.ObjectContent{T}"/> returned as part of the <see cref="System.Net.Http.HttpRequestMessage"/> in an action.
|
||||
/// The help page will use this information to produce more accurate response samples.
|
||||
/// </summary>
|
||||
/// <param name="config">The <see cref="HttpConfiguration"/>.</param>
|
||||
/// <param name="type">The type.</param>
|
||||
/// <param name="controllerName">Name of the controller.</param>
|
||||
/// <param name="actionName">Name of the action.</param>
|
||||
public static void SetActualResponseType(this HttpConfiguration config, Type type, string controllerName, string actionName)
|
||||
{
|
||||
config.GetHelpPageSampleGenerator().ActualHttpMessageTypes.Add(new HelpPageSampleKey(SampleDirection.Response, controllerName, actionName, new[] { "*" }), type);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specifies the actual type of <see cref="System.Net.Http.ObjectContent{T}"/> returned as part of the <see cref="System.Net.Http.HttpRequestMessage"/> in an action.
|
||||
/// The help page will use this information to produce more accurate response samples.
|
||||
/// </summary>
|
||||
/// <param name="config">The <see cref="HttpConfiguration"/>.</param>
|
||||
/// <param name="type">The type.</param>
|
||||
/// <param name="controllerName">Name of the controller.</param>
|
||||
/// <param name="actionName">Name of the action.</param>
|
||||
/// <param name="parameterNames">The parameter names.</param>
|
||||
public static void SetActualResponseType(this HttpConfiguration config, Type type, string controllerName, string actionName, params string[] parameterNames)
|
||||
{
|
||||
config.GetHelpPageSampleGenerator().ActualHttpMessageTypes.Add(new HelpPageSampleKey(SampleDirection.Response, controllerName, actionName, parameterNames), type);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the help page sample generator.
|
||||
/// </summary>
|
||||
/// <param name="config">The <see cref="HttpConfiguration"/>.</param>
|
||||
/// <returns>The help page sample generator.</returns>
|
||||
public static HelpPageSampleGenerator GetHelpPageSampleGenerator(this HttpConfiguration config)
|
||||
{
|
||||
return (HelpPageSampleGenerator)config.Properties.GetOrAdd(
|
||||
typeof(HelpPageSampleGenerator),
|
||||
k => new HelpPageSampleGenerator());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the help page sample generator.
|
||||
/// </summary>
|
||||
/// <param name="config">The <see cref="HttpConfiguration"/>.</param>
|
||||
/// <param name="sampleGenerator">The help page sample generator.</param>
|
||||
public static void SetHelpPageSampleGenerator(this HttpConfiguration config, HelpPageSampleGenerator sampleGenerator)
|
||||
{
|
||||
config.Properties.AddOrUpdate(
|
||||
typeof(HelpPageSampleGenerator),
|
||||
k => sampleGenerator,
|
||||
(k, o) => sampleGenerator);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the model description generator.
|
||||
/// </summary>
|
||||
/// <param name="config">The configuration.</param>
|
||||
/// <returns>The <see cref="ModelDescriptionGenerator"/></returns>
|
||||
public static ModelDescriptionGenerator GetModelDescriptionGenerator(this HttpConfiguration config)
|
||||
{
|
||||
return (ModelDescriptionGenerator)config.Properties.GetOrAdd(
|
||||
typeof(ModelDescriptionGenerator),
|
||||
k => InitializeModelDescriptionGenerator(config));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the model that represents an API displayed on the help page. The model is initialized on the first call and cached for subsequent calls.
|
||||
/// </summary>
|
||||
/// <param name="config">The <see cref="HttpConfiguration"/>.</param>
|
||||
/// <param name="apiDescriptionId">The <see cref="ApiDescription"/> ID.</param>
|
||||
/// <returns>
|
||||
/// An <see cref="HelpPageApiModel"/>
|
||||
/// </returns>
|
||||
public static HelpPageApiModel GetHelpPageApiModel(this HttpConfiguration config, string apiDescriptionId)
|
||||
{
|
||||
object model;
|
||||
string modelId = ApiModelPrefix + apiDescriptionId;
|
||||
if (!config.Properties.TryGetValue(modelId, out model))
|
||||
{
|
||||
Collection<ApiDescription> apiDescriptions = config.Services.GetApiExplorer().ApiDescriptions;
|
||||
ApiDescription apiDescription = apiDescriptions.FirstOrDefault(api => String.Equals(api.GetFriendlyId(), apiDescriptionId, StringComparison.OrdinalIgnoreCase));
|
||||
if (apiDescription != null)
|
||||
{
|
||||
model = GenerateApiModel(apiDescription, config);
|
||||
config.Properties.TryAdd(modelId, model);
|
||||
}
|
||||
}
|
||||
|
||||
return (HelpPageApiModel)model;
|
||||
}
|
||||
|
||||
private static HelpPageApiModel GenerateApiModel(ApiDescription apiDescription, HttpConfiguration config)
|
||||
{
|
||||
HelpPageApiModel apiModel = new HelpPageApiModel()
|
||||
{
|
||||
ApiDescription = apiDescription,
|
||||
};
|
||||
|
||||
ModelDescriptionGenerator modelGenerator = config.GetModelDescriptionGenerator();
|
||||
HelpPageSampleGenerator sampleGenerator = config.GetHelpPageSampleGenerator();
|
||||
GenerateUriParameters(apiModel, modelGenerator);
|
||||
GenerateRequestModelDescription(apiModel, modelGenerator, sampleGenerator);
|
||||
GenerateResourceDescription(apiModel, modelGenerator);
|
||||
GenerateSamples(apiModel, sampleGenerator);
|
||||
|
||||
return apiModel;
|
||||
}
|
||||
|
||||
private static void GenerateUriParameters(HelpPageApiModel apiModel, ModelDescriptionGenerator modelGenerator)
|
||||
{
|
||||
ApiDescription apiDescription = apiModel.ApiDescription;
|
||||
foreach (ApiParameterDescription apiParameter in apiDescription.ParameterDescriptions)
|
||||
{
|
||||
if (apiParameter.Source == ApiParameterSource.FromUri)
|
||||
{
|
||||
HttpParameterDescriptor parameterDescriptor = apiParameter.ParameterDescriptor;
|
||||
Type parameterType = null;
|
||||
ModelDescription typeDescription = null;
|
||||
ComplexTypeModelDescription complexTypeDescription = null;
|
||||
if (parameterDescriptor != null)
|
||||
{
|
||||
parameterType = parameterDescriptor.ParameterType;
|
||||
typeDescription = modelGenerator.GetOrCreateModelDescription(parameterType);
|
||||
complexTypeDescription = typeDescription as ComplexTypeModelDescription;
|
||||
}
|
||||
|
||||
// Example:
|
||||
// [TypeConverter(typeof(PointConverter))]
|
||||
// public class Point
|
||||
// {
|
||||
// public Point(int x, int y)
|
||||
// {
|
||||
// X = x;
|
||||
// Y = y;
|
||||
// }
|
||||
// public int X { get; set; }
|
||||
// public int Y { get; set; }
|
||||
// }
|
||||
// Class Point is bindable with a TypeConverter, so Point will be added to UriParameters collection.
|
||||
//
|
||||
// public class Point
|
||||
// {
|
||||
// public int X { get; set; }
|
||||
// public int Y { get; set; }
|
||||
// }
|
||||
// Regular complex class Point will have properties X and Y added to UriParameters collection.
|
||||
if (complexTypeDescription != null
|
||||
&& !IsBindableWithTypeConverter(parameterType))
|
||||
{
|
||||
foreach (ParameterDescription uriParameter in complexTypeDescription.Properties)
|
||||
{
|
||||
apiModel.UriParameters.Add(uriParameter);
|
||||
}
|
||||
}
|
||||
else if (parameterDescriptor != null)
|
||||
{
|
||||
ParameterDescription uriParameter =
|
||||
AddParameterDescription(apiModel, apiParameter, typeDescription);
|
||||
|
||||
if (!parameterDescriptor.IsOptional)
|
||||
{
|
||||
uriParameter.Annotations.Add(new ParameterAnnotation() { Documentation = "Required" });
|
||||
}
|
||||
|
||||
object defaultValue = parameterDescriptor.DefaultValue;
|
||||
if (defaultValue != null)
|
||||
{
|
||||
uriParameter.Annotations.Add(new ParameterAnnotation() { Documentation = "Default value is " + Convert.ToString(defaultValue, CultureInfo.InvariantCulture) });
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Assert(parameterDescriptor == null);
|
||||
|
||||
// If parameterDescriptor is null, this is an undeclared route parameter which only occurs
|
||||
// when source is FromUri. Ignored in request model and among resource parameters but listed
|
||||
// as a simple string here.
|
||||
ModelDescription modelDescription = modelGenerator.GetOrCreateModelDescription(typeof(string));
|
||||
AddParameterDescription(apiModel, apiParameter, modelDescription);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsBindableWithTypeConverter(Type parameterType)
|
||||
{
|
||||
if (parameterType == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return TypeDescriptor.GetConverter(parameterType).CanConvertFrom(typeof(string));
|
||||
}
|
||||
|
||||
private static ParameterDescription AddParameterDescription(HelpPageApiModel apiModel,
|
||||
ApiParameterDescription apiParameter, ModelDescription typeDescription)
|
||||
{
|
||||
ParameterDescription parameterDescription = new ParameterDescription
|
||||
{
|
||||
Name = apiParameter.Name,
|
||||
Documentation = apiParameter.Documentation,
|
||||
TypeDescription = typeDescription,
|
||||
};
|
||||
|
||||
apiModel.UriParameters.Add(parameterDescription);
|
||||
return parameterDescription;
|
||||
}
|
||||
|
||||
private static void GenerateRequestModelDescription(HelpPageApiModel apiModel, ModelDescriptionGenerator modelGenerator, HelpPageSampleGenerator sampleGenerator)
|
||||
{
|
||||
ApiDescription apiDescription = apiModel.ApiDescription;
|
||||
foreach (ApiParameterDescription apiParameter in apiDescription.ParameterDescriptions)
|
||||
{
|
||||
if (apiParameter.Source == ApiParameterSource.FromBody)
|
||||
{
|
||||
Type parameterType = apiParameter.ParameterDescriptor.ParameterType;
|
||||
apiModel.RequestModelDescription = modelGenerator.GetOrCreateModelDescription(parameterType);
|
||||
apiModel.RequestDocumentation = apiParameter.Documentation;
|
||||
}
|
||||
else if (apiParameter.ParameterDescriptor != null &&
|
||||
apiParameter.ParameterDescriptor.ParameterType == typeof(HttpRequestMessage))
|
||||
{
|
||||
Type parameterType = sampleGenerator.ResolveHttpRequestMessageType(apiDescription);
|
||||
|
||||
if (parameterType != null)
|
||||
{
|
||||
apiModel.RequestModelDescription = modelGenerator.GetOrCreateModelDescription(parameterType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void GenerateResourceDescription(HelpPageApiModel apiModel, ModelDescriptionGenerator modelGenerator)
|
||||
{
|
||||
ResponseDescription response = apiModel.ApiDescription.ResponseDescription;
|
||||
Type responseType = response.ResponseType ?? response.DeclaredType;
|
||||
if (responseType != null && responseType != typeof(void))
|
||||
{
|
||||
apiModel.ResourceDescription = modelGenerator.GetOrCreateModelDescription(responseType);
|
||||
}
|
||||
}
|
||||
|
||||
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "The exception is recorded as ErrorMessages.")]
|
||||
private static void GenerateSamples(HelpPageApiModel apiModel, HelpPageSampleGenerator sampleGenerator)
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (var item in sampleGenerator.GetSampleRequests(apiModel.ApiDescription))
|
||||
{
|
||||
apiModel.SampleRequests.Add(item.Key, item.Value);
|
||||
LogInvalidSampleAsError(apiModel, item.Value);
|
||||
}
|
||||
|
||||
foreach (var item in sampleGenerator.GetSampleResponses(apiModel.ApiDescription))
|
||||
{
|
||||
apiModel.SampleResponses.Add(item.Key, item.Value);
|
||||
LogInvalidSampleAsError(apiModel, item.Value);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
apiModel.ErrorMessages.Add(String.Format(CultureInfo.CurrentCulture,
|
||||
"An exception has occurred while generating the sample. Exception message: {0}",
|
||||
HelpPageSampleGenerator.UnwrapException(e).Message));
|
||||
}
|
||||
}
|
||||
|
||||
private static bool TryGetResourceParameter(ApiDescription apiDescription, HttpConfiguration config, out ApiParameterDescription parameterDescription, out Type resourceType)
|
||||
{
|
||||
parameterDescription = apiDescription.ParameterDescriptions.FirstOrDefault(
|
||||
p => p.Source == ApiParameterSource.FromBody ||
|
||||
(p.ParameterDescriptor != null && p.ParameterDescriptor.ParameterType == typeof(HttpRequestMessage)));
|
||||
|
||||
if (parameterDescription == null)
|
||||
{
|
||||
resourceType = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
resourceType = parameterDescription.ParameterDescriptor.ParameterType;
|
||||
|
||||
if (resourceType == typeof(HttpRequestMessage))
|
||||
{
|
||||
HelpPageSampleGenerator sampleGenerator = config.GetHelpPageSampleGenerator();
|
||||
resourceType = sampleGenerator.ResolveHttpRequestMessageType(apiDescription);
|
||||
}
|
||||
|
||||
if (resourceType == null)
|
||||
{
|
||||
parameterDescription = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static ModelDescriptionGenerator InitializeModelDescriptionGenerator(HttpConfiguration config)
|
||||
{
|
||||
ModelDescriptionGenerator modelGenerator = new ModelDescriptionGenerator(config);
|
||||
Collection<ApiDescription> apis = config.Services.GetApiExplorer().ApiDescriptions;
|
||||
foreach (ApiDescription api in apis)
|
||||
{
|
||||
ApiParameterDescription parameterDescription;
|
||||
Type parameterType;
|
||||
if (TryGetResourceParameter(api, config, out parameterDescription, out parameterType))
|
||||
{
|
||||
modelGenerator.GetOrCreateModelDescription(parameterType);
|
||||
}
|
||||
}
|
||||
return modelGenerator;
|
||||
}
|
||||
|
||||
private static void LogInvalidSampleAsError(HelpPageApiModel apiModel, object sample)
|
||||
{
|
||||
InvalidSample invalidSample = sample as InvalidSample;
|
||||
if (invalidSample != null)
|
||||
{
|
||||
apiModel.ErrorMessages.Add(invalidSample.ErrorMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace Ewide.Core.WebApi.Areas.HelpPage.ModelDescriptions
|
||||
{
|
||||
public class CollectionModelDescription : ModelDescription
|
||||
{
|
||||
public ModelDescription ElementDescription { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace Ewide.Core.WebApi.Areas.HelpPage.ModelDescriptions
|
||||
{
|
||||
public class ComplexTypeModelDescription : ModelDescription
|
||||
{
|
||||
public ComplexTypeModelDescription()
|
||||
{
|
||||
Properties = new Collection<ParameterDescription>();
|
||||
}
|
||||
|
||||
public Collection<ParameterDescription> Properties { get; private set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace Ewide.Core.WebApi.Areas.HelpPage.ModelDescriptions
|
||||
{
|
||||
public class DictionaryModelDescription : KeyValuePairModelDescription
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace Ewide.Core.WebApi.Areas.HelpPage.ModelDescriptions
|
||||
{
|
||||
public class EnumTypeModelDescription : ModelDescription
|
||||
{
|
||||
public EnumTypeModelDescription()
|
||||
{
|
||||
Values = new Collection<EnumValueDescription>();
|
||||
}
|
||||
|
||||
public Collection<EnumValueDescription> Values { get; private set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
namespace Ewide.Core.WebApi.Areas.HelpPage.ModelDescriptions
|
||||
{
|
||||
public class EnumValueDescription
|
||||
{
|
||||
public string Documentation { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public string Value { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Ewide.Core.WebApi.Areas.HelpPage.ModelDescriptions
|
||||
{
|
||||
public interface IModelDocumentationProvider
|
||||
{
|
||||
string GetDocumentation(MemberInfo member);
|
||||
|
||||
string GetDocumentation(Type type);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace Ewide.Core.WebApi.Areas.HelpPage.ModelDescriptions
|
||||
{
|
||||
public class KeyValuePairModelDescription : ModelDescription
|
||||
{
|
||||
public ModelDescription KeyModelDescription { get; set; }
|
||||
|
||||
public ModelDescription ValueModelDescription { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
|
||||
namespace Ewide.Core.WebApi.Areas.HelpPage.ModelDescriptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes a type model.
|
||||
/// </summary>
|
||||
public abstract class ModelDescription
|
||||
{
|
||||
public string Documentation { get; set; }
|
||||
|
||||
public Type ModelType { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,451 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Web.Http;
|
||||
using System.Web.Http.Description;
|
||||
using System.Xml.Serialization;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Ewide.Core.WebApi.Areas.HelpPage.ModelDescriptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Generates model descriptions for given types.
|
||||
/// </summary>
|
||||
public class ModelDescriptionGenerator
|
||||
{
|
||||
// Modify this to support more data annotation attributes.
|
||||
private readonly IDictionary<Type, Func<object, string>> AnnotationTextGenerator = new Dictionary<Type, Func<object, string>>
|
||||
{
|
||||
{ typeof(RequiredAttribute), a => "Required" },
|
||||
{ typeof(RangeAttribute), a =>
|
||||
{
|
||||
RangeAttribute range = (RangeAttribute)a;
|
||||
return String.Format(CultureInfo.CurrentCulture, "Range: inclusive between {0} and {1}", range.Minimum, range.Maximum);
|
||||
}
|
||||
},
|
||||
{ typeof(MaxLengthAttribute), a =>
|
||||
{
|
||||
MaxLengthAttribute maxLength = (MaxLengthAttribute)a;
|
||||
return String.Format(CultureInfo.CurrentCulture, "Max length: {0}", maxLength.Length);
|
||||
}
|
||||
},
|
||||
{ typeof(MinLengthAttribute), a =>
|
||||
{
|
||||
MinLengthAttribute minLength = (MinLengthAttribute)a;
|
||||
return String.Format(CultureInfo.CurrentCulture, "Min length: {0}", minLength.Length);
|
||||
}
|
||||
},
|
||||
{ typeof(StringLengthAttribute), a =>
|
||||
{
|
||||
StringLengthAttribute strLength = (StringLengthAttribute)a;
|
||||
return String.Format(CultureInfo.CurrentCulture, "String length: inclusive between {0} and {1}", strLength.MinimumLength, strLength.MaximumLength);
|
||||
}
|
||||
},
|
||||
{ typeof(DataTypeAttribute), a =>
|
||||
{
|
||||
DataTypeAttribute dataType = (DataTypeAttribute)a;
|
||||
return String.Format(CultureInfo.CurrentCulture, "Data type: {0}", dataType.CustomDataType ?? dataType.DataType.ToString());
|
||||
}
|
||||
},
|
||||
{ typeof(RegularExpressionAttribute), a =>
|
||||
{
|
||||
RegularExpressionAttribute regularExpression = (RegularExpressionAttribute)a;
|
||||
return String.Format(CultureInfo.CurrentCulture, "Matching regular expression pattern: {0}", regularExpression.Pattern);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
// Modify this to add more default documentations.
|
||||
private readonly IDictionary<Type, string> DefaultTypeDocumentation = new Dictionary<Type, string>
|
||||
{
|
||||
{ typeof(Int16), "integer" },
|
||||
{ typeof(Int32), "integer" },
|
||||
{ typeof(Int64), "integer" },
|
||||
{ typeof(UInt16), "unsigned integer" },
|
||||
{ typeof(UInt32), "unsigned integer" },
|
||||
{ typeof(UInt64), "unsigned integer" },
|
||||
{ typeof(Byte), "byte" },
|
||||
{ typeof(Char), "character" },
|
||||
{ typeof(SByte), "signed byte" },
|
||||
{ typeof(Uri), "URI" },
|
||||
{ typeof(Single), "decimal number" },
|
||||
{ typeof(Double), "decimal number" },
|
||||
{ typeof(Decimal), "decimal number" },
|
||||
{ typeof(String), "string" },
|
||||
{ typeof(Guid), "globally unique identifier" },
|
||||
{ typeof(TimeSpan), "time interval" },
|
||||
{ typeof(DateTime), "date" },
|
||||
{ typeof(DateTimeOffset), "date" },
|
||||
{ typeof(Boolean), "boolean" },
|
||||
};
|
||||
|
||||
private Lazy<IModelDocumentationProvider> _documentationProvider;
|
||||
|
||||
public ModelDescriptionGenerator(HttpConfiguration config)
|
||||
{
|
||||
if (config == null)
|
||||
{
|
||||
throw new ArgumentNullException("config");
|
||||
}
|
||||
|
||||
_documentationProvider = new Lazy<IModelDocumentationProvider>(() => config.Services.GetDocumentationProvider() as IModelDocumentationProvider);
|
||||
GeneratedModels = new Dictionary<string, ModelDescription>(StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
public Dictionary<string, ModelDescription> GeneratedModels { get; private set; }
|
||||
|
||||
private IModelDocumentationProvider DocumentationProvider
|
||||
{
|
||||
get
|
||||
{
|
||||
return _documentationProvider.Value;
|
||||
}
|
||||
}
|
||||
|
||||
public ModelDescription GetOrCreateModelDescription(Type modelType)
|
||||
{
|
||||
if (modelType == null)
|
||||
{
|
||||
throw new ArgumentNullException("modelType");
|
||||
}
|
||||
|
||||
Type underlyingType = Nullable.GetUnderlyingType(modelType);
|
||||
if (underlyingType != null)
|
||||
{
|
||||
modelType = underlyingType;
|
||||
}
|
||||
|
||||
ModelDescription modelDescription;
|
||||
string modelName = ModelNameHelper.GetModelName(modelType);
|
||||
if (GeneratedModels.TryGetValue(modelName, out modelDescription))
|
||||
{
|
||||
if (modelType != modelDescription.ModelType)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
String.Format(
|
||||
CultureInfo.CurrentCulture,
|
||||
"A model description could not be created. Duplicate model name '{0}' was found for types '{1}' and '{2}'. " +
|
||||
"Use the [ModelName] attribute to change the model name for at least one of the types so that it has a unique name.",
|
||||
modelName,
|
||||
modelDescription.ModelType.FullName,
|
||||
modelType.FullName));
|
||||
}
|
||||
|
||||
return modelDescription;
|
||||
}
|
||||
|
||||
if (DefaultTypeDocumentation.ContainsKey(modelType))
|
||||
{
|
||||
return GenerateSimpleTypeModelDescription(modelType);
|
||||
}
|
||||
|
||||
if (modelType.IsEnum)
|
||||
{
|
||||
return GenerateEnumTypeModelDescription(modelType);
|
||||
}
|
||||
|
||||
if (modelType.IsGenericType)
|
||||
{
|
||||
Type[] genericArguments = modelType.GetGenericArguments();
|
||||
|
||||
if (genericArguments.Length == 1)
|
||||
{
|
||||
Type enumerableType = typeof(IEnumerable<>).MakeGenericType(genericArguments);
|
||||
if (enumerableType.IsAssignableFrom(modelType))
|
||||
{
|
||||
return GenerateCollectionModelDescription(modelType, genericArguments[0]);
|
||||
}
|
||||
}
|
||||
if (genericArguments.Length == 2)
|
||||
{
|
||||
Type dictionaryType = typeof(IDictionary<,>).MakeGenericType(genericArguments);
|
||||
if (dictionaryType.IsAssignableFrom(modelType))
|
||||
{
|
||||
return GenerateDictionaryModelDescription(modelType, genericArguments[0], genericArguments[1]);
|
||||
}
|
||||
|
||||
Type keyValuePairType = typeof(KeyValuePair<,>).MakeGenericType(genericArguments);
|
||||
if (keyValuePairType.IsAssignableFrom(modelType))
|
||||
{
|
||||
return GenerateKeyValuePairModelDescription(modelType, genericArguments[0], genericArguments[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (modelType.IsArray)
|
||||
{
|
||||
Type elementType = modelType.GetElementType();
|
||||
return GenerateCollectionModelDescription(modelType, elementType);
|
||||
}
|
||||
|
||||
if (modelType == typeof(NameValueCollection))
|
||||
{
|
||||
return GenerateDictionaryModelDescription(modelType, typeof(string), typeof(string));
|
||||
}
|
||||
|
||||
if (typeof(IDictionary).IsAssignableFrom(modelType))
|
||||
{
|
||||
return GenerateDictionaryModelDescription(modelType, typeof(object), typeof(object));
|
||||
}
|
||||
|
||||
if (typeof(IEnumerable).IsAssignableFrom(modelType))
|
||||
{
|
||||
return GenerateCollectionModelDescription(modelType, typeof(object));
|
||||
}
|
||||
|
||||
return GenerateComplexTypeModelDescription(modelType);
|
||||
}
|
||||
|
||||
// Change this to provide different name for the member.
|
||||
private static string GetMemberName(MemberInfo member, bool hasDataContractAttribute)
|
||||
{
|
||||
JsonPropertyAttribute jsonProperty = member.GetCustomAttribute<JsonPropertyAttribute>();
|
||||
if (jsonProperty != null && !String.IsNullOrEmpty(jsonProperty.PropertyName))
|
||||
{
|
||||
return jsonProperty.PropertyName;
|
||||
}
|
||||
|
||||
if (hasDataContractAttribute)
|
||||
{
|
||||
DataMemberAttribute dataMember = member.GetCustomAttribute<DataMemberAttribute>();
|
||||
if (dataMember != null && !String.IsNullOrEmpty(dataMember.Name))
|
||||
{
|
||||
return dataMember.Name;
|
||||
}
|
||||
}
|
||||
|
||||
return member.Name;
|
||||
}
|
||||
|
||||
private static bool ShouldDisplayMember(MemberInfo member, bool hasDataContractAttribute)
|
||||
{
|
||||
JsonIgnoreAttribute jsonIgnore = member.GetCustomAttribute<JsonIgnoreAttribute>();
|
||||
XmlIgnoreAttribute xmlIgnore = member.GetCustomAttribute<XmlIgnoreAttribute>();
|
||||
IgnoreDataMemberAttribute ignoreDataMember = member.GetCustomAttribute<IgnoreDataMemberAttribute>();
|
||||
NonSerializedAttribute nonSerialized = member.GetCustomAttribute<NonSerializedAttribute>();
|
||||
ApiExplorerSettingsAttribute apiExplorerSetting = member.GetCustomAttribute<ApiExplorerSettingsAttribute>();
|
||||
|
||||
bool hasMemberAttribute = member.DeclaringType.IsEnum ?
|
||||
member.GetCustomAttribute<EnumMemberAttribute>() != null :
|
||||
member.GetCustomAttribute<DataMemberAttribute>() != null;
|
||||
|
||||
// Display member only if all the followings are true:
|
||||
// no JsonIgnoreAttribute
|
||||
// no XmlIgnoreAttribute
|
||||
// no IgnoreDataMemberAttribute
|
||||
// no NonSerializedAttribute
|
||||
// no ApiExplorerSettingsAttribute with IgnoreApi set to true
|
||||
// no DataContractAttribute without DataMemberAttribute or EnumMemberAttribute
|
||||
return jsonIgnore == null &&
|
||||
xmlIgnore == null &&
|
||||
ignoreDataMember == null &&
|
||||
nonSerialized == null &&
|
||||
(apiExplorerSetting == null || !apiExplorerSetting.IgnoreApi) &&
|
||||
(!hasDataContractAttribute || hasMemberAttribute);
|
||||
}
|
||||
|
||||
private string CreateDefaultDocumentation(Type type)
|
||||
{
|
||||
string documentation;
|
||||
if (DefaultTypeDocumentation.TryGetValue(type, out documentation))
|
||||
{
|
||||
return documentation;
|
||||
}
|
||||
if (DocumentationProvider != null)
|
||||
{
|
||||
documentation = DocumentationProvider.GetDocumentation(type);
|
||||
}
|
||||
|
||||
return documentation;
|
||||
}
|
||||
|
||||
private void GenerateAnnotations(MemberInfo property, ParameterDescription propertyModel)
|
||||
{
|
||||
List<ParameterAnnotation> annotations = new List<ParameterAnnotation>();
|
||||
|
||||
IEnumerable<Attribute> attributes = property.GetCustomAttributes();
|
||||
foreach (Attribute attribute in attributes)
|
||||
{
|
||||
Func<object, string> textGenerator;
|
||||
if (AnnotationTextGenerator.TryGetValue(attribute.GetType(), out textGenerator))
|
||||
{
|
||||
annotations.Add(
|
||||
new ParameterAnnotation
|
||||
{
|
||||
AnnotationAttribute = attribute,
|
||||
Documentation = textGenerator(attribute)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Rearrange the annotations
|
||||
annotations.Sort((x, y) =>
|
||||
{
|
||||
// Special-case RequiredAttribute so that it shows up on top
|
||||
if (x.AnnotationAttribute is RequiredAttribute)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if (y.AnnotationAttribute is RequiredAttribute)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Sort the rest based on alphabetic order of the documentation
|
||||
return String.Compare(x.Documentation, y.Documentation, StringComparison.OrdinalIgnoreCase);
|
||||
});
|
||||
|
||||
foreach (ParameterAnnotation annotation in annotations)
|
||||
{
|
||||
propertyModel.Annotations.Add(annotation);
|
||||
}
|
||||
}
|
||||
|
||||
private CollectionModelDescription GenerateCollectionModelDescription(Type modelType, Type elementType)
|
||||
{
|
||||
ModelDescription collectionModelDescription = GetOrCreateModelDescription(elementType);
|
||||
if (collectionModelDescription != null)
|
||||
{
|
||||
return new CollectionModelDescription
|
||||
{
|
||||
Name = ModelNameHelper.GetModelName(modelType),
|
||||
ModelType = modelType,
|
||||
ElementDescription = collectionModelDescription
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private ModelDescription GenerateComplexTypeModelDescription(Type modelType)
|
||||
{
|
||||
ComplexTypeModelDescription complexModelDescription = new ComplexTypeModelDescription
|
||||
{
|
||||
Name = ModelNameHelper.GetModelName(modelType),
|
||||
ModelType = modelType,
|
||||
Documentation = CreateDefaultDocumentation(modelType)
|
||||
};
|
||||
|
||||
GeneratedModels.Add(complexModelDescription.Name, complexModelDescription);
|
||||
bool hasDataContractAttribute = modelType.GetCustomAttribute<DataContractAttribute>() != null;
|
||||
PropertyInfo[] properties = modelType.GetProperties(BindingFlags.Public | BindingFlags.Instance);
|
||||
foreach (PropertyInfo property in properties)
|
||||
{
|
||||
if (ShouldDisplayMember(property, hasDataContractAttribute))
|
||||
{
|
||||
ParameterDescription propertyModel = new ParameterDescription
|
||||
{
|
||||
Name = GetMemberName(property, hasDataContractAttribute)
|
||||
};
|
||||
|
||||
if (DocumentationProvider != null)
|
||||
{
|
||||
propertyModel.Documentation = DocumentationProvider.GetDocumentation(property);
|
||||
}
|
||||
|
||||
GenerateAnnotations(property, propertyModel);
|
||||
complexModelDescription.Properties.Add(propertyModel);
|
||||
propertyModel.TypeDescription = GetOrCreateModelDescription(property.PropertyType);
|
||||
}
|
||||
}
|
||||
|
||||
FieldInfo[] fields = modelType.GetFields(BindingFlags.Public | BindingFlags.Instance);
|
||||
foreach (FieldInfo field in fields)
|
||||
{
|
||||
if (ShouldDisplayMember(field, hasDataContractAttribute))
|
||||
{
|
||||
ParameterDescription propertyModel = new ParameterDescription
|
||||
{
|
||||
Name = GetMemberName(field, hasDataContractAttribute)
|
||||
};
|
||||
|
||||
if (DocumentationProvider != null)
|
||||
{
|
||||
propertyModel.Documentation = DocumentationProvider.GetDocumentation(field);
|
||||
}
|
||||
|
||||
complexModelDescription.Properties.Add(propertyModel);
|
||||
propertyModel.TypeDescription = GetOrCreateModelDescription(field.FieldType);
|
||||
}
|
||||
}
|
||||
|
||||
return complexModelDescription;
|
||||
}
|
||||
|
||||
private DictionaryModelDescription GenerateDictionaryModelDescription(Type modelType, Type keyType, Type valueType)
|
||||
{
|
||||
ModelDescription keyModelDescription = GetOrCreateModelDescription(keyType);
|
||||
ModelDescription valueModelDescription = GetOrCreateModelDescription(valueType);
|
||||
|
||||
return new DictionaryModelDescription
|
||||
{
|
||||
Name = ModelNameHelper.GetModelName(modelType),
|
||||
ModelType = modelType,
|
||||
KeyModelDescription = keyModelDescription,
|
||||
ValueModelDescription = valueModelDescription
|
||||
};
|
||||
}
|
||||
|
||||
private EnumTypeModelDescription GenerateEnumTypeModelDescription(Type modelType)
|
||||
{
|
||||
EnumTypeModelDescription enumDescription = new EnumTypeModelDescription
|
||||
{
|
||||
Name = ModelNameHelper.GetModelName(modelType),
|
||||
ModelType = modelType,
|
||||
Documentation = CreateDefaultDocumentation(modelType)
|
||||
};
|
||||
bool hasDataContractAttribute = modelType.GetCustomAttribute<DataContractAttribute>() != null;
|
||||
foreach (FieldInfo field in modelType.GetFields(BindingFlags.Public | BindingFlags.Static))
|
||||
{
|
||||
if (ShouldDisplayMember(field, hasDataContractAttribute))
|
||||
{
|
||||
EnumValueDescription enumValue = new EnumValueDescription
|
||||
{
|
||||
Name = field.Name,
|
||||
Value = field.GetRawConstantValue().ToString()
|
||||
};
|
||||
if (DocumentationProvider != null)
|
||||
{
|
||||
enumValue.Documentation = DocumentationProvider.GetDocumentation(field);
|
||||
}
|
||||
enumDescription.Values.Add(enumValue);
|
||||
}
|
||||
}
|
||||
GeneratedModels.Add(enumDescription.Name, enumDescription);
|
||||
|
||||
return enumDescription;
|
||||
}
|
||||
|
||||
private KeyValuePairModelDescription GenerateKeyValuePairModelDescription(Type modelType, Type keyType, Type valueType)
|
||||
{
|
||||
ModelDescription keyModelDescription = GetOrCreateModelDescription(keyType);
|
||||
ModelDescription valueModelDescription = GetOrCreateModelDescription(valueType);
|
||||
|
||||
return new KeyValuePairModelDescription
|
||||
{
|
||||
Name = ModelNameHelper.GetModelName(modelType),
|
||||
ModelType = modelType,
|
||||
KeyModelDescription = keyModelDescription,
|
||||
ValueModelDescription = valueModelDescription
|
||||
};
|
||||
}
|
||||
|
||||
private ModelDescription GenerateSimpleTypeModelDescription(Type modelType)
|
||||
{
|
||||
SimpleTypeModelDescription simpleModelDescription = new SimpleTypeModelDescription
|
||||
{
|
||||
Name = ModelNameHelper.GetModelName(modelType),
|
||||
ModelType = modelType,
|
||||
Documentation = CreateDefaultDocumentation(modelType)
|
||||
};
|
||||
GeneratedModels.Add(simpleModelDescription.Name, simpleModelDescription);
|
||||
|
||||
return simpleModelDescription;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
|
||||
namespace Ewide.Core.WebApi.Areas.HelpPage.ModelDescriptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Use this attribute to change the name of the <see cref="ModelDescription"/> generated for a type.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum, AllowMultiple = false, Inherited = false)]
|
||||
public sealed class ModelNameAttribute : Attribute
|
||||
{
|
||||
public ModelNameAttribute(string name)
|
||||
{
|
||||
Name = name;
|
||||
}
|
||||
|
||||
public string Name { get; private set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Ewide.Core.WebApi.Areas.HelpPage.ModelDescriptions
|
||||
{
|
||||
internal static class ModelNameHelper
|
||||
{
|
||||
// Modify this to provide custom model name mapping.
|
||||
public static string GetModelName(Type type)
|
||||
{
|
||||
ModelNameAttribute modelNameAttribute = type.GetCustomAttribute<ModelNameAttribute>();
|
||||
if (modelNameAttribute != null && !String.IsNullOrEmpty(modelNameAttribute.Name))
|
||||
{
|
||||
return modelNameAttribute.Name;
|
||||
}
|
||||
|
||||
string modelName = type.Name;
|
||||
if (type.IsGenericType)
|
||||
{
|
||||
// Format the generic type name to something like: GenericOfAgurment1AndArgument2
|
||||
Type genericType = type.GetGenericTypeDefinition();
|
||||
Type[] genericArguments = type.GetGenericArguments();
|
||||
string genericTypeName = genericType.Name;
|
||||
|
||||
// Trim the generic parameter counts from the name
|
||||
genericTypeName = genericTypeName.Substring(0, genericTypeName.IndexOf('`'));
|
||||
string[] argumentTypeNames = genericArguments.Select(t => GetModelName(t)).ToArray();
|
||||
modelName = String.Format(CultureInfo.InvariantCulture, "{0}Of{1}", genericTypeName, String.Join("And", argumentTypeNames));
|
||||
}
|
||||
|
||||
return modelName;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
using System;
|
||||
|
||||
namespace Ewide.Core.WebApi.Areas.HelpPage.ModelDescriptions
|
||||
{
|
||||
public class ParameterAnnotation
|
||||
{
|
||||
public Attribute AnnotationAttribute { get; set; }
|
||||
|
||||
public string Documentation { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace Ewide.Core.WebApi.Areas.HelpPage.ModelDescriptions
|
||||
{
|
||||
public class ParameterDescription
|
||||
{
|
||||
public ParameterDescription()
|
||||
{
|
||||
Annotations = new Collection<ParameterAnnotation>();
|
||||
}
|
||||
|
||||
public Collection<ParameterAnnotation> Annotations { get; private set; }
|
||||
|
||||
public string Documentation { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public ModelDescription TypeDescription { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace Ewide.Core.WebApi.Areas.HelpPage.ModelDescriptions
|
||||
{
|
||||
public class SimpleTypeModelDescription : ModelDescription
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Web.Http.Description;
|
||||
using Ewide.Core.WebApi.Areas.HelpPage.ModelDescriptions;
|
||||
|
||||
namespace Ewide.Core.WebApi.Areas.HelpPage.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// The model that represents an API displayed on the help page.
|
||||
/// </summary>
|
||||
public class HelpPageApiModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="HelpPageApiModel"/> class.
|
||||
/// </summary>
|
||||
public HelpPageApiModel()
|
||||
{
|
||||
UriParameters = new Collection<ParameterDescription>();
|
||||
SampleRequests = new Dictionary<MediaTypeHeaderValue, object>();
|
||||
SampleResponses = new Dictionary<MediaTypeHeaderValue, object>();
|
||||
ErrorMessages = new Collection<string>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="ApiDescription"/> that describes the API.
|
||||
/// </summary>
|
||||
public ApiDescription ApiDescription { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="ParameterDescription"/> collection that describes the URI parameters for the API.
|
||||
/// </summary>
|
||||
public Collection<ParameterDescription> UriParameters { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the documentation for the request.
|
||||
/// </summary>
|
||||
public string RequestDocumentation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="ModelDescription"/> that describes the request body.
|
||||
/// </summary>
|
||||
public ModelDescription RequestModelDescription { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the request body parameter descriptions.
|
||||
/// </summary>
|
||||
public IList<ParameterDescription> RequestBodyParameters
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetParameterDescriptions(RequestModelDescription);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="ModelDescription"/> that describes the resource.
|
||||
/// </summary>
|
||||
public ModelDescription ResourceDescription { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the resource property descriptions.
|
||||
/// </summary>
|
||||
public IList<ParameterDescription> ResourceProperties
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetParameterDescriptions(ResourceDescription);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the sample requests associated with the API.
|
||||
/// </summary>
|
||||
public IDictionary<MediaTypeHeaderValue, object> SampleRequests { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the sample responses associated with the API.
|
||||
/// </summary>
|
||||
public IDictionary<MediaTypeHeaderValue, object> SampleResponses { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the error messages associated with this model.
|
||||
/// </summary>
|
||||
public Collection<string> ErrorMessages { get; private set; }
|
||||
|
||||
private static IList<ParameterDescription> GetParameterDescriptions(ModelDescription modelDescription)
|
||||
{
|
||||
ComplexTypeModelDescription complexTypeModelDescription = modelDescription as ComplexTypeModelDescription;
|
||||
if (complexTypeModelDescription != null)
|
||||
{
|
||||
return complexTypeModelDescription.Properties;
|
||||
}
|
||||
|
||||
CollectionModelDescription collectionModelDescription = modelDescription as CollectionModelDescription;
|
||||
if (collectionModelDescription != null)
|
||||
{
|
||||
complexTypeModelDescription = collectionModelDescription.ElementDescription as ComplexTypeModelDescription;
|
||||
if (complexTypeModelDescription != null)
|
||||
{
|
||||
return complexTypeModelDescription.Properties;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,444 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Formatting;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Web.Http.Description;
|
||||
using System.Xml.Linq;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Ewide.Core.WebApi.Areas.HelpPage
|
||||
{
|
||||
/// <summary>
|
||||
/// This class will generate the samples for the help page.
|
||||
/// </summary>
|
||||
public class HelpPageSampleGenerator
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="HelpPageSampleGenerator"/> class.
|
||||
/// </summary>
|
||||
public HelpPageSampleGenerator()
|
||||
{
|
||||
ActualHttpMessageTypes = new Dictionary<HelpPageSampleKey, Type>();
|
||||
ActionSamples = new Dictionary<HelpPageSampleKey, object>();
|
||||
SampleObjects = new Dictionary<Type, object>();
|
||||
SampleObjectFactories = new List<Func<HelpPageSampleGenerator, Type, object>>
|
||||
{
|
||||
DefaultSampleObjectFactory,
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets CLR types that are used as the content of <see cref="HttpRequestMessage"/> or <see cref="HttpResponseMessage"/>.
|
||||
/// </summary>
|
||||
public IDictionary<HelpPageSampleKey, Type> ActualHttpMessageTypes { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the objects that are used directly as samples for certain actions.
|
||||
/// </summary>
|
||||
public IDictionary<HelpPageSampleKey, object> ActionSamples { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the objects that are serialized as samples by the supported formatters.
|
||||
/// </summary>
|
||||
public IDictionary<Type, object> SampleObjects { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets factories for the objects that the supported formatters will serialize as samples. Processed in order,
|
||||
/// stopping when the factory successfully returns a non-<see langref="null"/> object.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Collection includes just <see cref="ObjectGenerator.GenerateObject(Type)"/> initially. Use
|
||||
/// <code>SampleObjectFactories.Insert(0, func)</code> to provide an override and
|
||||
/// <code>SampleObjectFactories.Add(func)</code> to provide a fallback.</remarks>
|
||||
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures",
|
||||
Justification = "This is an appropriate nesting of generic types")]
|
||||
public IList<Func<HelpPageSampleGenerator, Type, object>> SampleObjectFactories { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the request body samples for a given <see cref="ApiDescription"/>.
|
||||
/// </summary>
|
||||
/// <param name="api">The <see cref="ApiDescription"/>.</param>
|
||||
/// <returns>The samples keyed by media type.</returns>
|
||||
public IDictionary<MediaTypeHeaderValue, object> GetSampleRequests(ApiDescription api)
|
||||
{
|
||||
return GetSample(api, SampleDirection.Request);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the response body samples for a given <see cref="ApiDescription"/>.
|
||||
/// </summary>
|
||||
/// <param name="api">The <see cref="ApiDescription"/>.</param>
|
||||
/// <returns>The samples keyed by media type.</returns>
|
||||
public IDictionary<MediaTypeHeaderValue, object> GetSampleResponses(ApiDescription api)
|
||||
{
|
||||
return GetSample(api, SampleDirection.Response);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the request or response body samples.
|
||||
/// </summary>
|
||||
/// <param name="api">The <see cref="ApiDescription"/>.</param>
|
||||
/// <param name="sampleDirection">The value indicating whether the sample is for a request or for a response.</param>
|
||||
/// <returns>The samples keyed by media type.</returns>
|
||||
public virtual IDictionary<MediaTypeHeaderValue, object> GetSample(ApiDescription api, SampleDirection sampleDirection)
|
||||
{
|
||||
if (api == null)
|
||||
{
|
||||
throw new ArgumentNullException("api");
|
||||
}
|
||||
string controllerName = api.ActionDescriptor.ControllerDescriptor.ControllerName;
|
||||
string actionName = api.ActionDescriptor.ActionName;
|
||||
IEnumerable<string> parameterNames = api.ParameterDescriptions.Select(p => p.Name);
|
||||
Collection<MediaTypeFormatter> formatters;
|
||||
Type type = ResolveType(api, controllerName, actionName, parameterNames, sampleDirection, out formatters);
|
||||
var samples = new Dictionary<MediaTypeHeaderValue, object>();
|
||||
|
||||
// Use the samples provided directly for actions
|
||||
var actionSamples = GetAllActionSamples(controllerName, actionName, parameterNames, sampleDirection);
|
||||
foreach (var actionSample in actionSamples)
|
||||
{
|
||||
samples.Add(actionSample.Key.MediaType, WrapSampleIfString(actionSample.Value));
|
||||
}
|
||||
|
||||
// Do the sample generation based on formatters only if an action doesn't return an HttpResponseMessage.
|
||||
// Here we cannot rely on formatters because we don't know what's in the HttpResponseMessage, it might not even use formatters.
|
||||
if (type != null && !typeof(HttpResponseMessage).IsAssignableFrom(type))
|
||||
{
|
||||
object sampleObject = GetSampleObject(type);
|
||||
foreach (var formatter in formatters)
|
||||
{
|
||||
foreach (MediaTypeHeaderValue mediaType in formatter.SupportedMediaTypes)
|
||||
{
|
||||
if (!samples.ContainsKey(mediaType))
|
||||
{
|
||||
object sample = GetActionSample(controllerName, actionName, parameterNames, type, formatter, mediaType, sampleDirection);
|
||||
|
||||
// If no sample found, try generate sample using formatter and sample object
|
||||
if (sample == null && sampleObject != null)
|
||||
{
|
||||
sample = WriteSampleObjectUsingFormatter(formatter, sampleObject, type, mediaType);
|
||||
}
|
||||
|
||||
samples.Add(mediaType, WrapSampleIfString(sample));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return samples;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Search for samples that are provided directly through <see cref="ActionSamples"/>.
|
||||
/// </summary>
|
||||
/// <param name="controllerName">Name of the controller.</param>
|
||||
/// <param name="actionName">Name of the action.</param>
|
||||
/// <param name="parameterNames">The parameter names.</param>
|
||||
/// <param name="type">The CLR type.</param>
|
||||
/// <param name="formatter">The formatter.</param>
|
||||
/// <param name="mediaType">The media type.</param>
|
||||
/// <param name="sampleDirection">The value indicating whether the sample is for a request or for a response.</param>
|
||||
/// <returns>The sample that matches the parameters.</returns>
|
||||
public virtual object GetActionSample(string controllerName, string actionName, IEnumerable<string> parameterNames, Type type, MediaTypeFormatter formatter, MediaTypeHeaderValue mediaType, SampleDirection sampleDirection)
|
||||
{
|
||||
object sample;
|
||||
|
||||
// First, try to get the sample provided for the specified mediaType, sampleDirection, controllerName, actionName and parameterNames.
|
||||
// If not found, try to get the sample provided for the specified mediaType, sampleDirection, controllerName and actionName regardless of the parameterNames.
|
||||
// If still not found, try to get the sample provided for the specified mediaType and type.
|
||||
// Finally, try to get the sample provided for the specified mediaType.
|
||||
if (ActionSamples.TryGetValue(new HelpPageSampleKey(mediaType, sampleDirection, controllerName, actionName, parameterNames), out sample) ||
|
||||
ActionSamples.TryGetValue(new HelpPageSampleKey(mediaType, sampleDirection, controllerName, actionName, new[] { "*" }), out sample) ||
|
||||
ActionSamples.TryGetValue(new HelpPageSampleKey(mediaType, type), out sample) ||
|
||||
ActionSamples.TryGetValue(new HelpPageSampleKey(mediaType), out sample))
|
||||
{
|
||||
return sample;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the sample object that will be serialized by the formatters.
|
||||
/// First, it will look at the <see cref="SampleObjects"/>. If no sample object is found, it will try to create
|
||||
/// one using <see cref="DefaultSampleObjectFactory"/> (which wraps an <see cref="ObjectGenerator"/>) and other
|
||||
/// factories in <see cref="SampleObjectFactories"/>.
|
||||
/// </summary>
|
||||
/// <param name="type">The type.</param>
|
||||
/// <returns>The sample object.</returns>
|
||||
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes",
|
||||
Justification = "Even if all items in SampleObjectFactories throw, problem will be visible as missing sample.")]
|
||||
public virtual object GetSampleObject(Type type)
|
||||
{
|
||||
object sampleObject;
|
||||
|
||||
if (!SampleObjects.TryGetValue(type, out sampleObject))
|
||||
{
|
||||
// No specific object available, try our factories.
|
||||
foreach (Func<HelpPageSampleGenerator, Type, object> factory in SampleObjectFactories)
|
||||
{
|
||||
if (factory == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
sampleObject = factory(this, type);
|
||||
if (sampleObject != null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Ignore any problems encountered in the factory; go on to the next one (if any).
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sampleObject;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resolves the actual type of <see cref="System.Net.Http.ObjectContent{T}"/> passed to the <see cref="System.Net.Http.HttpRequestMessage"/> in an action.
|
||||
/// </summary>
|
||||
/// <param name="api">The <see cref="ApiDescription"/>.</param>
|
||||
/// <returns>The type.</returns>
|
||||
public virtual Type ResolveHttpRequestMessageType(ApiDescription api)
|
||||
{
|
||||
string controllerName = api.ActionDescriptor.ControllerDescriptor.ControllerName;
|
||||
string actionName = api.ActionDescriptor.ActionName;
|
||||
IEnumerable<string> parameterNames = api.ParameterDescriptions.Select(p => p.Name);
|
||||
Collection<MediaTypeFormatter> formatters;
|
||||
return ResolveType(api, controllerName, actionName, parameterNames, SampleDirection.Request, out formatters);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resolves the type of the action parameter or return value when <see cref="HttpRequestMessage"/> or <see cref="HttpResponseMessage"/> is used.
|
||||
/// </summary>
|
||||
/// <param name="api">The <see cref="ApiDescription"/>.</param>
|
||||
/// <param name="controllerName">Name of the controller.</param>
|
||||
/// <param name="actionName">Name of the action.</param>
|
||||
/// <param name="parameterNames">The parameter names.</param>
|
||||
/// <param name="sampleDirection">The value indicating whether the sample is for a request or a response.</param>
|
||||
/// <param name="formatters">The formatters.</param>
|
||||
[SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", Justification = "This is only used in advanced scenarios.")]
|
||||
public virtual Type ResolveType(ApiDescription api, string controllerName, string actionName, IEnumerable<string> parameterNames, SampleDirection sampleDirection, out Collection<MediaTypeFormatter> formatters)
|
||||
{
|
||||
if (!Enum.IsDefined(typeof(SampleDirection), sampleDirection))
|
||||
{
|
||||
throw new InvalidEnumArgumentException("sampleDirection", (int)sampleDirection, typeof(SampleDirection));
|
||||
}
|
||||
if (api == null)
|
||||
{
|
||||
throw new ArgumentNullException("api");
|
||||
}
|
||||
Type type;
|
||||
if (ActualHttpMessageTypes.TryGetValue(new HelpPageSampleKey(sampleDirection, controllerName, actionName, parameterNames), out type) ||
|
||||
ActualHttpMessageTypes.TryGetValue(new HelpPageSampleKey(sampleDirection, controllerName, actionName, new[] { "*" }), out type))
|
||||
{
|
||||
// Re-compute the supported formatters based on type
|
||||
Collection<MediaTypeFormatter> newFormatters = new Collection<MediaTypeFormatter>();
|
||||
foreach (var formatter in api.ActionDescriptor.Configuration.Formatters)
|
||||
{
|
||||
if (IsFormatSupported(sampleDirection, formatter, type))
|
||||
{
|
||||
newFormatters.Add(formatter);
|
||||
}
|
||||
}
|
||||
formatters = newFormatters;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (sampleDirection)
|
||||
{
|
||||
case SampleDirection.Request:
|
||||
ApiParameterDescription requestBodyParameter = api.ParameterDescriptions.FirstOrDefault(p => p.Source == ApiParameterSource.FromBody);
|
||||
type = requestBodyParameter == null ? null : requestBodyParameter.ParameterDescriptor.ParameterType;
|
||||
formatters = api.SupportedRequestBodyFormatters;
|
||||
break;
|
||||
case SampleDirection.Response:
|
||||
default:
|
||||
type = api.ResponseDescription.ResponseType ?? api.ResponseDescription.DeclaredType;
|
||||
formatters = api.SupportedResponseFormatters;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the sample object using formatter.
|
||||
/// </summary>
|
||||
/// <param name="formatter">The formatter.</param>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <param name="type">The type.</param>
|
||||
/// <param name="mediaType">Type of the media.</param>
|
||||
/// <returns></returns>
|
||||
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "The exception is recorded as InvalidSample.")]
|
||||
public virtual object WriteSampleObjectUsingFormatter(MediaTypeFormatter formatter, object value, Type type, MediaTypeHeaderValue mediaType)
|
||||
{
|
||||
if (formatter == null)
|
||||
{
|
||||
throw new ArgumentNullException("formatter");
|
||||
}
|
||||
if (mediaType == null)
|
||||
{
|
||||
throw new ArgumentNullException("mediaType");
|
||||
}
|
||||
|
||||
object sample = String.Empty;
|
||||
MemoryStream ms = null;
|
||||
HttpContent content = null;
|
||||
try
|
||||
{
|
||||
if (formatter.CanWriteType(type))
|
||||
{
|
||||
ms = new MemoryStream();
|
||||
content = new ObjectContent(type, value, formatter, mediaType);
|
||||
formatter.WriteToStreamAsync(type, value, ms, content, null).Wait();
|
||||
ms.Position = 0;
|
||||
StreamReader reader = new StreamReader(ms);
|
||||
string serializedSampleString = reader.ReadToEnd();
|
||||
if (mediaType.MediaType.ToUpperInvariant().Contains("XML"))
|
||||
{
|
||||
serializedSampleString = TryFormatXml(serializedSampleString);
|
||||
}
|
||||
else if (mediaType.MediaType.ToUpperInvariant().Contains("JSON"))
|
||||
{
|
||||
serializedSampleString = TryFormatJson(serializedSampleString);
|
||||
}
|
||||
|
||||
sample = new TextSample(serializedSampleString);
|
||||
}
|
||||
else
|
||||
{
|
||||
sample = new InvalidSample(String.Format(
|
||||
CultureInfo.CurrentCulture,
|
||||
"Failed to generate the sample for media type '{0}'. Cannot use formatter '{1}' to write type '{2}'.",
|
||||
mediaType,
|
||||
formatter.GetType().Name,
|
||||
type.Name));
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
sample = new InvalidSample(String.Format(
|
||||
CultureInfo.CurrentCulture,
|
||||
"An exception has occurred while using the formatter '{0}' to generate sample for media type '{1}'. Exception message: {2}",
|
||||
formatter.GetType().Name,
|
||||
mediaType.MediaType,
|
||||
UnwrapException(e).Message));
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (ms != null)
|
||||
{
|
||||
ms.Dispose();
|
||||
}
|
||||
if (content != null)
|
||||
{
|
||||
content.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
return sample;
|
||||
}
|
||||
|
||||
internal static Exception UnwrapException(Exception exception)
|
||||
{
|
||||
AggregateException aggregateException = exception as AggregateException;
|
||||
if (aggregateException != null)
|
||||
{
|
||||
return aggregateException.Flatten().InnerException;
|
||||
}
|
||||
return exception;
|
||||
}
|
||||
|
||||
// Default factory for sample objects
|
||||
private static object DefaultSampleObjectFactory(HelpPageSampleGenerator sampleGenerator, Type type)
|
||||
{
|
||||
// Try to create a default sample object
|
||||
ObjectGenerator objectGenerator = new ObjectGenerator();
|
||||
return objectGenerator.GenerateObject(type);
|
||||
}
|
||||
|
||||
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Handling the failure by returning the original string.")]
|
||||
private static string TryFormatJson(string str)
|
||||
{
|
||||
try
|
||||
{
|
||||
object parsedJson = JsonConvert.DeserializeObject(str);
|
||||
return JsonConvert.SerializeObject(parsedJson, Formatting.Indented);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// can't parse JSON, return the original string
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
||||
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Handling the failure by returning the original string.")]
|
||||
private static string TryFormatXml(string str)
|
||||
{
|
||||
try
|
||||
{
|
||||
XDocument xml = XDocument.Parse(str);
|
||||
return xml.ToString();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// can't parse XML, return the original string
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsFormatSupported(SampleDirection sampleDirection, MediaTypeFormatter formatter, Type type)
|
||||
{
|
||||
switch (sampleDirection)
|
||||
{
|
||||
case SampleDirection.Request:
|
||||
return formatter.CanReadType(type);
|
||||
case SampleDirection.Response:
|
||||
return formatter.CanWriteType(type);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private IEnumerable<KeyValuePair<HelpPageSampleKey, object>> GetAllActionSamples(string controllerName, string actionName, IEnumerable<string> parameterNames, SampleDirection sampleDirection)
|
||||
{
|
||||
HashSet<string> parameterNamesSet = new HashSet<string>(parameterNames, StringComparer.OrdinalIgnoreCase);
|
||||
foreach (var sample in ActionSamples)
|
||||
{
|
||||
HelpPageSampleKey sampleKey = sample.Key;
|
||||
if (String.Equals(controllerName, sampleKey.ControllerName, StringComparison.OrdinalIgnoreCase) &&
|
||||
String.Equals(actionName, sampleKey.ActionName, StringComparison.OrdinalIgnoreCase) &&
|
||||
(sampleKey.ParameterNames.SetEquals(new[] { "*" }) || parameterNamesSet.SetEquals(sampleKey.ParameterNames)) &&
|
||||
sampleDirection == sampleKey.SampleDirection)
|
||||
{
|
||||
yield return sample;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static object WrapSampleIfString(object sample)
|
||||
{
|
||||
string stringSample = sample as string;
|
||||
if (stringSample != null)
|
||||
{
|
||||
return new TextSample(stringSample);
|
||||
}
|
||||
|
||||
return sample;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Net.Http.Headers;
|
||||
|
||||
namespace Ewide.Core.WebApi.Areas.HelpPage
|
||||
{
|
||||
/// <summary>
|
||||
/// This is used to identify the place where the sample should be applied.
|
||||
/// </summary>
|
||||
public class HelpPageSampleKey
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="HelpPageSampleKey"/> based on media type.
|
||||
/// </summary>
|
||||
/// <param name="mediaType">The media type.</param>
|
||||
public HelpPageSampleKey(MediaTypeHeaderValue mediaType)
|
||||
{
|
||||
if (mediaType == null)
|
||||
{
|
||||
throw new ArgumentNullException("mediaType");
|
||||
}
|
||||
|
||||
ActionName = String.Empty;
|
||||
ControllerName = String.Empty;
|
||||
MediaType = mediaType;
|
||||
ParameterNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="HelpPageSampleKey"/> based on media type and CLR type.
|
||||
/// </summary>
|
||||
/// <param name="mediaType">The media type.</param>
|
||||
/// <param name="type">The CLR type.</param>
|
||||
public HelpPageSampleKey(MediaTypeHeaderValue mediaType, Type type)
|
||||
: this(mediaType)
|
||||
{
|
||||
if (type == null)
|
||||
{
|
||||
throw new ArgumentNullException("type");
|
||||
}
|
||||
|
||||
ParameterType = type;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="HelpPageSampleKey"/> based on <see cref="SampleDirection"/>, controller name, action name and parameter names.
|
||||
/// </summary>
|
||||
/// <param name="sampleDirection">The <see cref="SampleDirection"/>.</param>
|
||||
/// <param name="controllerName">Name of the controller.</param>
|
||||
/// <param name="actionName">Name of the action.</param>
|
||||
/// <param name="parameterNames">The parameter names.</param>
|
||||
public HelpPageSampleKey(SampleDirection sampleDirection, string controllerName, string actionName, IEnumerable<string> parameterNames)
|
||||
{
|
||||
if (!Enum.IsDefined(typeof(SampleDirection), sampleDirection))
|
||||
{
|
||||
throw new InvalidEnumArgumentException("sampleDirection", (int)sampleDirection, typeof(SampleDirection));
|
||||
}
|
||||
if (controllerName == null)
|
||||
{
|
||||
throw new ArgumentNullException("controllerName");
|
||||
}
|
||||
if (actionName == null)
|
||||
{
|
||||
throw new ArgumentNullException("actionName");
|
||||
}
|
||||
if (parameterNames == null)
|
||||
{
|
||||
throw new ArgumentNullException("parameterNames");
|
||||
}
|
||||
|
||||
ControllerName = controllerName;
|
||||
ActionName = actionName;
|
||||
ParameterNames = new HashSet<string>(parameterNames, StringComparer.OrdinalIgnoreCase);
|
||||
SampleDirection = sampleDirection;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="HelpPageSampleKey"/> based on media type, <see cref="SampleDirection"/>, controller name, action name and parameter names.
|
||||
/// </summary>
|
||||
/// <param name="mediaType">The media type.</param>
|
||||
/// <param name="sampleDirection">The <see cref="SampleDirection"/>.</param>
|
||||
/// <param name="controllerName">Name of the controller.</param>
|
||||
/// <param name="actionName">Name of the action.</param>
|
||||
/// <param name="parameterNames">The parameter names.</param>
|
||||
public HelpPageSampleKey(MediaTypeHeaderValue mediaType, SampleDirection sampleDirection, string controllerName, string actionName, IEnumerable<string> parameterNames)
|
||||
: this(sampleDirection, controllerName, actionName, parameterNames)
|
||||
{
|
||||
if (mediaType == null)
|
||||
{
|
||||
throw new ArgumentNullException("mediaType");
|
||||
}
|
||||
|
||||
MediaType = mediaType;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the controller.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The name of the controller.
|
||||
/// </value>
|
||||
public string ControllerName { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the action.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The name of the action.
|
||||
/// </value>
|
||||
public string ActionName { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the media type.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The media type.
|
||||
/// </value>
|
||||
public MediaTypeHeaderValue MediaType { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the parameter names.
|
||||
/// </summary>
|
||||
public HashSet<string> ParameterNames { get; private set; }
|
||||
|
||||
public Type ParameterType { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="SampleDirection"/>.
|
||||
/// </summary>
|
||||
public SampleDirection? SampleDirection { get; private set; }
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
HelpPageSampleKey otherKey = obj as HelpPageSampleKey;
|
||||
if (otherKey == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return String.Equals(ControllerName, otherKey.ControllerName, StringComparison.OrdinalIgnoreCase) &&
|
||||
String.Equals(ActionName, otherKey.ActionName, StringComparison.OrdinalIgnoreCase) &&
|
||||
(MediaType == otherKey.MediaType || (MediaType != null && MediaType.Equals(otherKey.MediaType))) &&
|
||||
ParameterType == otherKey.ParameterType &&
|
||||
SampleDirection == otherKey.SampleDirection &&
|
||||
ParameterNames.SetEquals(otherKey.ParameterNames);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
int hashCode = ControllerName.ToUpperInvariant().GetHashCode() ^ ActionName.ToUpperInvariant().GetHashCode();
|
||||
if (MediaType != null)
|
||||
{
|
||||
hashCode ^= MediaType.GetHashCode();
|
||||
}
|
||||
if (SampleDirection != null)
|
||||
{
|
||||
hashCode ^= SampleDirection.GetHashCode();
|
||||
}
|
||||
if (ParameterType != null)
|
||||
{
|
||||
hashCode ^= ParameterType.GetHashCode();
|
||||
}
|
||||
foreach (string parameterName in ParameterNames)
|
||||
{
|
||||
hashCode ^= parameterName.ToUpperInvariant().GetHashCode();
|
||||
}
|
||||
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using System;
|
||||
|
||||
namespace Ewide.Core.WebApi.Areas.HelpPage
|
||||
{
|
||||
/// <summary>
|
||||
/// This represents an image sample on the help page. There's a display template named ImageSample associated with this class.
|
||||
/// </summary>
|
||||
public class ImageSample
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ImageSample"/> class.
|
||||
/// </summary>
|
||||
/// <param name="src">The URL of an image.</param>
|
||||
public ImageSample(string src)
|
||||
{
|
||||
if (src == null)
|
||||
{
|
||||
throw new ArgumentNullException("src");
|
||||
}
|
||||
Src = src;
|
||||
}
|
||||
|
||||
public string Src { get; private set; }
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
ImageSample other = obj as ImageSample;
|
||||
return other != null && Src == other.Src;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Src.GetHashCode();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Src;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
|
||||
namespace Ewide.Core.WebApi.Areas.HelpPage
|
||||
{
|
||||
/// <summary>
|
||||
/// This represents an invalid sample on the help page. There's a display template named InvalidSample associated with this class.
|
||||
/// </summary>
|
||||
public class InvalidSample
|
||||
{
|
||||
public InvalidSample(string errorMessage)
|
||||
{
|
||||
if (errorMessage == null)
|
||||
{
|
||||
throw new ArgumentNullException("errorMessage");
|
||||
}
|
||||
ErrorMessage = errorMessage;
|
||||
}
|
||||
|
||||
public string ErrorMessage { get; private set; }
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
InvalidSample other = obj as InvalidSample;
|
||||
return other != null && ErrorMessage == other.ErrorMessage;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return ErrorMessage.GetHashCode();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return ErrorMessage;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,456 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Ewide.Core.WebApi.Areas.HelpPage
|
||||
{
|
||||
/// <summary>
|
||||
/// This class will create an object of a given type and populate it with sample data.
|
||||
/// </summary>
|
||||
public class ObjectGenerator
|
||||
{
|
||||
internal const int DefaultCollectionSize = 2;
|
||||
private readonly SimpleTypeObjectGenerator SimpleObjectGenerator = new SimpleTypeObjectGenerator();
|
||||
|
||||
/// <summary>
|
||||
/// Generates an object for a given type. The type needs to be public, have a public default constructor and settable public properties/fields. Currently it supports the following types:
|
||||
/// Simple types: <see cref="int"/>, <see cref="string"/>, <see cref="Enum"/>, <see cref="DateTime"/>, <see cref="Uri"/>, etc.
|
||||
/// Complex types: POCO types.
|
||||
/// Nullables: <see cref="Nullable{T}"/>.
|
||||
/// Arrays: arrays of simple types or complex types.
|
||||
/// Key value pairs: <see cref="KeyValuePair{TKey,TValue}"/>
|
||||
/// Tuples: <see cref="Tuple{T1}"/>, <see cref="Tuple{T1,T2}"/>, etc
|
||||
/// Dictionaries: <see cref="IDictionary{TKey,TValue}"/> or anything deriving from <see cref="IDictionary{TKey,TValue}"/>.
|
||||
/// Collections: <see cref="IList{T}"/>, <see cref="IEnumerable{T}"/>, <see cref="ICollection{T}"/>, <see cref="IList"/>, <see cref="IEnumerable"/>, <see cref="ICollection"/> or anything deriving from <see cref="ICollection{T}"/> or <see cref="IList"/>.
|
||||
/// Queryables: <see cref="IQueryable"/>, <see cref="IQueryable{T}"/>.
|
||||
/// </summary>
|
||||
/// <param name="type">The type.</param>
|
||||
/// <returns>An object of the given type.</returns>
|
||||
public object GenerateObject(Type type)
|
||||
{
|
||||
return GenerateObject(type, new Dictionary<Type, object>());
|
||||
}
|
||||
|
||||
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Here we just want to return null if anything goes wrong.")]
|
||||
private object GenerateObject(Type type, Dictionary<Type, object> createdObjectReferences)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (SimpleTypeObjectGenerator.CanGenerateObject(type))
|
||||
{
|
||||
return SimpleObjectGenerator.GenerateObject(type);
|
||||
}
|
||||
|
||||
if (type.IsArray)
|
||||
{
|
||||
return GenerateArray(type, DefaultCollectionSize, createdObjectReferences);
|
||||
}
|
||||
|
||||
if (type.IsGenericType)
|
||||
{
|
||||
return GenerateGenericType(type, DefaultCollectionSize, createdObjectReferences);
|
||||
}
|
||||
|
||||
if (type == typeof(IDictionary))
|
||||
{
|
||||
return GenerateDictionary(typeof(Hashtable), DefaultCollectionSize, createdObjectReferences);
|
||||
}
|
||||
|
||||
if (typeof(IDictionary).IsAssignableFrom(type))
|
||||
{
|
||||
return GenerateDictionary(type, DefaultCollectionSize, createdObjectReferences);
|
||||
}
|
||||
|
||||
if (type == typeof(IList) ||
|
||||
type == typeof(IEnumerable) ||
|
||||
type == typeof(ICollection))
|
||||
{
|
||||
return GenerateCollection(typeof(ArrayList), DefaultCollectionSize, createdObjectReferences);
|
||||
}
|
||||
|
||||
if (typeof(IList).IsAssignableFrom(type))
|
||||
{
|
||||
return GenerateCollection(type, DefaultCollectionSize, createdObjectReferences);
|
||||
}
|
||||
|
||||
if (type == typeof(IQueryable))
|
||||
{
|
||||
return GenerateQueryable(type, DefaultCollectionSize, createdObjectReferences);
|
||||
}
|
||||
|
||||
if (type.IsEnum)
|
||||
{
|
||||
return GenerateEnum(type);
|
||||
}
|
||||
|
||||
if (type.IsPublic || type.IsNestedPublic)
|
||||
{
|
||||
return GenerateComplexObject(type, createdObjectReferences);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Returns null if anything fails
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static object GenerateGenericType(Type type, int collectionSize, Dictionary<Type, object> createdObjectReferences)
|
||||
{
|
||||
Type genericTypeDefinition = type.GetGenericTypeDefinition();
|
||||
if (genericTypeDefinition == typeof(Nullable<>))
|
||||
{
|
||||
return GenerateNullable(type, createdObjectReferences);
|
||||
}
|
||||
|
||||
if (genericTypeDefinition == typeof(KeyValuePair<,>))
|
||||
{
|
||||
return GenerateKeyValuePair(type, createdObjectReferences);
|
||||
}
|
||||
|
||||
if (IsTuple(genericTypeDefinition))
|
||||
{
|
||||
return GenerateTuple(type, createdObjectReferences);
|
||||
}
|
||||
|
||||
Type[] genericArguments = type.GetGenericArguments();
|
||||
if (genericArguments.Length == 1)
|
||||
{
|
||||
if (genericTypeDefinition == typeof(IList<>) ||
|
||||
genericTypeDefinition == typeof(IEnumerable<>) ||
|
||||
genericTypeDefinition == typeof(ICollection<>))
|
||||
{
|
||||
Type collectionType = typeof(List<>).MakeGenericType(genericArguments);
|
||||
return GenerateCollection(collectionType, collectionSize, createdObjectReferences);
|
||||
}
|
||||
|
||||
if (genericTypeDefinition == typeof(IQueryable<>))
|
||||
{
|
||||
return GenerateQueryable(type, collectionSize, createdObjectReferences);
|
||||
}
|
||||
|
||||
Type closedCollectionType = typeof(ICollection<>).MakeGenericType(genericArguments[0]);
|
||||
if (closedCollectionType.IsAssignableFrom(type))
|
||||
{
|
||||
return GenerateCollection(type, collectionSize, createdObjectReferences);
|
||||
}
|
||||
}
|
||||
|
||||
if (genericArguments.Length == 2)
|
||||
{
|
||||
if (genericTypeDefinition == typeof(IDictionary<,>))
|
||||
{
|
||||
Type dictionaryType = typeof(Dictionary<,>).MakeGenericType(genericArguments);
|
||||
return GenerateDictionary(dictionaryType, collectionSize, createdObjectReferences);
|
||||
}
|
||||
|
||||
Type closedDictionaryType = typeof(IDictionary<,>).MakeGenericType(genericArguments[0], genericArguments[1]);
|
||||
if (closedDictionaryType.IsAssignableFrom(type))
|
||||
{
|
||||
return GenerateDictionary(type, collectionSize, createdObjectReferences);
|
||||
}
|
||||
}
|
||||
|
||||
if (type.IsPublic || type.IsNestedPublic)
|
||||
{
|
||||
return GenerateComplexObject(type, createdObjectReferences);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static object GenerateTuple(Type type, Dictionary<Type, object> createdObjectReferences)
|
||||
{
|
||||
Type[] genericArgs = type.GetGenericArguments();
|
||||
object[] parameterValues = new object[genericArgs.Length];
|
||||
bool failedToCreateTuple = true;
|
||||
ObjectGenerator objectGenerator = new ObjectGenerator();
|
||||
for (int i = 0; i < genericArgs.Length; i++)
|
||||
{
|
||||
parameterValues[i] = objectGenerator.GenerateObject(genericArgs[i], createdObjectReferences);
|
||||
failedToCreateTuple &= parameterValues[i] == null;
|
||||
}
|
||||
if (failedToCreateTuple)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
object result = Activator.CreateInstance(type, parameterValues);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static bool IsTuple(Type genericTypeDefinition)
|
||||
{
|
||||
return genericTypeDefinition == typeof(Tuple<>) ||
|
||||
genericTypeDefinition == typeof(Tuple<,>) ||
|
||||
genericTypeDefinition == typeof(Tuple<,,>) ||
|
||||
genericTypeDefinition == typeof(Tuple<,,,>) ||
|
||||
genericTypeDefinition == typeof(Tuple<,,,,>) ||
|
||||
genericTypeDefinition == typeof(Tuple<,,,,,>) ||
|
||||
genericTypeDefinition == typeof(Tuple<,,,,,,>) ||
|
||||
genericTypeDefinition == typeof(Tuple<,,,,,,,>);
|
||||
}
|
||||
|
||||
private static object GenerateKeyValuePair(Type keyValuePairType, Dictionary<Type, object> createdObjectReferences)
|
||||
{
|
||||
Type[] genericArgs = keyValuePairType.GetGenericArguments();
|
||||
Type typeK = genericArgs[0];
|
||||
Type typeV = genericArgs[1];
|
||||
ObjectGenerator objectGenerator = new ObjectGenerator();
|
||||
object keyObject = objectGenerator.GenerateObject(typeK, createdObjectReferences);
|
||||
object valueObject = objectGenerator.GenerateObject(typeV, createdObjectReferences);
|
||||
if (keyObject == null && valueObject == null)
|
||||
{
|
||||
// Failed to create key and values
|
||||
return null;
|
||||
}
|
||||
object result = Activator.CreateInstance(keyValuePairType, keyObject, valueObject);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static object GenerateArray(Type arrayType, int size, Dictionary<Type, object> createdObjectReferences)
|
||||
{
|
||||
Type type = arrayType.GetElementType();
|
||||
Array result = Array.CreateInstance(type, size);
|
||||
bool areAllElementsNull = true;
|
||||
ObjectGenerator objectGenerator = new ObjectGenerator();
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
object element = objectGenerator.GenerateObject(type, createdObjectReferences);
|
||||
result.SetValue(element, i);
|
||||
areAllElementsNull &= element == null;
|
||||
}
|
||||
|
||||
if (areAllElementsNull)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static object GenerateDictionary(Type dictionaryType, int size, Dictionary<Type, object> createdObjectReferences)
|
||||
{
|
||||
Type typeK = typeof(object);
|
||||
Type typeV = typeof(object);
|
||||
if (dictionaryType.IsGenericType)
|
||||
{
|
||||
Type[] genericArgs = dictionaryType.GetGenericArguments();
|
||||
typeK = genericArgs[0];
|
||||
typeV = genericArgs[1];
|
||||
}
|
||||
|
||||
object result = Activator.CreateInstance(dictionaryType);
|
||||
MethodInfo addMethod = dictionaryType.GetMethod("Add") ?? dictionaryType.GetMethod("TryAdd");
|
||||
MethodInfo containsMethod = dictionaryType.GetMethod("Contains") ?? dictionaryType.GetMethod("ContainsKey");
|
||||
ObjectGenerator objectGenerator = new ObjectGenerator();
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
object newKey = objectGenerator.GenerateObject(typeK, createdObjectReferences);
|
||||
if (newKey == null)
|
||||
{
|
||||
// Cannot generate a valid key
|
||||
return null;
|
||||
}
|
||||
|
||||
bool containsKey = (bool)containsMethod.Invoke(result, new object[] { newKey });
|
||||
if (!containsKey)
|
||||
{
|
||||
object newValue = objectGenerator.GenerateObject(typeV, createdObjectReferences);
|
||||
addMethod.Invoke(result, new object[] { newKey, newValue });
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static object GenerateEnum(Type enumType)
|
||||
{
|
||||
Array possibleValues = Enum.GetValues(enumType);
|
||||
if (possibleValues.Length > 0)
|
||||
{
|
||||
return possibleValues.GetValue(0);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static object GenerateQueryable(Type queryableType, int size, Dictionary<Type, object> createdObjectReferences)
|
||||
{
|
||||
bool isGeneric = queryableType.IsGenericType;
|
||||
object list;
|
||||
if (isGeneric)
|
||||
{
|
||||
Type listType = typeof(List<>).MakeGenericType(queryableType.GetGenericArguments());
|
||||
list = GenerateCollection(listType, size, createdObjectReferences);
|
||||
}
|
||||
else
|
||||
{
|
||||
list = GenerateArray(typeof(object[]), size, createdObjectReferences);
|
||||
}
|
||||
if (list == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (isGeneric)
|
||||
{
|
||||
Type argumentType = typeof(IEnumerable<>).MakeGenericType(queryableType.GetGenericArguments());
|
||||
MethodInfo asQueryableMethod = typeof(Queryable).GetMethod("AsQueryable", new[] { argumentType });
|
||||
return asQueryableMethod.Invoke(null, new[] { list });
|
||||
}
|
||||
|
||||
return Queryable.AsQueryable((IEnumerable)list);
|
||||
}
|
||||
|
||||
private static object GenerateCollection(Type collectionType, int size, Dictionary<Type, object> createdObjectReferences)
|
||||
{
|
||||
Type type = collectionType.IsGenericType ?
|
||||
collectionType.GetGenericArguments()[0] :
|
||||
typeof(object);
|
||||
object result = Activator.CreateInstance(collectionType);
|
||||
MethodInfo addMethod = collectionType.GetMethod("Add");
|
||||
bool areAllElementsNull = true;
|
||||
ObjectGenerator objectGenerator = new ObjectGenerator();
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
object element = objectGenerator.GenerateObject(type, createdObjectReferences);
|
||||
addMethod.Invoke(result, new object[] { element });
|
||||
areAllElementsNull &= element == null;
|
||||
}
|
||||
|
||||
if (areAllElementsNull)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static object GenerateNullable(Type nullableType, Dictionary<Type, object> createdObjectReferences)
|
||||
{
|
||||
Type type = nullableType.GetGenericArguments()[0];
|
||||
ObjectGenerator objectGenerator = new ObjectGenerator();
|
||||
return objectGenerator.GenerateObject(type, createdObjectReferences);
|
||||
}
|
||||
|
||||
private static object GenerateComplexObject(Type type, Dictionary<Type, object> createdObjectReferences)
|
||||
{
|
||||
object result = null;
|
||||
|
||||
if (createdObjectReferences.TryGetValue(type, out result))
|
||||
{
|
||||
// The object has been created already, just return it. This will handle the circular reference case.
|
||||
return result;
|
||||
}
|
||||
|
||||
if (type.IsValueType)
|
||||
{
|
||||
result = Activator.CreateInstance(type);
|
||||
}
|
||||
else
|
||||
{
|
||||
ConstructorInfo defaultCtor = type.GetConstructor(Type.EmptyTypes);
|
||||
if (defaultCtor == null)
|
||||
{
|
||||
// Cannot instantiate the type because it doesn't have a default constructor
|
||||
return null;
|
||||
}
|
||||
|
||||
result = defaultCtor.Invoke(new object[0]);
|
||||
}
|
||||
createdObjectReferences.Add(type, result);
|
||||
SetPublicProperties(type, result, createdObjectReferences);
|
||||
SetPublicFields(type, result, createdObjectReferences);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void SetPublicProperties(Type type, object obj, Dictionary<Type, object> createdObjectReferences)
|
||||
{
|
||||
PropertyInfo[] properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
|
||||
ObjectGenerator objectGenerator = new ObjectGenerator();
|
||||
foreach (PropertyInfo property in properties)
|
||||
{
|
||||
if (property.CanWrite)
|
||||
{
|
||||
object propertyValue = objectGenerator.GenerateObject(property.PropertyType, createdObjectReferences);
|
||||
property.SetValue(obj, propertyValue, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetPublicFields(Type type, object obj, Dictionary<Type, object> createdObjectReferences)
|
||||
{
|
||||
FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.Instance);
|
||||
ObjectGenerator objectGenerator = new ObjectGenerator();
|
||||
foreach (FieldInfo field in fields)
|
||||
{
|
||||
object fieldValue = objectGenerator.GenerateObject(field.FieldType, createdObjectReferences);
|
||||
field.SetValue(obj, fieldValue);
|
||||
}
|
||||
}
|
||||
|
||||
private class SimpleTypeObjectGenerator
|
||||
{
|
||||
private long _index = 0;
|
||||
private static readonly Dictionary<Type, Func<long, object>> DefaultGenerators = InitializeGenerators();
|
||||
|
||||
[SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Justification = "These are simple type factories and cannot be split up.")]
|
||||
private static Dictionary<Type, Func<long, object>> InitializeGenerators()
|
||||
{
|
||||
return new Dictionary<Type, Func<long, object>>
|
||||
{
|
||||
{ typeof(Boolean), index => true },
|
||||
{ typeof(Byte), index => (Byte)64 },
|
||||
{ typeof(Char), index => (Char)65 },
|
||||
{ typeof(DateTime), index => DateTime.Now },
|
||||
{ typeof(DateTimeOffset), index => new DateTimeOffset(DateTime.Now) },
|
||||
{ typeof(DBNull), index => DBNull.Value },
|
||||
{ typeof(Decimal), index => (Decimal)index },
|
||||
{ typeof(Double), index => (Double)(index + 0.1) },
|
||||
{ typeof(Guid), index => Guid.NewGuid() },
|
||||
{ typeof(Int16), index => (Int16)(index % Int16.MaxValue) },
|
||||
{ typeof(Int32), index => (Int32)(index % Int32.MaxValue) },
|
||||
{ typeof(Int64), index => (Int64)index },
|
||||
{ typeof(Object), index => new object() },
|
||||
{ typeof(SByte), index => (SByte)64 },
|
||||
{ typeof(Single), index => (Single)(index + 0.1) },
|
||||
{
|
||||
typeof(String), index =>
|
||||
{
|
||||
return String.Format(CultureInfo.CurrentCulture, "sample string {0}", index);
|
||||
}
|
||||
},
|
||||
{
|
||||
typeof(TimeSpan), index =>
|
||||
{
|
||||
return TimeSpan.FromTicks(1234567);
|
||||
}
|
||||
},
|
||||
{ typeof(UInt16), index => (UInt16)(index % UInt16.MaxValue) },
|
||||
{ typeof(UInt32), index => (UInt32)(index % UInt32.MaxValue) },
|
||||
{ typeof(UInt64), index => (UInt64)index },
|
||||
{
|
||||
typeof(Uri), index =>
|
||||
{
|
||||
return new Uri(String.Format(CultureInfo.CurrentCulture, "http://webapihelppage{0}.com", index));
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
public static bool CanGenerateObject(Type type)
|
||||
{
|
||||
return DefaultGenerators.ContainsKey(type);
|
||||
}
|
||||
|
||||
public object GenerateObject(Type type)
|
||||
{
|
||||
return DefaultGenerators[type](++_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
namespace Ewide.Core.WebApi.Areas.HelpPage
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates whether the sample is used for request or response
|
||||
/// </summary>
|
||||
public enum SampleDirection
|
||||
{
|
||||
Request = 0,
|
||||
Response
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
|
||||
namespace Ewide.Core.WebApi.Areas.HelpPage
|
||||
{
|
||||
/// <summary>
|
||||
/// This represents a preformatted text sample on the help page. There's a display template named TextSample associated with this class.
|
||||
/// </summary>
|
||||
public class TextSample
|
||||
{
|
||||
public TextSample(string text)
|
||||
{
|
||||
if (text == null)
|
||||
{
|
||||
throw new ArgumentNullException("text");
|
||||
}
|
||||
Text = text;
|
||||
}
|
||||
|
||||
public string Text { get; private set; }
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
TextSample other = obj as TextSample;
|
||||
return other != null && Text == other.Text;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Text.GetHashCode();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Text;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
@using System.Web.Http
|
||||
@using Ewide.Core.WebApi.Areas.HelpPage.Models
|
||||
@model HelpPageApiModel
|
||||
|
||||
@{
|
||||
var description = Model.ApiDescription;
|
||||
ViewBag.Title = description.HttpMethod.Method + " " + description.RelativePath;
|
||||
}
|
||||
|
||||
<link type="text/css" href="~/Areas/HelpPage/HelpPage.css" rel="stylesheet" />
|
||||
<div id="body" class="help-page">
|
||||
<section class="featured">
|
||||
<div class="content-wrapper">
|
||||
<p>
|
||||
@Html.ActionLink("Help Page Home", "Index")
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
<section class="content-wrapper main-content clear-fix">
|
||||
@Html.DisplayForModel()
|
||||
</section>
|
||||
</div>
|
||||
@@ -0,0 +1,41 @@
|
||||
@using System.Web.Http
|
||||
@using System.Web.Http.Controllers
|
||||
@using System.Web.Http.Description
|
||||
@using Ewide.Core.WebApi.Areas.HelpPage
|
||||
@using Ewide.Core.WebApi.Areas.HelpPage.Models
|
||||
@model IGrouping<HttpControllerDescriptor, ApiDescription>
|
||||
|
||||
@{
|
||||
var controllerDocumentation = ViewBag.DocumentationProvider != null ?
|
||||
ViewBag.DocumentationProvider.GetDocumentation(Model.Key) :
|
||||
null;
|
||||
}
|
||||
|
||||
<h2 id="@Model.Key.ControllerName">@Model.Key.ControllerName</h2>
|
||||
@if (!String.IsNullOrEmpty(controllerDocumentation))
|
||||
{
|
||||
<p>@controllerDocumentation</p>
|
||||
}
|
||||
<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="@Url.Action("Api", "Help", new { 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>
|
||||
@@ -0,0 +1,6 @@
|
||||
@using Ewide.Core.WebApi.Areas.HelpPage.ModelDescriptions
|
||||
@model CollectionModelDescription
|
||||
@if (Model.ElementDescription is ComplexTypeModelDescription)
|
||||
{
|
||||
@Html.DisplayFor(m => m.ElementDescription)
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
@using Ewide.Core.WebApi.Areas.HelpPage.ModelDescriptions
|
||||
@model ComplexTypeModelDescription
|
||||
@Html.DisplayFor(m => m.Properties, "Parameters")
|
||||
@@ -0,0 +1,4 @@
|
||||
@using Ewide.Core.WebApi.Areas.HelpPage.ModelDescriptions
|
||||
@model DictionaryModelDescription
|
||||
Dictionary of @Html.DisplayFor(m => Model.KeyModelDescription.ModelType, "ModelDescriptionLink", new { modelDescription = Model.KeyModelDescription }) [key]
|
||||
and @Html.DisplayFor(m => Model.ValueModelDescription.ModelType, "ModelDescriptionLink", new { modelDescription = Model.ValueModelDescription }) [value]
|
||||
@@ -0,0 +1,24 @@
|
||||
@using Ewide.Core.WebApi.Areas.HelpPage.ModelDescriptions
|
||||
@model EnumTypeModelDescription
|
||||
|
||||
<p>Possible enumeration values:</p>
|
||||
|
||||
<table class="help-page-table">
|
||||
<thead>
|
||||
<tr><th>Name</th><th>Value</th><th>Description</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (EnumValueDescription value in Model.Values)
|
||||
{
|
||||
<tr>
|
||||
<td class="enum-name"><b>@value.Name</b></td>
|
||||
<td class="enum-value">
|
||||
<p>@value.Value</p>
|
||||
</td>
|
||||
<td class="enum-description">
|
||||
<p>@value.Documentation</p>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -0,0 +1,67 @@
|
||||
@using System.Web.Http
|
||||
@using System.Web.Http.Description
|
||||
@using Ewide.Core.WebApi.Areas.HelpPage.Models
|
||||
@using Ewide.Core.WebApi.Areas.HelpPage.ModelDescriptions
|
||||
@model HelpPageApiModel
|
||||
|
||||
@{
|
||||
ApiDescription description = Model.ApiDescription;
|
||||
}
|
||||
<h1>@description.HttpMethod.Method @description.RelativePath</h1>
|
||||
<div>
|
||||
<p>@description.Documentation</p>
|
||||
|
||||
<h2>Request Information</h2>
|
||||
|
||||
<h3>URI Parameters</h3>
|
||||
@Html.DisplayFor(m => m.UriParameters, "Parameters")
|
||||
|
||||
<h3>Body Parameters</h3>
|
||||
|
||||
<p>@Model.RequestDocumentation</p>
|
||||
|
||||
@if (Model.RequestModelDescription != null)
|
||||
{
|
||||
@Html.DisplayFor(m => m.RequestModelDescription.ModelType, "ModelDescriptionLink", new { modelDescription = Model.RequestModelDescription })
|
||||
if (Model.RequestBodyParameters != null)
|
||||
{
|
||||
@Html.DisplayFor(m => m.RequestBodyParameters, "Parameters")
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
<p>None.</p>
|
||||
}
|
||||
|
||||
@if (Model.SampleRequests.Count > 0)
|
||||
{
|
||||
<h3>Request Formats</h3>
|
||||
@Html.DisplayFor(m => m.SampleRequests, "Samples")
|
||||
}
|
||||
|
||||
<h2>Response Information</h2>
|
||||
|
||||
<h3>Resource Description</h3>
|
||||
|
||||
<p>@description.ResponseDescription.Documentation</p>
|
||||
|
||||
@if (Model.ResourceDescription != null)
|
||||
{
|
||||
@Html.DisplayFor(m => m.ResourceDescription.ModelType, "ModelDescriptionLink", new { modelDescription = Model.ResourceDescription })
|
||||
if (Model.ResourceProperties != null)
|
||||
{
|
||||
@Html.DisplayFor(m => m.ResourceProperties, "Parameters")
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
<p>None.</p>
|
||||
}
|
||||
|
||||
@if (Model.SampleResponses.Count > 0)
|
||||
{
|
||||
<h3>Response Formats</h3>
|
||||
@Html.DisplayFor(m => m.SampleResponses, "Samples")
|
||||
}
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,4 @@
|
||||
@using Ewide.Core.WebApi.Areas.HelpPage
|
||||
@model ImageSample
|
||||
|
||||
<img src="@Model.Src" />
|
||||
@@ -0,0 +1,13 @@
|
||||
@using Ewide.Core.WebApi.Areas.HelpPage
|
||||
@model InvalidSample
|
||||
|
||||
@if (HttpContext.Current.IsDebuggingEnabled)
|
||||
{
|
||||
<div class="warning-message-container">
|
||||
<p>@Model.ErrorMessage</p>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<p>Sample not available.</p>
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
@using Ewide.Core.WebApi.Areas.HelpPage.ModelDescriptions
|
||||
@model KeyValuePairModelDescription
|
||||
Pair of @Html.DisplayFor(m => Model.KeyModelDescription.ModelType, "ModelDescriptionLink", new { modelDescription = Model.KeyModelDescription }) [key]
|
||||
and @Html.DisplayFor(m => Model.ValueModelDescription.ModelType, "ModelDescriptionLink", new { modelDescription = Model.ValueModelDescription }) [value]
|
||||
@@ -0,0 +1,26 @@
|
||||
@using Ewide.Core.WebApi.Areas.HelpPage.ModelDescriptions
|
||||
@model Type
|
||||
@{
|
||||
ModelDescription modelDescription = ViewBag.modelDescription;
|
||||
if (modelDescription is ComplexTypeModelDescription || modelDescription is EnumTypeModelDescription)
|
||||
{
|
||||
if (Model == typeof(Object))
|
||||
{
|
||||
@:Object
|
||||
}
|
||||
else
|
||||
{
|
||||
@Html.ActionLink(modelDescription.Name, "ResourceModel", "Help", new { modelName = modelDescription.Name }, null)
|
||||
}
|
||||
}
|
||||
else if (modelDescription is CollectionModelDescription)
|
||||
{
|
||||
var collectionDescription = modelDescription as CollectionModelDescription;
|
||||
var elementDescription = collectionDescription.ElementDescription;
|
||||
@:Collection of @Html.DisplayFor(m => elementDescription.ModelType, "ModelDescriptionLink", new { modelDescription = elementDescription })
|
||||
}
|
||||
else
|
||||
{
|
||||
@Html.DisplayFor(m => modelDescription)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
@using System.Collections.Generic
|
||||
@using System.Collections.ObjectModel
|
||||
@using System.Web.Http.Description
|
||||
@using System.Threading
|
||||
@using Ewide.Core.WebApi.Areas.HelpPage.ModelDescriptions
|
||||
@model IList<ParameterDescription>
|
||||
|
||||
@if (Model.Count > 0)
|
||||
{
|
||||
<table class="help-page-table">
|
||||
<thead>
|
||||
<tr><th>Name</th><th>Description</th><th>Type</th><th>Additional information</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (ParameterDescription parameter in Model)
|
||||
{
|
||||
ModelDescription modelDescription = parameter.TypeDescription;
|
||||
<tr>
|
||||
<td class="parameter-name">@parameter.Name</td>
|
||||
<td class="parameter-documentation">
|
||||
<p>@parameter.Documentation</p>
|
||||
</td>
|
||||
<td class="parameter-type">
|
||||
@Html.DisplayFor(m => modelDescription.ModelType, "ModelDescriptionLink", new { modelDescription = modelDescription })
|
||||
</td>
|
||||
<td class="parameter-annotations">
|
||||
@if (parameter.Annotations.Count > 0)
|
||||
{
|
||||
foreach (var annotation in parameter.Annotations)
|
||||
{
|
||||
<p>@annotation.Documentation</p>
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
<p>None.</p>
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
||||
else
|
||||
{
|
||||
<p>None.</p>
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
@using System.Net.Http.Headers
|
||||
@model Dictionary<MediaTypeHeaderValue, object>
|
||||
|
||||
@{
|
||||
// Group the samples into a single tab if they are the same.
|
||||
Dictionary<string, object> samples = Model.GroupBy(pair => pair.Value).ToDictionary(
|
||||
pair => String.Join(", ", pair.Select(m => m.Key.ToString()).ToArray()),
|
||||
pair => pair.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
|
||||
{
|
||||
@Html.DisplayFor(s => sample);
|
||||
}
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
@@ -0,0 +1,3 @@
|
||||
@using Ewide.Core.WebApi.Areas.HelpPage.ModelDescriptions
|
||||
@model SimpleTypeModelDescription
|
||||
@Model.Documentation
|
||||
@@ -0,0 +1,6 @@
|
||||
@using Ewide.Core.WebApi.Areas.HelpPage
|
||||
@model TextSample
|
||||
|
||||
<pre class="wrapped">
|
||||
@Model.Text
|
||||
</pre>
|
||||
@@ -0,0 +1,38 @@
|
||||
@using System.Web.Http
|
||||
@using System.Web.Http.Controllers
|
||||
@using System.Web.Http.Description
|
||||
@using System.Collections.ObjectModel
|
||||
@using Ewide.Core.WebApi.Areas.HelpPage.Models
|
||||
@model Collection<ApiDescription>
|
||||
|
||||
@{
|
||||
ViewBag.Title = "ASP.NET Web API Help Page";
|
||||
|
||||
// Group APIs by controller
|
||||
ILookup<HttpControllerDescriptor, ApiDescription> apiGroups = Model.ToLookup(api => api.ActionDescriptor.ControllerDescriptor);
|
||||
}
|
||||
|
||||
<link type="text/css" href="~/Areas/HelpPage/HelpPage.css" rel="stylesheet" />
|
||||
<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 (var group in apiGroups)
|
||||
{
|
||||
@Html.DisplayFor(m => group, "ApiGroup")
|
||||
}
|
||||
</section>
|
||||
</div>
|
||||
@@ -0,0 +1,19 @@
|
||||
@using System.Web.Http
|
||||
@using Ewide.Core.WebApi.Areas.HelpPage.ModelDescriptions
|
||||
@model ModelDescription
|
||||
|
||||
<link type="text/css" href="~/Areas/HelpPage/HelpPage.css" rel="stylesheet" />
|
||||
<div id="body" class="help-page">
|
||||
<section class="featured">
|
||||
<div class="content-wrapper">
|
||||
<p>
|
||||
@Html.ActionLink("Help Page Home", "Index")
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
<h1>@Model.Name</h1>
|
||||
<p>@Model.Documentation</p>
|
||||
<section class="content-wrapper main-content clear-fix">
|
||||
@Html.DisplayFor(m => Model)
|
||||
</section>
|
||||
</div>
|
||||
@@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>@ViewBag.Title</title>
|
||||
@RenderSection("scripts", required: false)
|
||||
</head>
|
||||
<body>
|
||||
@RenderBody()
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<configuration>
|
||||
<configSections>
|
||||
<sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
|
||||
<section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
|
||||
<section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
|
||||
</sectionGroup>
|
||||
</configSections>
|
||||
|
||||
<system.web.webPages.razor>
|
||||
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.4.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
|
||||
<pages pageBaseType="System.Web.Mvc.WebViewPage">
|
||||
<namespaces>
|
||||
<add namespace="System.Web.Mvc" />
|
||||
<add namespace="System.Web.Mvc.Ajax" />
|
||||
<add namespace="System.Web.Mvc.Html" />
|
||||
<add namespace="System.Web.Routing" />
|
||||
</namespaces>
|
||||
</pages>
|
||||
</system.web.webPages.razor>
|
||||
|
||||
<appSettings>
|
||||
<add key="webpages:Enabled" value="false" />
|
||||
</appSettings>
|
||||
|
||||
<system.web>
|
||||
<compilation debug="true">
|
||||
<assemblies>
|
||||
<add assembly="System.Net.Http, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
</assemblies>
|
||||
</compilation>
|
||||
</system.web>
|
||||
|
||||
<system.webServer>
|
||||
<handlers>
|
||||
<remove name="BlockViewHandler"/>
|
||||
<add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
|
||||
</handlers>
|
||||
</system.webServer>
|
||||
</configuration>
|
||||
@@ -0,0 +1,4 @@
|
||||
@{
|
||||
// Change the Layout path below to blend the look and feel of the help page with your existing web pages
|
||||
Layout = "~/Views/Shared/_Layout.cshtml";
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Web.Http.Controllers;
|
||||
using System.Web.Http.Description;
|
||||
using System.Xml.XPath;
|
||||
using Ewide.Core.WebApi.Areas.HelpPage.ModelDescriptions;
|
||||
|
||||
namespace Ewide.Core.WebApi.Areas.HelpPage
|
||||
{
|
||||
/// <summary>
|
||||
/// A custom <see cref="IDocumentationProvider"/> that reads the API documentation from an XML documentation file.
|
||||
/// </summary>
|
||||
public class XmlDocumentationProvider : IDocumentationProvider, IModelDocumentationProvider
|
||||
{
|
||||
private XPathNavigator _documentNavigator;
|
||||
private const string TypeExpression = "/doc/members/member[@name='T:{0}']";
|
||||
private const string MethodExpression = "/doc/members/member[@name='M:{0}']";
|
||||
private const string PropertyExpression = "/doc/members/member[@name='P:{0}']";
|
||||
private const string FieldExpression = "/doc/members/member[@name='F:{0}']";
|
||||
private const string ParameterExpression = "param[@name='{0}']";
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="XmlDocumentationProvider"/> class.
|
||||
/// </summary>
|
||||
/// <param name="documentPath">The physical path to XML document.</param>
|
||||
public XmlDocumentationProvider(string documentPath)
|
||||
{
|
||||
if (documentPath == null)
|
||||
{
|
||||
throw new ArgumentNullException("documentPath");
|
||||
}
|
||||
XPathDocument xpath = new XPathDocument(documentPath);
|
||||
_documentNavigator = xpath.CreateNavigator();
|
||||
}
|
||||
|
||||
public string GetDocumentation(HttpControllerDescriptor controllerDescriptor)
|
||||
{
|
||||
XPathNavigator typeNode = GetTypeNode(controllerDescriptor.ControllerType);
|
||||
return GetTagValue(typeNode, "summary");
|
||||
}
|
||||
|
||||
public virtual string GetDocumentation(HttpActionDescriptor actionDescriptor)
|
||||
{
|
||||
XPathNavigator methodNode = GetMethodNode(actionDescriptor);
|
||||
return GetTagValue(methodNode, "summary");
|
||||
}
|
||||
|
||||
public virtual string GetDocumentation(HttpParameterDescriptor parameterDescriptor)
|
||||
{
|
||||
ReflectedHttpParameterDescriptor reflectedParameterDescriptor = parameterDescriptor as ReflectedHttpParameterDescriptor;
|
||||
if (reflectedParameterDescriptor != null)
|
||||
{
|
||||
XPathNavigator methodNode = GetMethodNode(reflectedParameterDescriptor.ActionDescriptor);
|
||||
if (methodNode != null)
|
||||
{
|
||||
string parameterName = reflectedParameterDescriptor.ParameterInfo.Name;
|
||||
XPathNavigator parameterNode = methodNode.SelectSingleNode(String.Format(CultureInfo.InvariantCulture, ParameterExpression, parameterName));
|
||||
if (parameterNode != null)
|
||||
{
|
||||
return parameterNode.Value.Trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public string GetResponseDocumentation(HttpActionDescriptor actionDescriptor)
|
||||
{
|
||||
XPathNavigator methodNode = GetMethodNode(actionDescriptor);
|
||||
return GetTagValue(methodNode, "returns");
|
||||
}
|
||||
|
||||
public string GetDocumentation(MemberInfo member)
|
||||
{
|
||||
string memberName = String.Format(CultureInfo.InvariantCulture, "{0}.{1}", GetTypeName(member.DeclaringType), member.Name);
|
||||
string expression = member.MemberType == MemberTypes.Field ? FieldExpression : PropertyExpression;
|
||||
string selectExpression = String.Format(CultureInfo.InvariantCulture, expression, memberName);
|
||||
XPathNavigator propertyNode = _documentNavigator.SelectSingleNode(selectExpression);
|
||||
return GetTagValue(propertyNode, "summary");
|
||||
}
|
||||
|
||||
public string GetDocumentation(Type type)
|
||||
{
|
||||
XPathNavigator typeNode = GetTypeNode(type);
|
||||
return GetTagValue(typeNode, "summary");
|
||||
}
|
||||
|
||||
private XPathNavigator GetMethodNode(HttpActionDescriptor actionDescriptor)
|
||||
{
|
||||
ReflectedHttpActionDescriptor reflectedActionDescriptor = actionDescriptor as ReflectedHttpActionDescriptor;
|
||||
if (reflectedActionDescriptor != null)
|
||||
{
|
||||
string selectExpression = String.Format(CultureInfo.InvariantCulture, MethodExpression, GetMemberName(reflectedActionDescriptor.MethodInfo));
|
||||
return _documentNavigator.SelectSingleNode(selectExpression);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static string GetMemberName(MethodInfo method)
|
||||
{
|
||||
string name = String.Format(CultureInfo.InvariantCulture, "{0}.{1}", GetTypeName(method.DeclaringType), method.Name);
|
||||
ParameterInfo[] parameters = method.GetParameters();
|
||||
if (parameters.Length != 0)
|
||||
{
|
||||
string[] parameterTypeNames = parameters.Select(param => GetTypeName(param.ParameterType)).ToArray();
|
||||
name += String.Format(CultureInfo.InvariantCulture, "({0})", String.Join(",", parameterTypeNames));
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
private static string GetTagValue(XPathNavigator parentNode, string tagName)
|
||||
{
|
||||
if (parentNode != null)
|
||||
{
|
||||
XPathNavigator node = parentNode.SelectSingleNode(tagName);
|
||||
if (node != null)
|
||||
{
|
||||
return node.Value.Trim();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private XPathNavigator GetTypeNode(Type type)
|
||||
{
|
||||
string controllerTypeName = GetTypeName(type);
|
||||
string selectExpression = String.Format(CultureInfo.InvariantCulture, TypeExpression, controllerTypeName);
|
||||
return _documentNavigator.SelectSingleNode(selectExpression);
|
||||
}
|
||||
|
||||
private static string GetTypeName(Type type)
|
||||
{
|
||||
string name = type.FullName;
|
||||
if (type.IsGenericType)
|
||||
{
|
||||
// Format the generic type name to something like: Generic{System.Int32,System.String}
|
||||
Type genericType = type.GetGenericTypeDefinition();
|
||||
Type[] genericArguments = type.GetGenericArguments();
|
||||
string genericTypeName = genericType.FullName;
|
||||
|
||||
// Trim the generic parameter counts from the name
|
||||
genericTypeName = genericTypeName.Substring(0, genericTypeName.IndexOf('`'));
|
||||
string[] argumentTypeNames = genericArguments.Select(t => GetTypeName(t)).ToArray();
|
||||
name = String.Format(CultureInfo.InvariantCulture, "{0}{{{1}}}", genericTypeName, String.Join(",", argumentTypeNames));
|
||||
}
|
||||
if (type.IsNested)
|
||||
{
|
||||
// Changing the nested type name from OuterType+InnerType to OuterType.InnerType to match the XML documentation syntax.
|
||||
name = name.Replace("+", ".");
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using System.Web.Mvc;
|
||||
|
||||
namespace Ewide.Core.WebApi.Areas.Manage
|
||||
{
|
||||
public class ManageAreaRegistration : AreaRegistration
|
||||
{
|
||||
public override string AreaName
|
||||
{
|
||||
get
|
||||
{
|
||||
return "Manage";
|
||||
}
|
||||
}
|
||||
|
||||
public override void RegisterArea(AreaRegistrationContext context)
|
||||
{
|
||||
context.MapRoute(
|
||||
"Manage_default",
|
||||
"Manage/{controller}/{action}/{id}",
|
||||
new { action = "Index", id = UrlParameter.Optional }
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<configuration>
|
||||
<configSections>
|
||||
<sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
|
||||
<section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
|
||||
<section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
|
||||
</sectionGroup>
|
||||
</configSections>
|
||||
|
||||
<system.web.webPages.razor>
|
||||
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.4.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
|
||||
<pages pageBaseType="System.Web.Mvc.WebViewPage">
|
||||
<namespaces>
|
||||
<add namespace="System.Web.Mvc" />
|
||||
<add namespace="System.Web.Mvc.Ajax" />
|
||||
<add namespace="System.Web.Mvc.Html" />
|
||||
<add namespace="System.Web.Routing" />
|
||||
<add namespace="System.Web.Optimization" />
|
||||
<add namespace="Ewide.Core.WebApi" />
|
||||
|
||||
</namespaces>
|
||||
</pages>
|
||||
</system.web.webPages.razor>
|
||||
|
||||
<appSettings>
|
||||
<add key="webpages:Enabled" value="false" />
|
||||
</appSettings>
|
||||
|
||||
<system.webServer>
|
||||
<handlers>
|
||||
<remove name="BlockViewHandler"/>
|
||||
<add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
|
||||
</handlers>
|
||||
</system.webServer>
|
||||
</configuration>
|
||||
17
Api/Ewide.Core/Ewide.Core.WebApi/Content/Site.css
Normal file
17
Api/Ewide.Core/Ewide.Core.WebApi/Content/Site.css
Normal file
@@ -0,0 +1,17 @@
|
||||
body {
|
||||
padding-top: 50px;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
/* Set padding to keep content from hitting the edges */
|
||||
.body-content {
|
||||
padding-left: 15px;
|
||||
padding-right: 15px;
|
||||
}
|
||||
|
||||
/* Set width on the form input elements since they're 100% wide by default */
|
||||
input,
|
||||
select,
|
||||
textarea {
|
||||
max-width: 280px;
|
||||
}
|
||||
587
Api/Ewide.Core/Ewide.Core.WebApi/Content/bootstrap-theme.css
vendored
Normal file
587
Api/Ewide.Core/Ewide.Core.WebApi/Content/bootstrap-theme.css
vendored
Normal file
@@ -0,0 +1,587 @@
|
||||
/*!
|
||||
* Bootstrap v3.3.7 (http://getbootstrap.com)
|
||||
* Copyright 2011-2016 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
*/
|
||||
.btn-default,
|
||||
.btn-primary,
|
||||
.btn-success,
|
||||
.btn-info,
|
||||
.btn-warning,
|
||||
.btn-danger {
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, .2);
|
||||
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075);
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075);
|
||||
}
|
||||
.btn-default:active,
|
||||
.btn-primary:active,
|
||||
.btn-success:active,
|
||||
.btn-info:active,
|
||||
.btn-warning:active,
|
||||
.btn-danger:active,
|
||||
.btn-default.active,
|
||||
.btn-primary.active,
|
||||
.btn-success.active,
|
||||
.btn-info.active,
|
||||
.btn-warning.active,
|
||||
.btn-danger.active {
|
||||
-webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
|
||||
box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
|
||||
}
|
||||
.btn-default.disabled,
|
||||
.btn-primary.disabled,
|
||||
.btn-success.disabled,
|
||||
.btn-info.disabled,
|
||||
.btn-warning.disabled,
|
||||
.btn-danger.disabled,
|
||||
.btn-default[disabled],
|
||||
.btn-primary[disabled],
|
||||
.btn-success[disabled],
|
||||
.btn-info[disabled],
|
||||
.btn-warning[disabled],
|
||||
.btn-danger[disabled],
|
||||
fieldset[disabled] .btn-default,
|
||||
fieldset[disabled] .btn-primary,
|
||||
fieldset[disabled] .btn-success,
|
||||
fieldset[disabled] .btn-info,
|
||||
fieldset[disabled] .btn-warning,
|
||||
fieldset[disabled] .btn-danger {
|
||||
-webkit-box-shadow: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
.btn-default .badge,
|
||||
.btn-primary .badge,
|
||||
.btn-success .badge,
|
||||
.btn-info .badge,
|
||||
.btn-warning .badge,
|
||||
.btn-danger .badge {
|
||||
text-shadow: none;
|
||||
}
|
||||
.btn:active,
|
||||
.btn.active {
|
||||
background-image: none;
|
||||
}
|
||||
.btn-default {
|
||||
text-shadow: 0 1px 0 #fff;
|
||||
background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%);
|
||||
background-image: -o-linear-gradient(top, #fff 0%, #e0e0e0 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#e0e0e0));
|
||||
background-image: linear-gradient(to bottom, #fff 0%, #e0e0e0 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #dbdbdb;
|
||||
border-color: #ccc;
|
||||
}
|
||||
.btn-default:hover,
|
||||
.btn-default:focus {
|
||||
background-color: #e0e0e0;
|
||||
background-position: 0 -15px;
|
||||
}
|
||||
.btn-default:active,
|
||||
.btn-default.active {
|
||||
background-color: #e0e0e0;
|
||||
border-color: #dbdbdb;
|
||||
}
|
||||
.btn-default.disabled,
|
||||
.btn-default[disabled],
|
||||
fieldset[disabled] .btn-default,
|
||||
.btn-default.disabled:hover,
|
||||
.btn-default[disabled]:hover,
|
||||
fieldset[disabled] .btn-default:hover,
|
||||
.btn-default.disabled:focus,
|
||||
.btn-default[disabled]:focus,
|
||||
fieldset[disabled] .btn-default:focus,
|
||||
.btn-default.disabled.focus,
|
||||
.btn-default[disabled].focus,
|
||||
fieldset[disabled] .btn-default.focus,
|
||||
.btn-default.disabled:active,
|
||||
.btn-default[disabled]:active,
|
||||
fieldset[disabled] .btn-default:active,
|
||||
.btn-default.disabled.active,
|
||||
.btn-default[disabled].active,
|
||||
fieldset[disabled] .btn-default.active {
|
||||
background-color: #e0e0e0;
|
||||
background-image: none;
|
||||
}
|
||||
.btn-primary {
|
||||
background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%);
|
||||
background-image: -o-linear-gradient(top, #337ab7 0%, #265a88 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#265a88));
|
||||
background-image: linear-gradient(to bottom, #337ab7 0%, #265a88 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #245580;
|
||||
}
|
||||
.btn-primary:hover,
|
||||
.btn-primary:focus {
|
||||
background-color: #265a88;
|
||||
background-position: 0 -15px;
|
||||
}
|
||||
.btn-primary:active,
|
||||
.btn-primary.active {
|
||||
background-color: #265a88;
|
||||
border-color: #245580;
|
||||
}
|
||||
.btn-primary.disabled,
|
||||
.btn-primary[disabled],
|
||||
fieldset[disabled] .btn-primary,
|
||||
.btn-primary.disabled:hover,
|
||||
.btn-primary[disabled]:hover,
|
||||
fieldset[disabled] .btn-primary:hover,
|
||||
.btn-primary.disabled:focus,
|
||||
.btn-primary[disabled]:focus,
|
||||
fieldset[disabled] .btn-primary:focus,
|
||||
.btn-primary.disabled.focus,
|
||||
.btn-primary[disabled].focus,
|
||||
fieldset[disabled] .btn-primary.focus,
|
||||
.btn-primary.disabled:active,
|
||||
.btn-primary[disabled]:active,
|
||||
fieldset[disabled] .btn-primary:active,
|
||||
.btn-primary.disabled.active,
|
||||
.btn-primary[disabled].active,
|
||||
fieldset[disabled] .btn-primary.active {
|
||||
background-color: #265a88;
|
||||
background-image: none;
|
||||
}
|
||||
.btn-success {
|
||||
background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%);
|
||||
background-image: -o-linear-gradient(top, #5cb85c 0%, #419641 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#419641));
|
||||
background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #3e8f3e;
|
||||
}
|
||||
.btn-success:hover,
|
||||
.btn-success:focus {
|
||||
background-color: #419641;
|
||||
background-position: 0 -15px;
|
||||
}
|
||||
.btn-success:active,
|
||||
.btn-success.active {
|
||||
background-color: #419641;
|
||||
border-color: #3e8f3e;
|
||||
}
|
||||
.btn-success.disabled,
|
||||
.btn-success[disabled],
|
||||
fieldset[disabled] .btn-success,
|
||||
.btn-success.disabled:hover,
|
||||
.btn-success[disabled]:hover,
|
||||
fieldset[disabled] .btn-success:hover,
|
||||
.btn-success.disabled:focus,
|
||||
.btn-success[disabled]:focus,
|
||||
fieldset[disabled] .btn-success:focus,
|
||||
.btn-success.disabled.focus,
|
||||
.btn-success[disabled].focus,
|
||||
fieldset[disabled] .btn-success.focus,
|
||||
.btn-success.disabled:active,
|
||||
.btn-success[disabled]:active,
|
||||
fieldset[disabled] .btn-success:active,
|
||||
.btn-success.disabled.active,
|
||||
.btn-success[disabled].active,
|
||||
fieldset[disabled] .btn-success.active {
|
||||
background-color: #419641;
|
||||
background-image: none;
|
||||
}
|
||||
.btn-info {
|
||||
background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);
|
||||
background-image: -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#2aabd2));
|
||||
background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #28a4c9;
|
||||
}
|
||||
.btn-info:hover,
|
||||
.btn-info:focus {
|
||||
background-color: #2aabd2;
|
||||
background-position: 0 -15px;
|
||||
}
|
||||
.btn-info:active,
|
||||
.btn-info.active {
|
||||
background-color: #2aabd2;
|
||||
border-color: #28a4c9;
|
||||
}
|
||||
.btn-info.disabled,
|
||||
.btn-info[disabled],
|
||||
fieldset[disabled] .btn-info,
|
||||
.btn-info.disabled:hover,
|
||||
.btn-info[disabled]:hover,
|
||||
fieldset[disabled] .btn-info:hover,
|
||||
.btn-info.disabled:focus,
|
||||
.btn-info[disabled]:focus,
|
||||
fieldset[disabled] .btn-info:focus,
|
||||
.btn-info.disabled.focus,
|
||||
.btn-info[disabled].focus,
|
||||
fieldset[disabled] .btn-info.focus,
|
||||
.btn-info.disabled:active,
|
||||
.btn-info[disabled]:active,
|
||||
fieldset[disabled] .btn-info:active,
|
||||
.btn-info.disabled.active,
|
||||
.btn-info[disabled].active,
|
||||
fieldset[disabled] .btn-info.active {
|
||||
background-color: #2aabd2;
|
||||
background-image: none;
|
||||
}
|
||||
.btn-warning {
|
||||
background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);
|
||||
background-image: -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#eb9316));
|
||||
background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #e38d13;
|
||||
}
|
||||
.btn-warning:hover,
|
||||
.btn-warning:focus {
|
||||
background-color: #eb9316;
|
||||
background-position: 0 -15px;
|
||||
}
|
||||
.btn-warning:active,
|
||||
.btn-warning.active {
|
||||
background-color: #eb9316;
|
||||
border-color: #e38d13;
|
||||
}
|
||||
.btn-warning.disabled,
|
||||
.btn-warning[disabled],
|
||||
fieldset[disabled] .btn-warning,
|
||||
.btn-warning.disabled:hover,
|
||||
.btn-warning[disabled]:hover,
|
||||
fieldset[disabled] .btn-warning:hover,
|
||||
.btn-warning.disabled:focus,
|
||||
.btn-warning[disabled]:focus,
|
||||
fieldset[disabled] .btn-warning:focus,
|
||||
.btn-warning.disabled.focus,
|
||||
.btn-warning[disabled].focus,
|
||||
fieldset[disabled] .btn-warning.focus,
|
||||
.btn-warning.disabled:active,
|
||||
.btn-warning[disabled]:active,
|
||||
fieldset[disabled] .btn-warning:active,
|
||||
.btn-warning.disabled.active,
|
||||
.btn-warning[disabled].active,
|
||||
fieldset[disabled] .btn-warning.active {
|
||||
background-color: #eb9316;
|
||||
background-image: none;
|
||||
}
|
||||
.btn-danger {
|
||||
background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%);
|
||||
background-image: -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c12e2a));
|
||||
background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #b92c28;
|
||||
}
|
||||
.btn-danger:hover,
|
||||
.btn-danger:focus {
|
||||
background-color: #c12e2a;
|
||||
background-position: 0 -15px;
|
||||
}
|
||||
.btn-danger:active,
|
||||
.btn-danger.active {
|
||||
background-color: #c12e2a;
|
||||
border-color: #b92c28;
|
||||
}
|
||||
.btn-danger.disabled,
|
||||
.btn-danger[disabled],
|
||||
fieldset[disabled] .btn-danger,
|
||||
.btn-danger.disabled:hover,
|
||||
.btn-danger[disabled]:hover,
|
||||
fieldset[disabled] .btn-danger:hover,
|
||||
.btn-danger.disabled:focus,
|
||||
.btn-danger[disabled]:focus,
|
||||
fieldset[disabled] .btn-danger:focus,
|
||||
.btn-danger.disabled.focus,
|
||||
.btn-danger[disabled].focus,
|
||||
fieldset[disabled] .btn-danger.focus,
|
||||
.btn-danger.disabled:active,
|
||||
.btn-danger[disabled]:active,
|
||||
fieldset[disabled] .btn-danger:active,
|
||||
.btn-danger.disabled.active,
|
||||
.btn-danger[disabled].active,
|
||||
fieldset[disabled] .btn-danger.active {
|
||||
background-color: #c12e2a;
|
||||
background-image: none;
|
||||
}
|
||||
.thumbnail,
|
||||
.img-thumbnail {
|
||||
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
|
||||
}
|
||||
.dropdown-menu > li > a:hover,
|
||||
.dropdown-menu > li > a:focus {
|
||||
background-color: #e8e8e8;
|
||||
background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
|
||||
background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8));
|
||||
background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.dropdown-menu > .active > a,
|
||||
.dropdown-menu > .active > a:hover,
|
||||
.dropdown-menu > .active > a:focus {
|
||||
background-color: #2e6da4;
|
||||
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
|
||||
background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
|
||||
background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.navbar-default {
|
||||
background-image: -webkit-linear-gradient(top, #fff 0%, #f8f8f8 100%);
|
||||
background-image: -o-linear-gradient(top, #fff 0%, #f8f8f8 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#f8f8f8));
|
||||
background-image: linear-gradient(to bottom, #fff 0%, #f8f8f8 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
background-repeat: repeat-x;
|
||||
border-radius: 4px;
|
||||
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075);
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075);
|
||||
}
|
||||
.navbar-default .navbar-nav > .open > a,
|
||||
.navbar-default .navbar-nav > .active > a {
|
||||
background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);
|
||||
background-image: -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#dbdbdb), to(#e2e2e2));
|
||||
background-image: linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
-webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075);
|
||||
box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075);
|
||||
}
|
||||
.navbar-brand,
|
||||
.navbar-nav > li > a {
|
||||
text-shadow: 0 1px 0 rgba(255, 255, 255, .25);
|
||||
}
|
||||
.navbar-inverse {
|
||||
background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%);
|
||||
background-image: -o-linear-gradient(top, #3c3c3c 0%, #222 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#3c3c3c), to(#222));
|
||||
background-image: linear-gradient(to bottom, #3c3c3c 0%, #222 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
background-repeat: repeat-x;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.navbar-inverse .navbar-nav > .open > a,
|
||||
.navbar-inverse .navbar-nav > .active > a {
|
||||
background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%);
|
||||
background-image: -o-linear-gradient(top, #080808 0%, #0f0f0f 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#080808), to(#0f0f0f));
|
||||
background-image: linear-gradient(to bottom, #080808 0%, #0f0f0f 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
-webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25);
|
||||
box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25);
|
||||
}
|
||||
.navbar-inverse .navbar-brand,
|
||||
.navbar-inverse .navbar-nav > li > a {
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, .25);
|
||||
}
|
||||
.navbar-static-top,
|
||||
.navbar-fixed-top,
|
||||
.navbar-fixed-bottom {
|
||||
border-radius: 0;
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
.navbar .navbar-nav .open .dropdown-menu > .active > a,
|
||||
.navbar .navbar-nav .open .dropdown-menu > .active > a:hover,
|
||||
.navbar .navbar-nav .open .dropdown-menu > .active > a:focus {
|
||||
color: #fff;
|
||||
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
|
||||
background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
|
||||
background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
}
|
||||
.alert {
|
||||
text-shadow: 0 1px 0 rgba(255, 255, 255, .2);
|
||||
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05);
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05);
|
||||
}
|
||||
.alert-success {
|
||||
background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);
|
||||
background-image: -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#c8e5bc));
|
||||
background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #b2dba1;
|
||||
}
|
||||
.alert-info {
|
||||
background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%);
|
||||
background-image: -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#b9def0));
|
||||
background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #9acfea;
|
||||
}
|
||||
.alert-warning {
|
||||
background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);
|
||||
background-image: -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#f8efc0));
|
||||
background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #f5e79e;
|
||||
}
|
||||
.alert-danger {
|
||||
background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);
|
||||
background-image: -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#e7c3c3));
|
||||
background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #dca7a7;
|
||||
}
|
||||
.progress {
|
||||
background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);
|
||||
background-image: -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#ebebeb), to(#f5f5f5));
|
||||
background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.progress-bar {
|
||||
background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%);
|
||||
background-image: -o-linear-gradient(top, #337ab7 0%, #286090 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#286090));
|
||||
background-image: linear-gradient(to bottom, #337ab7 0%, #286090 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.progress-bar-success {
|
||||
background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%);
|
||||
background-image: -o-linear-gradient(top, #5cb85c 0%, #449d44 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#449d44));
|
||||
background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.progress-bar-info {
|
||||
background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);
|
||||
background-image: -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#31b0d5));
|
||||
background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.progress-bar-warning {
|
||||
background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);
|
||||
background-image: -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#ec971f));
|
||||
background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.progress-bar-danger {
|
||||
background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%);
|
||||
background-image: -o-linear-gradient(top, #d9534f 0%, #c9302c 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c9302c));
|
||||
background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.progress-bar-striped {
|
||||
background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
|
||||
background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
|
||||
background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
|
||||
}
|
||||
.list-group {
|
||||
border-radius: 4px;
|
||||
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
|
||||
}
|
||||
.list-group-item.active,
|
||||
.list-group-item.active:hover,
|
||||
.list-group-item.active:focus {
|
||||
text-shadow: 0 -1px 0 #286090;
|
||||
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%);
|
||||
background-image: -o-linear-gradient(top, #337ab7 0%, #2b669a 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2b669a));
|
||||
background-image: linear-gradient(to bottom, #337ab7 0%, #2b669a 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #2b669a;
|
||||
}
|
||||
.list-group-item.active .badge,
|
||||
.list-group-item.active:hover .badge,
|
||||
.list-group-item.active:focus .badge {
|
||||
text-shadow: none;
|
||||
}
|
||||
.panel {
|
||||
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
|
||||
}
|
||||
.panel-default > .panel-heading {
|
||||
background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
|
||||
background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8));
|
||||
background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.panel-primary > .panel-heading {
|
||||
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
|
||||
background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
|
||||
background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.panel-success > .panel-heading {
|
||||
background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);
|
||||
background-image: -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#d0e9c6));
|
||||
background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.panel-info > .panel-heading {
|
||||
background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);
|
||||
background-image: -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#c4e3f3));
|
||||
background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.panel-warning > .panel-heading {
|
||||
background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);
|
||||
background-image: -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#faf2cc));
|
||||
background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.panel-danger > .panel-heading {
|
||||
background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%);
|
||||
background-image: -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#ebcccc));
|
||||
background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.well {
|
||||
background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);
|
||||
background-image: -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#e8e8e8), to(#f5f5f5));
|
||||
background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #dcdcdc;
|
||||
-webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1);
|
||||
box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1);
|
||||
}
|
||||
/*# sourceMappingURL=bootstrap-theme.css.map */
|
||||
File diff suppressed because one or more lines are too long
6
Api/Ewide.Core/Ewide.Core.WebApi/Content/bootstrap-theme.min.css
vendored
Normal file
6
Api/Ewide.Core/Ewide.Core.WebApi/Content/bootstrap-theme.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
6757
Api/Ewide.Core/Ewide.Core.WebApi/Content/bootstrap.css
vendored
Normal file
6757
Api/Ewide.Core/Ewide.Core.WebApi/Content/bootstrap.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
6
Api/Ewide.Core/Ewide.Core.WebApi/Content/bootstrap.min.css
vendored
Normal file
6
Api/Ewide.Core/Ewide.Core.WebApi/Content/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Web.Http;
|
||||
|
||||
namespace Ewide.Core.WebApi
|
||||
{
|
||||
public class ApiAuthorizeAttribute : AuthorizeAttribute
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Web.Http;
|
||||
using System.Web.Http.Controllers;
|
||||
using System.Web.Http.Results;
|
||||
using Ewide.Core.Common;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Ewide.Core.WebApi
|
||||
{
|
||||
public class BaseController : ApiController
|
||||
{
|
||||
protected override void Initialize(HttpControllerContext controllerContext)
|
||||
{
|
||||
base.Initialize(controllerContext);
|
||||
}
|
||||
|
||||
protected override ExceptionResult InternalServerError(Exception exception)
|
||||
{
|
||||
return base.InternalServerError(exception);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 序列化为JSON并返回
|
||||
/// </summary>
|
||||
/// <param name="obj"></param>
|
||||
/// <returns></returns>
|
||||
private IHttpActionResult _DisplayJSON(object obj)
|
||||
{
|
||||
var _result = JsonConvert.SerializeObject(obj, Formatting.Indented, new JsonSerializerSettings
|
||||
{
|
||||
ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver(),
|
||||
DateFormatString = "yyyy-MM-dd HH:mm:ss"
|
||||
});
|
||||
|
||||
var result = JsonConvert.DeserializeObject(_result);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 返回自定义格式的JSON,并标注接口是否调用成功
|
||||
/// </summary>
|
||||
/// <param name="code"></param>
|
||||
/// <param name="result"></param>
|
||||
/// <returns></returns>
|
||||
protected IHttpActionResult DisplayJSON(object result)
|
||||
{
|
||||
return _DisplayJSON(BaseDisplayJSON.Ok(result));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 返回文字信息,并标注接口是否调用成功
|
||||
/// </summary>
|
||||
/// <param name="code"></param>
|
||||
/// <param name="message"></param>
|
||||
/// <returns></returns>
|
||||
protected IHttpActionResult DisplayJSON(string message)
|
||||
{
|
||||
return _DisplayJSON(BaseDisplayJSON.Ok(message));
|
||||
}
|
||||
|
||||
protected IHttpActionResult DisplayDataJSON(object data, int total)
|
||||
{
|
||||
return _DisplayJSON(BaseDisplayJSON.Ok(new
|
||||
{
|
||||
Data = data,
|
||||
Total = total
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.Mvc;
|
||||
|
||||
namespace Ewide.Core.WebApi.Controllers
|
||||
{
|
||||
public class HomeController : Controller
|
||||
{
|
||||
public ActionResult Index()
|
||||
{
|
||||
ViewBag.Title = "Home Page";
|
||||
|
||||
return View();
|
||||
}
|
||||
}
|
||||
}
|
||||
310
Api/Ewide.Core/Ewide.Core.WebApi/Ewide.Core.WebApi.csproj
Normal file
310
Api/Ewide.Core/Ewide.Core.WebApi/Ewide.Core.WebApi.csproj
Normal file
@@ -0,0 +1,310 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.0\build\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props" Condition="Exists('..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.0\build\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props')" />
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>
|
||||
</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{328B697C-0A23-4F33-95AB-090476D21BF5}</ProjectGuid>
|
||||
<ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Ewide.Core.WebApi</RootNamespace>
|
||||
<AssemblyName>Ewide.Core.WebApi</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<MvcBuildViews>false</MvcBuildViews>
|
||||
<UseIISExpress>true</UseIISExpress>
|
||||
<Use64BitIISExpress />
|
||||
<IISExpressSSLPort />
|
||||
<IISExpressAnonymousAuthentication />
|
||||
<IISExpressWindowsAuthentication />
|
||||
<IISExpressUseClassicPipelineMode />
|
||||
<UseGlobalApplicationHostFile />
|
||||
<NuGetPackageImportStamp>
|
||||
</NuGetPackageImportStamp>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Web.Entity" />
|
||||
<Reference Include="System.Web.ApplicationServices" />
|
||||
<Reference Include="System.ComponentModel.DataAnnotations" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Web" />
|
||||
<Reference Include="System.Web.Abstractions" />
|
||||
<Reference Include="System.Web.Routing" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System.Configuration" />
|
||||
<Reference Include="System.Runtime.Serialization" />
|
||||
<Reference Include="Microsoft.Web.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<Private>True</Private>
|
||||
<HintPath>..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json">
|
||||
<HintPath>..\packages\Newtonsoft.Json.11.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Http">
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Http.Formatting, Version=5.2.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.AspNet.WebApi.Client.5.2.4\lib\net45\System.Net.Http.Formatting.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Http.WebRequest">
|
||||
</Reference>
|
||||
<Reference Include="System.Web.Helpers, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<Private>True</Private>
|
||||
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.4\lib\net45\System.Web.Helpers.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Web.Http, Version=5.2.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.AspNet.WebApi.Core.5.2.4\lib\net45\System.Web.Http.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Web.Http.WebHost, Version=5.2.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.AspNet.WebApi.WebHost.5.2.4\lib\net45\System.Web.Http.WebHost.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Web.Mvc, Version=5.2.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<Private>True</Private>
|
||||
<HintPath>..\packages\Microsoft.AspNet.Mvc.5.2.4\lib\net45\System.Web.Mvc.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Web.Optimization">
|
||||
<HintPath>..\packages\Microsoft.AspNet.Web.Optimization.1.1.3\lib\net40\System.Web.Optimization.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Web.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<Private>True</Private>
|
||||
<HintPath>..\packages\Microsoft.AspNet.Razor.3.2.4\lib\net45\System.Web.Razor.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Web.WebPages, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<Private>True</Private>
|
||||
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.4\lib\net45\System.Web.WebPages.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Web.WebPages.Deployment, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<Private>True</Private>
|
||||
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.4\lib\net45\System.Web.WebPages.Deployment.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<Private>True</Private>
|
||||
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.4\lib\net45\System.Web.WebPages.Razor.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="WebGrease">
|
||||
<Private>True</Private>
|
||||
<HintPath>..\packages\WebGrease.1.6.0\lib\WebGrease.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Antlr3.Runtime">
|
||||
<Private>True</Private>
|
||||
<HintPath>..\packages\Antlr.3.5.0.2\lib\Antlr3.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.CodeDom.Providers.DotNetCompilerPlatform">
|
||||
<HintPath>..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.0\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="App_Start\BundleConfig.cs" />
|
||||
<Compile Include="App_Start\FilterConfig.cs" />
|
||||
<Compile Include="App_Start\Filters\HttpNotFoundControllerActionSelector.cs" />
|
||||
<Compile Include="App_Start\Filters\HttpNotFoundDefaultHttpControllerSelector.cs" />
|
||||
<Compile Include="App_Start\Filters\HttpWebApiControllerActionInvoker.cs" />
|
||||
<Compile Include="App_Start\RouteConfig.cs" />
|
||||
<Compile Include="App_Start\WebApiConfig.cs" />
|
||||
<Compile Include="Areas\Gate\Controllers\LoginController.cs" />
|
||||
<Compile Include="Areas\Gate\GateAreaRegistration.cs" />
|
||||
<Compile Include="Areas\HelpPage\ApiDescriptionExtensions.cs" />
|
||||
<Compile Include="Areas\HelpPage\App_Start\HelpPageConfig.cs" />
|
||||
<Compile Include="Areas\HelpPage\Controllers\HelpController.cs" />
|
||||
<Compile Include="Areas\HelpPage\HelpPageAreaRegistration.cs" />
|
||||
<Compile Include="Areas\HelpPage\HelpPageConfigurationExtensions.cs" />
|
||||
<Compile Include="Areas\HelpPage\ModelDescriptions\CollectionModelDescription.cs" />
|
||||
<Compile Include="Areas\HelpPage\ModelDescriptions\ComplexTypeModelDescription.cs" />
|
||||
<Compile Include="Areas\HelpPage\ModelDescriptions\DictionaryModelDescription.cs" />
|
||||
<Compile Include="Areas\HelpPage\ModelDescriptions\EnumTypeModelDescription.cs" />
|
||||
<Compile Include="Areas\HelpPage\ModelDescriptions\EnumValueDescription.cs" />
|
||||
<Compile Include="Areas\HelpPage\ModelDescriptions\IModelDocumentationProvider.cs" />
|
||||
<Compile Include="Areas\HelpPage\ModelDescriptions\KeyValuePairModelDescription.cs" />
|
||||
<Compile Include="Areas\HelpPage\ModelDescriptions\ModelDescription.cs" />
|
||||
<Compile Include="Areas\HelpPage\ModelDescriptions\ModelDescriptionGenerator.cs" />
|
||||
<Compile Include="Areas\HelpPage\ModelDescriptions\ModelNameAttribute.cs" />
|
||||
<Compile Include="Areas\HelpPage\ModelDescriptions\ModelNameHelper.cs" />
|
||||
<Compile Include="Areas\HelpPage\ModelDescriptions\ParameterAnnotation.cs" />
|
||||
<Compile Include="Areas\HelpPage\ModelDescriptions\ParameterDescription.cs" />
|
||||
<Compile Include="Areas\HelpPage\ModelDescriptions\SimpleTypeModelDescription.cs" />
|
||||
<Compile Include="Areas\HelpPage\Models\HelpPageApiModel.cs" />
|
||||
<Compile Include="Areas\HelpPage\SampleGeneration\HelpPageSampleGenerator.cs" />
|
||||
<Compile Include="Areas\HelpPage\SampleGeneration\HelpPageSampleKey.cs" />
|
||||
<Compile Include="Areas\HelpPage\SampleGeneration\ImageSample.cs" />
|
||||
<Compile Include="Areas\HelpPage\SampleGeneration\InvalidSample.cs" />
|
||||
<Compile Include="Areas\HelpPage\SampleGeneration\ObjectGenerator.cs" />
|
||||
<Compile Include="Areas\HelpPage\SampleGeneration\SampleDirection.cs" />
|
||||
<Compile Include="Areas\HelpPage\SampleGeneration\TextSample.cs" />
|
||||
<Compile Include="Areas\HelpPage\XmlDocumentationProvider.cs" />
|
||||
<Compile Include="Areas\Manage\ManageAreaRegistration.cs" />
|
||||
<Compile Include="Controllers\Code\ApiAuthorizeAttribute.cs" />
|
||||
<Compile Include="Controllers\Code\BaseController.cs" />
|
||||
<Compile Include="Controllers\HomeController.cs" />
|
||||
<Compile Include="Global.asax.cs">
|
||||
<DependentUpon>Global.asax</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Areas\HelpPage\HelpPage.css" />
|
||||
<Content Include="Content\bootstrap-theme.css" />
|
||||
<Content Include="Content\bootstrap-theme.min.css" />
|
||||
<Content Include="Content\bootstrap.css" />
|
||||
<Content Include="Content\bootstrap.min.css" />
|
||||
<Content Include="favicon.ico" />
|
||||
<Content Include="fonts\glyphicons-halflings-regular.svg" />
|
||||
<Content Include="Global.asax" />
|
||||
<Content Include="Scripts\bootstrap.js" />
|
||||
<Content Include="Areas\HelpPage\Views\Web.config" />
|
||||
<Content Include="Areas\HelpPage\Views\Shared\_Layout.cshtml" />
|
||||
<Content Include="Areas\HelpPage\Views\Help\ResourceModel.cshtml" />
|
||||
<Content Include="Areas\HelpPage\Views\Help\Index.cshtml" />
|
||||
<Content Include="Areas\HelpPage\Views\Help\DisplayTemplates\TextSample.cshtml" />
|
||||
<Content Include="Areas\HelpPage\Views\Help\DisplayTemplates\SimpleTypeModelDescription.cshtml" />
|
||||
<Content Include="Areas\HelpPage\Views\Help\DisplayTemplates\Samples.cshtml" />
|
||||
<Content Include="Areas\HelpPage\Views\Help\DisplayTemplates\Parameters.cshtml" />
|
||||
<Content Include="Areas\HelpPage\Views\Help\DisplayTemplates\ModelDescriptionLink.cshtml" />
|
||||
<Content Include="Areas\HelpPage\Views\Help\DisplayTemplates\KeyValuePairModelDescription.cshtml" />
|
||||
<Content Include="Areas\HelpPage\Views\Help\DisplayTemplates\InvalidSample.cshtml" />
|
||||
<Content Include="Areas\HelpPage\Views\Help\DisplayTemplates\ImageSample.cshtml" />
|
||||
<Content Include="Areas\HelpPage\Views\Help\DisplayTemplates\HelpPageApiModel.cshtml" />
|
||||
<Content Include="Areas\HelpPage\Views\Help\DisplayTemplates\EnumTypeModelDescription.cshtml" />
|
||||
<Content Include="Areas\HelpPage\Views\Help\DisplayTemplates\DictionaryModelDescription.cshtml" />
|
||||
<Content Include="Areas\HelpPage\Views\Help\DisplayTemplates\ComplexTypeModelDescription.cshtml" />
|
||||
<Content Include="Areas\HelpPage\Views\Help\DisplayTemplates\CollectionModelDescription.cshtml" />
|
||||
<Content Include="Areas\HelpPage\Views\Help\DisplayTemplates\ApiGroup.cshtml" />
|
||||
<Content Include="Areas\HelpPage\Views\Help\Api.cshtml" />
|
||||
<Content Include="Scripts\jquery-3.3.1.js" />
|
||||
<Content Include="Scripts\modernizr-2.8.3.js" />
|
||||
<Content Include="Web.config" />
|
||||
<Content Include="Web.Debug.config">
|
||||
<DependentUpon>Web.config</DependentUpon>
|
||||
</Content>
|
||||
<Content Include="Web.Release.config">
|
||||
<DependentUpon>Web.config</DependentUpon>
|
||||
</Content>
|
||||
<Content Include="Areas\HelpPage\Views\_ViewStart.cshtml" />
|
||||
<Content Include="Content\Site.css" />
|
||||
<Content Include="Views\Web.config" />
|
||||
<Content Include="Views\_ViewStart.cshtml" />
|
||||
<Content Include="Views\Home\Index.cshtml" />
|
||||
<Content Include="Views\Shared\Error.cshtml" />
|
||||
<Content Include="Views\Shared\_Layout.cshtml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="App_Data\" />
|
||||
<Folder Include="Areas\Gate\Models\" />
|
||||
<Folder Include="Areas\Gate\Views\Shared\" />
|
||||
<Folder Include="Areas\Manage\Controllers\" />
|
||||
<Folder Include="Areas\Manage\Models\" />
|
||||
<Folder Include="Areas\Manage\Views\Shared\" />
|
||||
<Folder Include="Models\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="fonts\glyphicons-halflings-regular.woff2" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="fonts\glyphicons-halflings-regular.woff" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="fonts\glyphicons-halflings-regular.ttf" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="fonts\glyphicons-halflings-regular.eot" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Content\bootstrap.min.css.map" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Content\bootstrap.css.map" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Content\bootstrap-theme.min.css.map" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Content\bootstrap-theme.css.map" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Areas\Manage\Views\web.config" />
|
||||
<Content Include="Areas\Gate\Views\web.config" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Ewide.Core.Common\Ewide.Core.Common.csproj">
|
||||
<Project>{c7e2ac14-ac20-4552-a5b8-08b650ac8416}</Project>
|
||||
<Name>Ewide.Core.Common</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Ewide.Core.Service\Ewide.Core.Service.csproj">
|
||||
<Project>{34ae80c2-5c37-4b6c-aac3-f52c06928721}</Project>
|
||||
<Name>Ewide.Core.Service</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Ewide.Core.Utility\Ewide.Core.Utility.csproj">
|
||||
<Project>{d5c48d01-5ab1-44c9-8709-d4a336d19e9f}</Project>
|
||||
<Name>Ewide.Core.Utility</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" />
|
||||
<Target Name="MvcBuildViews" AfterTargets="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
|
||||
<AspNetCompiler VirtualPath="temp" PhysicalPath="$(WebProjectOutputDir)" />
|
||||
</Target>
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
|
||||
<WebProjectProperties>
|
||||
<UseIIS>True</UseIIS>
|
||||
<AutoAssignPort>True</AutoAssignPort>
|
||||
<DevelopmentServerPort>60161</DevelopmentServerPort>
|
||||
<DevelopmentServerVPath>/</DevelopmentServerVPath>
|
||||
<IISUrl>http://localhost:60161/</IISUrl>
|
||||
<NTLMAuthentication>False</NTLMAuthentication>
|
||||
<UseCustomServer>False</UseCustomServer>
|
||||
<CustomServerUrl>
|
||||
</CustomServerUrl>
|
||||
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
|
||||
</WebProjectProperties>
|
||||
</FlavorProperties>
|
||||
</VisualStudio>
|
||||
</ProjectExtensions>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.0\build\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.0\build\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props'))" />
|
||||
</Target>
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target> -->
|
||||
</Project>
|
||||
1
Api/Ewide.Core/Ewide.Core.WebApi/Global.asax
Normal file
1
Api/Ewide.Core/Ewide.Core.WebApi/Global.asax
Normal file
@@ -0,0 +1 @@
|
||||
<%@ Application Codebehind="Global.asax.cs" Inherits="Ewide.Core.WebApi.WebApiApplication" Language="C#" %>
|
||||
23
Api/Ewide.Core/Ewide.Core.WebApi/Global.asax.cs
Normal file
23
Api/Ewide.Core/Ewide.Core.WebApi/Global.asax.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.Http;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Optimization;
|
||||
using System.Web.Routing;
|
||||
|
||||
namespace Ewide.Core.WebApi
|
||||
{
|
||||
public class WebApiApplication : System.Web.HttpApplication
|
||||
{
|
||||
protected void Application_Start()
|
||||
{
|
||||
AreaRegistration.RegisterAllAreas();
|
||||
GlobalConfiguration.Configure(WebApiConfig.Register);
|
||||
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
|
||||
RouteConfig.RegisterRoutes(RouteTable.Routes);
|
||||
BundleConfig.RegisterBundles(BundleTable.Bundles);
|
||||
}
|
||||
}
|
||||
}
|
||||
35
Api/Ewide.Core/Ewide.Core.WebApi/Properties/AssemblyInfo.cs
Normal file
35
Api/Ewide.Core/Ewide.Core.WebApi/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// 有关程序集的常规信息是通过以下项进行控制的
|
||||
// 控制。更改这些特性值可修改
|
||||
// 与程序集关联的信息。
|
||||
[assembly: AssemblyTitle("Ewide.Core.WebApi")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Ewide.Core.WebApi")]
|
||||
[assembly: AssemblyCopyright("版权所有(C) 2021")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// 将 ComVisible 设置为 false 将使此程序集中的类型
|
||||
// 对 COM 组件不可见。如果需要
|
||||
// 从 COM 访问此程序集中的某个类型,请针对该类型将 ComVisible 特性设置为 true。
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// 如果此项目向 COM 公开,则下列 GUID 用于 typelib 的 ID
|
||||
[assembly: Guid("26218f2a-c349-473b-bf9a-c4053a9380d0")]
|
||||
|
||||
// 程序集的版本信息由下列四个值组成:
|
||||
//
|
||||
// 主版本
|
||||
// 次版本
|
||||
// 内部版本号
|
||||
// 修订版本
|
||||
//
|
||||
// 你可以指定所有值,也可以让修订版本和内部版本号采用默认值,
|
||||
// 方法是按如下所示使用 "*":
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
2377
Api/Ewide.Core/Ewide.Core.WebApi/Scripts/bootstrap.js
vendored
Normal file
2377
Api/Ewide.Core/Ewide.Core.WebApi/Scripts/bootstrap.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
10364
Api/Ewide.Core/Ewide.Core.WebApi/Scripts/jquery-3.3.1.js
vendored
Normal file
10364
Api/Ewide.Core/Ewide.Core.WebApi/Scripts/jquery-3.3.1.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1406
Api/Ewide.Core/Ewide.Core.WebApi/Scripts/modernizr-2.8.3.js
vendored
Normal file
1406
Api/Ewide.Core/Ewide.Core.WebApi/Scripts/modernizr-2.8.3.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
24
Api/Ewide.Core/Ewide.Core.WebApi/Views/Home/Index.cshtml
Normal file
24
Api/Ewide.Core/Ewide.Core.WebApi/Views/Home/Index.cshtml
Normal file
@@ -0,0 +1,24 @@
|
||||
<div class="jumbotron">
|
||||
<h1>ASP.NET</h1>
|
||||
<p class="lead">ASP.NET is a free web framework for building great Web sites and Web applications using HTML, CSS, and JavaScript.</p>
|
||||
<p><a href="https://asp.net" class="btn btn-primary btn-lg">Learn more »</a></p>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<h2>Getting started</h2>
|
||||
<p>ASP.NET Web API is a framework that makes it easy to build HTTP services that reach
|
||||
a broad range of clients, including browsers and mobile devices. ASP.NET Web API
|
||||
is an ideal platform for building RESTful applications on the .NET Framework.</p>
|
||||
<p><a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkId=301870">Learn more »</a></p>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<h2>Get more libraries</h2>
|
||||
<p>NuGet is a free Visual Studio extension that makes it easy to add, remove, and update libraries and tools in Visual Studio projects.</p>
|
||||
<p><a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkId=301871">Learn more »</a></p>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<h2>Web Hosting</h2>
|
||||
<p>You can easily find a web hosting company that offers the right mix of features and price for your applications.</p>
|
||||
<p><a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkId=301872">Learn more »</a></p>
|
||||
</div>
|
||||
</div>
|
||||
14
Api/Ewide.Core/Ewide.Core.WebApi/Views/Shared/Error.cshtml
Normal file
14
Api/Ewide.Core/Ewide.Core.WebApi/Views/Shared/Error.cshtml
Normal file
@@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>错误</title>
|
||||
</head>
|
||||
<body>
|
||||
<hgroup>
|
||||
<h1>错误。</h1>
|
||||
<h2>处理你的请求时出错。</h2>
|
||||
</hgroup>
|
||||
</body>
|
||||
</html>
|
||||
43
Api/Ewide.Core/Ewide.Core.WebApi/Views/Shared/_Layout.cshtml
Normal file
43
Api/Ewide.Core/Ewide.Core.WebApi/Views/Shared/_Layout.cshtml
Normal file
@@ -0,0 +1,43 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>@ViewBag.Title</title>
|
||||
@Styles.Render("~/Content/css")
|
||||
@Scripts.Render("~/bundles/modernizr")
|
||||
</head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||
<body>
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="container">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
@Html.ActionLink("应用程序名称", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
|
||||
</div>
|
||||
<div class="navbar-collapse collapse">
|
||||
<ul class="nav navbar-nav">
|
||||
<li>@Html.ActionLink("主页", "Index", "Home", new { area = "" }, null)</li>
|
||||
<li>@Html.ActionLink("API", "Index", "Help", new { area = "" }, null)</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container body-content">
|
||||
@RenderBody()
|
||||
<hr />
|
||||
<footer>
|
||||
<p>© @DateTime.Now.Year - 我的 ASP.NET 应用程序</p>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
@Scripts.Render("~/bundles/jquery")
|
||||
@Scripts.Render("~/bundles/bootstrap")
|
||||
@RenderSection("scripts", required: false)
|
||||
</body>
|
||||
</html>
|
||||
43
Api/Ewide.Core/Ewide.Core.WebApi/Views/Web.config
Normal file
43
Api/Ewide.Core/Ewide.Core.WebApi/Views/Web.config
Normal file
@@ -0,0 +1,43 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<configuration>
|
||||
<configSections>
|
||||
<sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
|
||||
<section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
|
||||
<section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
|
||||
</sectionGroup>
|
||||
</configSections>
|
||||
|
||||
<system.web.webPages.razor>
|
||||
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.4.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
|
||||
<pages pageBaseType="System.Web.Mvc.WebViewPage">
|
||||
<namespaces>
|
||||
<add namespace="System.Web.Mvc" />
|
||||
<add namespace="System.Web.Mvc.Ajax" />
|
||||
<add namespace="System.Web.Mvc.Html" />
|
||||
<add namespace="System.Web.Optimization"/>
|
||||
<add namespace="System.Web.Routing" />
|
||||
<add namespace="Ewide.Core.WebApi" />
|
||||
</namespaces>
|
||||
</pages>
|
||||
</system.web.webPages.razor>
|
||||
|
||||
<appSettings>
|
||||
<add key="webpages:Enabled" value="false" />
|
||||
</appSettings>
|
||||
|
||||
<system.webServer>
|
||||
<handlers>
|
||||
<remove name="BlockViewHandler"/>
|
||||
<add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
|
||||
</handlers>
|
||||
</system.webServer>
|
||||
|
||||
<system.web>
|
||||
<compilation>
|
||||
<assemblies>
|
||||
<add assembly="System.Web.Mvc, Version=5.2.4.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
|
||||
</assemblies>
|
||||
</compilation>
|
||||
</system.web>
|
||||
</configuration>
|
||||
3
Api/Ewide.Core/Ewide.Core.WebApi/Views/_ViewStart.cshtml
Normal file
3
Api/Ewide.Core/Ewide.Core.WebApi/Views/_ViewStart.cshtml
Normal file
@@ -0,0 +1,3 @@
|
||||
@{
|
||||
Layout = "~/Views/Shared/_Layout.cshtml";
|
||||
}
|
||||
30
Api/Ewide.Core/Ewide.Core.WebApi/Web.Debug.config
Normal file
30
Api/Ewide.Core/Ewide.Core.WebApi/Web.Debug.config
Normal file
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!-- 有关使用 Web.config 转换的详细信息,请访问 https://go.microsoft.com/fwlink/?LinkId=301874 -->
|
||||
|
||||
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
|
||||
<!--
|
||||
在下例中,“SetAttributes”转换将更改
|
||||
“connectionString”的值,仅在“Match”定位器找到值为“MyDB”的
|
||||
特性“name”时使用“ReleaseSQLServer”。
|
||||
|
||||
<connectionStrings>
|
||||
<add name="MyDB"
|
||||
connectionString="Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True"
|
||||
xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
|
||||
</connectionStrings>
|
||||
-->
|
||||
<system.web>
|
||||
<!--
|
||||
在以下示例中,"Replace" 转换将替换 Web.config 文件的
|
||||
整个 <customErrors> 节。
|
||||
请注意,由于在 <system.web> 节点下只有一个
|
||||
customErrors 节,因此无需使用 "xdt:Locator" 属性。
|
||||
|
||||
<customErrors defaultRedirect="GenericError.htm"
|
||||
mode="RemoteOnly" xdt:Transform="Replace">
|
||||
<error statusCode="500" redirect="InternalError.htm"/>
|
||||
</customErrors>
|
||||
-->
|
||||
</system.web>
|
||||
</configuration>
|
||||
31
Api/Ewide.Core/Ewide.Core.WebApi/Web.Release.config
Normal file
31
Api/Ewide.Core/Ewide.Core.WebApi/Web.Release.config
Normal file
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!-- 有关使用 Web.config 转换的详细信息,请访问 https://go.microsoft.com/fwlink/?LinkId=301874 -->
|
||||
|
||||
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
|
||||
<!--
|
||||
在下例中,“SetAttributes”转换将更改
|
||||
“connectionString”的值,仅在“Match”定位器找到值为“MyDB”的
|
||||
特性“name”时使用“ReleaseSQLServer”。
|
||||
|
||||
<connectionStrings>
|
||||
<add name="MyDB"
|
||||
connectionString="Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True"
|
||||
xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
|
||||
</connectionStrings>
|
||||
-->
|
||||
<system.web>
|
||||
<compilation xdt:Transform="RemoveAttributes(debug)" />
|
||||
<!--
|
||||
在以下示例中,"Replace" 转换将替换 Web.config 文件的
|
||||
整个 <customErrors> 节。
|
||||
请注意,由于在 <system.web> 节点下只有一个
|
||||
customErrors 节,因此无需使用 "xdt:Locator" 属性。
|
||||
|
||||
<customErrors defaultRedirect="GenericError.htm"
|
||||
mode="RemoteOnly" xdt:Transform="Replace">
|
||||
<error statusCode="500" redirect="InternalError.htm"/>
|
||||
</customErrors>
|
||||
-->
|
||||
</system.web>
|
||||
</configuration>
|
||||
68
Api/Ewide.Core/Ewide.Core.WebApi/Web.config
Normal file
68
Api/Ewide.Core/Ewide.Core.WebApi/Web.config
Normal file
@@ -0,0 +1,68 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
有关如何配置 ASP.NET 应用程序的详细信息,请访问
|
||||
https://go.microsoft.com/fwlink/?LinkId=301879
|
||||
-->
|
||||
<configuration>
|
||||
<appSettings>
|
||||
<add key="webpages:Version" value="3.0.0.0"/>
|
||||
<add key="webpages:Enabled" value="false"/>
|
||||
<add key="ClientValidationEnabled" value="true"/>
|
||||
<add key="UnobtrusiveJavaScriptEnabled" value="true"/>
|
||||
</appSettings>
|
||||
<system.web>
|
||||
<compilation debug="true" targetFramework="4.5"/>
|
||||
<httpRuntime targetFramework="4.5"/>
|
||||
</system.web>
|
||||
<system.webServer>
|
||||
<handlers>
|
||||
<remove name="ExtensionlessUrlHandler-Integrated-4.0"/>
|
||||
<remove name="OPTIONSVerbHandler"/>
|
||||
<remove name="TRACEVerbHandler"/>
|
||||
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler"
|
||||
preCondition="integratedMode,runtimeVersionv4.0"/>
|
||||
</handlers>
|
||||
</system.webServer>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Antlr3.Runtime" publicKeyToken="eb42632606e9261f"/>
|
||||
<bindingRedirect oldVersion="0.0.0.0-3.5.0.2" newVersion="3.5.0.2"/>
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Newtonsoft.Json" culture="neutral" publicKeyToken="30ad4fe6b2a6aeed"/>
|
||||
<bindingRedirect oldVersion="0.0.0.0-11.0.0.0" newVersion="11.0.0.0"/>
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Web.Optimization" publicKeyToken="31bf3856ad364e35"/>
|
||||
<bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="1.1.0.0"/>
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35"/>
|
||||
<bindingRedirect oldVersion="1.0.0.0-1.6.5135.21930" newVersion="1.6.5135.21930"/>
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35"/>
|
||||
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0"/>
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35"/>
|
||||
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0"/>
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35"/>
|
||||
<bindingRedirect oldVersion="1.0.0.0-5.2.4.0" newVersion="5.2.4.0"/>
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
<system.codedom>
|
||||
<compilers>
|
||||
<compiler language="c#;cs;csharp" extension=".cs"
|
||||
type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
|
||||
warningLevel="4" compilerOptions="/langversion:6 /nowarn:1659;1699;1701"/>
|
||||
<compiler language="vb;vbs;visualbasic;vbscript" extension=".vb"
|
||||
type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
|
||||
warningLevel="4" compilerOptions="/langversion:14 /nowarn:41008 /define:_MYTYPE=\"Web\" /optionInfer+"/>
|
||||
</compilers>
|
||||
</system.codedom>
|
||||
</configuration>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user