This commit is contained in:
Ianko Djemerenov 2016-11-16 15:24:54 +02:00
Родитель cc7cf0305d
Коммит 1c072363ae
113 изменённых файлов: 0 добавлений и 32030 удалений

Просмотреть файл

@ -1,14 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
Note: Add entries to the App.config file for configuration settings
that apply only to the Test project.
-->
<configuration>
<appSettings>
</appSettings>
<connectionStrings>
</connectionStrings>
</configuration>

Просмотреть файл

@ -1,25 +0,0 @@
using System.Web.Mvc;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OlympicGames;
using OlympicGames.Controllers;
namespace OlympicGames.Tests.Controllers
{
[TestClass]
public class HomeControllerTest
{
[TestMethod]
public void Index()
{
// Arrange
HomeController controller = new HomeController();
// Act
ViewResult result = controller.Index() as ViewResult;
// Assert
Assert.IsNotNull(result);
Assert.AreEqual("Home Page", result.ViewBag.Title);
}
}
}

Просмотреть файл

@ -1,81 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Web.Http;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OlympicGames;
using OlympicGames.Controllers;
namespace OlympicGames.Tests.Controllers
{
[TestClass]
public class ValuesControllerTest
{
[TestMethod]
public void Get()
{
// Arrange
ValuesController controller = new ValuesController();
// Act
IEnumerable<string> result = controller.Get();
// Assert
Assert.IsNotNull(result);
Assert.AreEqual(2, result.Count());
Assert.AreEqual("value1", result.ElementAt(0));
Assert.AreEqual("value2", result.ElementAt(1));
}
[TestMethod]
public void GetById()
{
// Arrange
ValuesController controller = new ValuesController();
// Act
string result = controller.Get(5);
// Assert
Assert.AreEqual("value", result);
}
[TestMethod]
public void Post()
{
// Arrange
ValuesController controller = new ValuesController();
// Act
controller.Post("value");
// Assert
}
[TestMethod]
public void Put()
{
// Arrange
ValuesController controller = new ValuesController();
// Act
controller.Put(5, "value");
// Assert
}
[TestMethod]
public void Delete()
{
// Arrange
ValuesController controller = new ValuesController();
// Act
controller.Delete(5);
// Assert
}
}
}

Просмотреть файл

@ -1,118 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>
</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{39DCCBEF-CA89-4ADC-BF8B-0F4CF7F5CBD4}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>OlympicGames.Tests</RootNamespace>
<AssemblyName>OlympicGames.Tests</AssemblyName>
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
</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="Microsoft.CSharp" />
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
<Reference Include="System" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Data" />
<Reference Include="System.Web" />
<Reference Include="System.Web.ApplicationServices" />
<Reference Include="System.Web.Extensions" />
<Reference Include="System.Web.Abstractions" />
<Reference Include="System.Web.Routing" />
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq" />
<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.6.0.4\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System.Net.Http" />
<Reference Include="System.Net.Http.Formatting, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll</HintPath>
</Reference>
<Reference Include="System.Net.Http.WebRequest" />
<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.3\lib\net45\System.Web.Helpers.dll</HintPath>
</Reference>
<Reference Include="System.Web.Http, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll</HintPath>
</Reference>
<Reference Include="System.Web.Http.WebHost, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.WebHost.5.2.3\lib\net45\System.Web.Http.WebHost.dll</HintPath>
</Reference>
<Reference Include="System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Private>True</Private>
<HintPath>..\packages\Microsoft.AspNet.Mvc.5.2.3\lib\net45\System.Web.Mvc.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.3\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.3\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.3\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.3\lib\net45\System.Web.WebPages.Razor.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Controllers\HomeControllerTest.cs" />
<Compile Include="Controllers\ValuesControllerTest.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="App.config" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\OlympicGames\OlympicGames.csproj">
<Project>{ABFAA97D-7510-4C0E-B736-FBD01558B628}</Project>
<Name>OlympicGames</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- 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,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectView>ShowAllFiles</ProjectView>
</PropertyGroup>
</Project>

Просмотреть файл

@ -1,35 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("OlympicGames.Tests")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("OlympicGames.Tests")]
[assembly: AssemblyCopyright("Copyright © 2016")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("55d222e7-73c8-4db0-9413-74eaaf91ee01")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

Просмотреть файл

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.AspNet.Mvc" version="5.2.3" targetFramework="net462" />
<package id="Microsoft.AspNet.Razor" version="3.2.3" targetFramework="net462" />
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net462" />
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net462" />
<package id="Microsoft.AspNet.WebApi.WebHost" version="5.2.3" targetFramework="net462" />
<package id="Microsoft.AspNet.WebPages" version="3.2.3" targetFramework="net462" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net462" />
<package id="Newtonsoft.Json" version="6.0.4" targetFramework="net462" />
</packages>

Просмотреть файл

@ -1,28 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OlympicGames", "OlympicGames\OlympicGames.csproj", "{ABFAA97D-7510-4C0E-B736-FBD01558B628}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OlympicGames.Tests", "OlympicGames.Tests\OlympicGames.Tests.csproj", "{39DCCBEF-CA89-4ADC-BF8B-0F4CF7F5CBD4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{ABFAA97D-7510-4C0E-B736-FBD01558B628}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ABFAA97D-7510-4C0E-B736-FBD01558B628}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ABFAA97D-7510-4C0E-B736-FBD01558B628}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ABFAA97D-7510-4C0E-B736-FBD01558B628}.Release|Any CPU.Build.0 = Release|Any CPU
{39DCCBEF-CA89-4ADC-BF8B-0F4CF7F5CBD4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{39DCCBEF-CA89-4ADC-BF8B-0F4CF7F5CBD4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{39DCCBEF-CA89-4ADC-BF8B-0F4CF7F5CBD4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{39DCCBEF-CA89-4ADC-BF8B-0F4CF7F5CBD4}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

Двоичные данные
OlympicGames/App_Data/Olympics.mdf

Двоичный файл не отображается.

Двоичные данные
OlympicGames/App_Data/Olympics.sql

Двоичный файл не отображается.

Двоичные данные
OlympicGames/App_Data/Olympics_log.ldf

Двоичный файл не отображается.

Просмотреть файл

@ -1,28 +0,0 @@
using System.Web;
using System.Web.Optimization;
namespace OlympicGames
{
public class BundleConfig
{
// For more information on bundling, visit http://go.microsoft.com/fwlink/?LinkId=301862
public static void RegisterBundles(BundleCollection bundles)
{
bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
"~/Scripts/jquery-{version}.js"));
// Use the development version of Modernizr to develop with and learn from. Then, when you're
// ready for production, use the build tool at http://modernizr.com to pick only the tests you need.
bundles.Add(new ScriptBundle("~/bundles/modernizr").Include(
"~/Scripts/modernizr-*"));
bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include(
"~/Scripts/bootstrap.js",
"~/Scripts/respond.js"));
bundles.Add(new StyleBundle("~/Content/css").Include(
"~/Content/bootstrap.css",
"~/Content/site.css"));
}
}
}

Просмотреть файл

@ -1,13 +0,0 @@
using System.Web;
using System.Web.Mvc;
namespace OlympicGames
{
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
}
}
}

Просмотреть файл

@ -1,45 +0,0 @@
using System.Threading.Tasks;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin;
using OlympicGames.Models;
namespace OlympicGames
{
// Configure the application user manager used in this application. UserManager is defined in ASP.NET Identity and is used by the application.
public class ApplicationUserManager : UserManager<ApplicationUser>
{
public ApplicationUserManager(IUserStore<ApplicationUser> store)
: base(store)
{
}
public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
{
var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));
// Configure validation logic for usernames
manager.UserValidator = new UserValidator<ApplicationUser>(manager)
{
AllowOnlyAlphanumericUserNames = false,
RequireUniqueEmail = true
};
// Configure validation logic for passwords
manager.PasswordValidator = new PasswordValidator
{
RequiredLength = 6,
RequireNonLetterOrDigit = true,
RequireDigit = true,
RequireLowercase = true,
RequireUppercase = true,
};
var dataProtectionProvider = options.DataProtectionProvider;
if (dataProtectionProvider != null)
{
manager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity"));
}
return manager;
}
}
}

Просмотреть файл

@ -1,23 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
namespace OlympicGames
{
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 }
);
}
}
}

Просмотреть файл

@ -1,69 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.Owin;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.Google;
using Microsoft.Owin.Security.OAuth;
using Owin;
using OlympicGames.Providers;
using OlympicGames.Models;
namespace OlympicGames
{
public partial class Startup
{
public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }
public static string PublicClientId { get; private set; }
// For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864
public void ConfigureAuth(IAppBuilder app)
{
// Configure the db context and user manager to use a single instance per request
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
// Enable the application to use a cookie to store information for the signed in user
// and to use a cookie to temporarily store information about a user logging in with a third party login provider
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
// Configure the application for OAuth based flow
PublicClientId = "self";
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
Provider = new ApplicationOAuthProvider(PublicClientId),
AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
// In production mode set AllowInsecureHttp = false
AllowInsecureHttp = true
};
// Enable the application to use bearer tokens to authenticate users
app.UseOAuthBearerTokens(OAuthOptions);
// Uncomment the following lines to enable logging in with third party login providers
//app.UseMicrosoftAccountAuthentication(
// clientId: "",
// clientSecret: "");
//app.UseTwitterAuthentication(
// consumerKey: "",
// consumerSecret: "");
//app.UseFacebookAuthentication(
// appId: "",
// appSecret: "");
//app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions()
//{
// ClientId = "",
// ClientSecret = ""
//});
}
}
}

Просмотреть файл

@ -1,30 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Web.Http;
using Microsoft.Owin.Security.OAuth;
using Newtonsoft.Json.Serialization;
namespace OlympicGames
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Configure Web API to use only bearer token authentication.
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
}

Просмотреть файл

@ -1,39 +0,0 @@
using System;
using System.Text;
using System.Web;
using System.Web.Http.Description;
namespace OlympicGames.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();
}
}
}

Просмотреть файл

@ -1,113 +0,0 @@
// 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 OlympicGames.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 = "OlympicGames.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
}
}

Просмотреть файл

@ -1,63 +0,0 @@
using System;
using System.Web.Http;
using System.Web.Mvc;
using OlympicGames.Areas.HelpPage.ModelDescriptions;
using OlympicGames.Areas.HelpPage.Models;
namespace OlympicGames.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);
}
}
}

Просмотреть файл

@ -1,134 +0,0 @@
.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;
}

Просмотреть файл

@ -1,26 +0,0 @@
using System.Web.Http;
using System.Web.Mvc;
namespace OlympicGames.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);
}
}
}

Просмотреть файл

@ -1,467 +0,0 @@
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 OlympicGames.Areas.HelpPage.ModelDescriptions;
using OlympicGames.Areas.HelpPage.Models;
namespace OlympicGames.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);
}
}
}
}

Просмотреть файл

@ -1,7 +0,0 @@
namespace OlympicGames.Areas.HelpPage.ModelDescriptions
{
public class CollectionModelDescription : ModelDescription
{
public ModelDescription ElementDescription { get; set; }
}
}

Просмотреть файл

@ -1,14 +0,0 @@
using System.Collections.ObjectModel;
namespace OlympicGames.Areas.HelpPage.ModelDescriptions
{
public class ComplexTypeModelDescription : ModelDescription
{
public ComplexTypeModelDescription()
{
Properties = new Collection<ParameterDescription>();
}
public Collection<ParameterDescription> Properties { get; private set; }
}
}

Просмотреть файл

@ -1,6 +0,0 @@
namespace OlympicGames.Areas.HelpPage.ModelDescriptions
{
public class DictionaryModelDescription : KeyValuePairModelDescription
{
}
}

Просмотреть файл

@ -1,15 +0,0 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace OlympicGames.Areas.HelpPage.ModelDescriptions
{
public class EnumTypeModelDescription : ModelDescription
{
public EnumTypeModelDescription()
{
Values = new Collection<EnumValueDescription>();
}
public Collection<EnumValueDescription> Values { get; private set; }
}
}

Просмотреть файл

@ -1,11 +0,0 @@
namespace OlympicGames.Areas.HelpPage.ModelDescriptions
{
public class EnumValueDescription
{
public string Documentation { get; set; }
public string Name { get; set; }
public string Value { get; set; }
}
}

Просмотреть файл

@ -1,12 +0,0 @@
using System;
using System.Reflection;
namespace OlympicGames.Areas.HelpPage.ModelDescriptions
{
public interface IModelDocumentationProvider
{
string GetDocumentation(MemberInfo member);
string GetDocumentation(Type type);
}
}

Просмотреть файл

@ -1,9 +0,0 @@
namespace OlympicGames.Areas.HelpPage.ModelDescriptions
{
public class KeyValuePairModelDescription : ModelDescription
{
public ModelDescription KeyModelDescription { get; set; }
public ModelDescription ValueModelDescription { get; set; }
}
}

Просмотреть файл

@ -1,16 +0,0 @@
using System;
namespace OlympicGames.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; }
}
}

Просмотреть файл

@ -1,451 +0,0 @@
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 OlympicGames.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;
}
}
}

Просмотреть файл

@ -1,18 +0,0 @@
using System;
namespace OlympicGames.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; }
}
}

Просмотреть файл

@ -1,36 +0,0 @@
using System;
using System.Globalization;
using System.Linq;
using System.Reflection;
namespace OlympicGames.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;
}
}
}

Просмотреть файл

@ -1,11 +0,0 @@
using System;
namespace OlympicGames.Areas.HelpPage.ModelDescriptions
{
public class ParameterAnnotation
{
public Attribute AnnotationAttribute { get; set; }
public string Documentation { get; set; }
}
}

Просмотреть файл

@ -1,21 +0,0 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace OlympicGames.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; }
}
}

Просмотреть файл

@ -1,6 +0,0 @@
namespace OlympicGames.Areas.HelpPage.ModelDescriptions
{
public class SimpleTypeModelDescription : ModelDescription
{
}
}

Просмотреть файл

@ -1,108 +0,0 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Net.Http.Headers;
using System.Web.Http.Description;
using OlympicGames.Areas.HelpPage.ModelDescriptions;
namespace OlympicGames.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;
}
}
}

Просмотреть файл

@ -1,444 +0,0 @@
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 OlympicGames.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;
}
}
}

Просмотреть файл

@ -1,172 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Net.Http.Headers;
namespace OlympicGames.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;
}
}
}

Просмотреть файл

@ -1,41 +0,0 @@
using System;
namespace OlympicGames.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;
}
}
}

Просмотреть файл

@ -1,37 +0,0 @@
using System;
namespace OlympicGames.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;
}
}
}

Просмотреть файл

@ -1,456 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
using System.Reflection;
namespace OlympicGames.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);
}
}
}
}

Просмотреть файл

@ -1,11 +0,0 @@
namespace OlympicGames.Areas.HelpPage
{
/// <summary>
/// Indicates whether the sample is used for request or response
/// </summary>
public enum SampleDirection
{
Request = 0,
Response
}
}

Просмотреть файл

@ -1,37 +0,0 @@
using System;
namespace OlympicGames.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;
}
}
}

Просмотреть файл

@ -1,22 +0,0 @@
@using System.Web.Http
@using OlympicGames.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>

Просмотреть файл

@ -1,41 +0,0 @@
@using System.Web.Http
@using System.Web.Http.Controllers
@using System.Web.Http.Description
@using OlympicGames.Areas.HelpPage
@using OlympicGames.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>

Просмотреть файл

@ -1,6 +0,0 @@
@using OlympicGames.Areas.HelpPage.ModelDescriptions
@model CollectionModelDescription
@if (Model.ElementDescription is ComplexTypeModelDescription)
{
@Html.DisplayFor(m => m.ElementDescription)
}

Просмотреть файл

@ -1,3 +0,0 @@
@using OlympicGames.Areas.HelpPage.ModelDescriptions
@model ComplexTypeModelDescription
@Html.DisplayFor(m => m.Properties, "Parameters")

Просмотреть файл

@ -1,4 +0,0 @@
@using OlympicGames.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]

Просмотреть файл

@ -1,24 +0,0 @@
@using OlympicGames.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>

Просмотреть файл

@ -1,67 +0,0 @@
@using System.Web.Http
@using System.Web.Http.Description
@using OlympicGames.Areas.HelpPage.Models
@using OlympicGames.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>

Просмотреть файл

@ -1,4 +0,0 @@
@using OlympicGames.Areas.HelpPage
@model ImageSample
<img src="@Model.Src" />

Просмотреть файл

@ -1,13 +0,0 @@
@using OlympicGames.Areas.HelpPage
@model InvalidSample
@if (HttpContext.Current.IsDebuggingEnabled)
{
<div class="warning-message-container">
<p>@Model.ErrorMessage</p>
</div>
}
else
{
<p>Sample not available.</p>
}

Просмотреть файл

@ -1,4 +0,0 @@
@using OlympicGames.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]

Просмотреть файл

@ -1,26 +0,0 @@
@using OlympicGames.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)
}
}

Просмотреть файл

@ -1,48 +0,0 @@
@using System.Collections.Generic
@using System.Collections.ObjectModel
@using System.Web.Http.Description
@using System.Threading
@using OlympicGames.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>
}

Просмотреть файл

@ -1,30 +0,0 @@
@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>

Просмотреть файл

@ -1,3 +0,0 @@
@using OlympicGames.Areas.HelpPage.ModelDescriptions
@model SimpleTypeModelDescription
@Model.Documentation

Просмотреть файл

@ -1,6 +0,0 @@
@using OlympicGames.Areas.HelpPage
@model TextSample
<pre class="wrapped">
@Model.Text
</pre>

Просмотреть файл

@ -1,38 +0,0 @@
@using System.Web.Http
@using System.Web.Http.Controllers
@using System.Web.Http.Description
@using System.Collections.ObjectModel
@using OlympicGames.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>

Просмотреть файл

@ -1,19 +0,0 @@
@using System.Web.Http
@using OlympicGames.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>

Просмотреть файл

@ -1,12 +0,0 @@
<!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>

Просмотреть файл

@ -1,41 +0,0 @@
<?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.3.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>

Просмотреть файл

@ -1,4 +0,0 @@
@{
// 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";
}

Просмотреть файл

@ -1,161 +0,0 @@
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 OlympicGames.Areas.HelpPage.ModelDescriptions;
namespace OlympicGames.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;
}
}
}

Просмотреть файл

@ -1,17 +0,0 @@
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;
}

6816
OlympicGames/Content/bootstrap.css поставляемый

Разница между файлами не показана из-за своего большого размера Загрузить разницу

20
OlympicGames/Content/bootstrap.min.css поставляемый

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -1,494 +0,0 @@
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Security.Claims;
using System.Security.Cryptography;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;
using System.Web.Http.ModelBinding;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.OAuth;
using OlympicGames.Models;
using OlympicGames.Providers;
using OlympicGames.Results;
namespace OlympicGames.Controllers
{
[Authorize]
[RoutePrefix("api/Account")]
public class AccountController : ApiController
{
private const string LocalLoginProvider = "Local";
private ApplicationUserManager _userManager;
public AccountController()
{
}
public AccountController(ApplicationUserManager userManager,
ISecureDataFormat<AuthenticationTicket> accessTokenFormat)
{
UserManager = userManager;
AccessTokenFormat = accessTokenFormat;
}
public ApplicationUserManager UserManager
{
get
{
return _userManager ?? Request.GetOwinContext().GetUserManager<ApplicationUserManager>();
}
private set
{
_userManager = value;
}
}
public ISecureDataFormat<AuthenticationTicket> AccessTokenFormat { get; private set; }
// GET api/Account/UserInfo
[HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
[Route("UserInfo")]
public UserInfoViewModel GetUserInfo()
{
ExternalLoginData externalLogin = ExternalLoginData.FromIdentity(User.Identity as ClaimsIdentity);
return new UserInfoViewModel
{
Email = User.Identity.GetUserName(),
HasRegistered = externalLogin == null,
LoginProvider = externalLogin != null ? externalLogin.LoginProvider : null
};
}
// POST api/Account/Logout
[Route("Logout")]
public IHttpActionResult Logout()
{
Authentication.SignOut(CookieAuthenticationDefaults.AuthenticationType);
return Ok();
}
// GET api/Account/ManageInfo?returnUrl=%2F&generateState=true
[Route("ManageInfo")]
public async Task<ManageInfoViewModel> GetManageInfo(string returnUrl, bool generateState = false)
{
IdentityUser user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
if (user == null)
{
return null;
}
List<UserLoginInfoViewModel> logins = new List<UserLoginInfoViewModel>();
foreach (IdentityUserLogin linkedAccount in user.Logins)
{
logins.Add(new UserLoginInfoViewModel
{
LoginProvider = linkedAccount.LoginProvider,
ProviderKey = linkedAccount.ProviderKey
});
}
if (user.PasswordHash != null)
{
logins.Add(new UserLoginInfoViewModel
{
LoginProvider = LocalLoginProvider,
ProviderKey = user.UserName,
});
}
return new ManageInfoViewModel
{
LocalLoginProvider = LocalLoginProvider,
Email = user.UserName,
Logins = logins,
ExternalLoginProviders = GetExternalLogins(returnUrl, generateState)
};
}
// POST api/Account/ChangePassword
[Route("ChangePassword")]
public async Task<IHttpActionResult> ChangePassword(ChangePasswordBindingModel model)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
IdentityResult result = await UserManager.ChangePasswordAsync(User.Identity.GetUserId(), model.OldPassword,
model.NewPassword);
if (!result.Succeeded)
{
return GetErrorResult(result);
}
return Ok();
}
// POST api/Account/SetPassword
[Route("SetPassword")]
public async Task<IHttpActionResult> SetPassword(SetPasswordBindingModel model)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
IdentityResult result = await UserManager.AddPasswordAsync(User.Identity.GetUserId(), model.NewPassword);
if (!result.Succeeded)
{
return GetErrorResult(result);
}
return Ok();
}
// POST api/Account/AddExternalLogin
[Route("AddExternalLogin")]
public async Task<IHttpActionResult> AddExternalLogin(AddExternalLoginBindingModel model)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie);
AuthenticationTicket ticket = AccessTokenFormat.Unprotect(model.ExternalAccessToken);
if (ticket == null || ticket.Identity == null || (ticket.Properties != null
&& ticket.Properties.ExpiresUtc.HasValue
&& ticket.Properties.ExpiresUtc.Value < DateTimeOffset.UtcNow))
{
return BadRequest("External login failure.");
}
ExternalLoginData externalData = ExternalLoginData.FromIdentity(ticket.Identity);
if (externalData == null)
{
return BadRequest("The external login is already associated with an account.");
}
IdentityResult result = await UserManager.AddLoginAsync(User.Identity.GetUserId(),
new UserLoginInfo(externalData.LoginProvider, externalData.ProviderKey));
if (!result.Succeeded)
{
return GetErrorResult(result);
}
return Ok();
}
// POST api/Account/RemoveLogin
[Route("RemoveLogin")]
public async Task<IHttpActionResult> RemoveLogin(RemoveLoginBindingModel model)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
IdentityResult result;
if (model.LoginProvider == LocalLoginProvider)
{
result = await UserManager.RemovePasswordAsync(User.Identity.GetUserId());
}
else
{
result = await UserManager.RemoveLoginAsync(User.Identity.GetUserId(),
new UserLoginInfo(model.LoginProvider, model.ProviderKey));
}
if (!result.Succeeded)
{
return GetErrorResult(result);
}
return Ok();
}
// GET api/Account/ExternalLogin
[OverrideAuthentication]
[HostAuthentication(DefaultAuthenticationTypes.ExternalCookie)]
[AllowAnonymous]
[Route("ExternalLogin", Name = "ExternalLogin")]
public async Task<IHttpActionResult> GetExternalLogin(string provider, string error = null)
{
if (error != null)
{
return Redirect(Url.Content("~/") + "#error=" + Uri.EscapeDataString(error));
}
if (!User.Identity.IsAuthenticated)
{
return new ChallengeResult(provider, this);
}
ExternalLoginData externalLogin = ExternalLoginData.FromIdentity(User.Identity as ClaimsIdentity);
if (externalLogin == null)
{
return InternalServerError();
}
if (externalLogin.LoginProvider != provider)
{
Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie);
return new ChallengeResult(provider, this);
}
ApplicationUser user = await UserManager.FindAsync(new UserLoginInfo(externalLogin.LoginProvider,
externalLogin.ProviderKey));
bool hasRegistered = user != null;
if (hasRegistered)
{
Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie);
ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(UserManager,
OAuthDefaults.AuthenticationType);
ClaimsIdentity cookieIdentity = await user.GenerateUserIdentityAsync(UserManager,
CookieAuthenticationDefaults.AuthenticationType);
AuthenticationProperties properties = ApplicationOAuthProvider.CreateProperties(user.UserName);
Authentication.SignIn(properties, oAuthIdentity, cookieIdentity);
}
else
{
IEnumerable<Claim> claims = externalLogin.GetClaims();
ClaimsIdentity identity = new ClaimsIdentity(claims, OAuthDefaults.AuthenticationType);
Authentication.SignIn(identity);
}
return Ok();
}
// GET api/Account/ExternalLogins?returnUrl=%2F&generateState=true
[AllowAnonymous]
[Route("ExternalLogins")]
public IEnumerable<ExternalLoginViewModel> GetExternalLogins(string returnUrl, bool generateState = false)
{
IEnumerable<AuthenticationDescription> descriptions = Authentication.GetExternalAuthenticationTypes();
List<ExternalLoginViewModel> logins = new List<ExternalLoginViewModel>();
string state;
if (generateState)
{
const int strengthInBits = 256;
state = RandomOAuthStateGenerator.Generate(strengthInBits);
}
else
{
state = null;
}
foreach (AuthenticationDescription description in descriptions)
{
ExternalLoginViewModel login = new ExternalLoginViewModel
{
Name = description.Caption,
Url = Url.Route("ExternalLogin", new
{
provider = description.AuthenticationType,
response_type = "token",
client_id = Startup.PublicClientId,
redirect_uri = new Uri(Request.RequestUri, returnUrl).AbsoluteUri,
state = state
}),
State = state
};
logins.Add(login);
}
return logins;
}
// POST api/Account/Register
[AllowAnonymous]
[Route("Register")]
public async Task<IHttpActionResult> Register(RegisterBindingModel model)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var user = new ApplicationUser() { UserName = model.Email, Email = model.Email };
IdentityResult result = await UserManager.CreateAsync(user, model.Password);
if (!result.Succeeded)
{
return GetErrorResult(result);
}
return Ok();
}
// POST api/Account/RegisterExternal
[OverrideAuthentication]
[HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
[Route("RegisterExternal")]
public async Task<IHttpActionResult> RegisterExternal(RegisterExternalBindingModel model)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var info = await Authentication.GetExternalLoginInfoAsync();
if (info == null)
{
return InternalServerError();
}
var user = new ApplicationUser() { UserName = model.Email, Email = model.Email };
IdentityResult result = await UserManager.CreateAsync(user);
if (!result.Succeeded)
{
return GetErrorResult(result);
}
result = await UserManager.AddLoginAsync(user.Id, info.Login);
if (!result.Succeeded)
{
return GetErrorResult(result);
}
return Ok();
}
protected override void Dispose(bool disposing)
{
if (disposing && _userManager != null)
{
_userManager.Dispose();
_userManager = null;
}
base.Dispose(disposing);
}
#region Helpers
private IAuthenticationManager Authentication
{
get { return Request.GetOwinContext().Authentication; }
}
private IHttpActionResult GetErrorResult(IdentityResult result)
{
if (result == null)
{
return InternalServerError();
}
if (!result.Succeeded)
{
if (result.Errors != null)
{
foreach (string error in result.Errors)
{
ModelState.AddModelError("", error);
}
}
if (ModelState.IsValid)
{
// No ModelState errors are available to send, so just return an empty BadRequest.
return BadRequest();
}
return BadRequest(ModelState);
}
return null;
}
private class ExternalLoginData
{
public string LoginProvider { get; set; }
public string ProviderKey { get; set; }
public string UserName { get; set; }
public IList<Claim> GetClaims()
{
IList<Claim> claims = new List<Claim>();
claims.Add(new Claim(ClaimTypes.NameIdentifier, ProviderKey, null, LoginProvider));
if (UserName != null)
{
claims.Add(new Claim(ClaimTypes.Name, UserName, null, LoginProvider));
}
return claims;
}
public static ExternalLoginData FromIdentity(ClaimsIdentity identity)
{
if (identity == null)
{
return null;
}
Claim providerKeyClaim = identity.FindFirst(ClaimTypes.NameIdentifier);
if (providerKeyClaim == null || String.IsNullOrEmpty(providerKeyClaim.Issuer)
|| String.IsNullOrEmpty(providerKeyClaim.Value))
{
return null;
}
if (providerKeyClaim.Issuer == ClaimsIdentity.DefaultIssuer)
{
return null;
}
return new ExternalLoginData
{
LoginProvider = providerKeyClaim.Issuer,
ProviderKey = providerKeyClaim.Value,
UserName = identity.FindFirstValue(ClaimTypes.Name)
};
}
}
private static class RandomOAuthStateGenerator
{
private static RandomNumberGenerator _random = new RNGCryptoServiceProvider();
public static string Generate(int strengthInBits)
{
const int bitsPerByte = 8;
if (strengthInBits % bitsPerByte != 0)
{
throw new ArgumentException("strengthInBits must be evenly divisible by 8.", "strengthInBits");
}
int strengthInBytes = strengthInBits / bitsPerByte;
byte[] data = new byte[strengthInBytes];
_random.GetBytes(data);
return HttpServerUtility.UrlTokenEncode(data);
}
}
#endregion
}
}

Просмотреть файл

@ -1,18 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace OlympicGames.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Title = "Home Page";
return View();
}
}
}

Просмотреть файл

@ -1,40 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
namespace OlympicGames.Controllers
{
[Authorize]
public class ValuesController : ApiController
{
// GET api/values
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
// GET api/values/5
public string Get(int id)
{
return "value";
}
// POST api/values
public void Post([FromBody]string value)
{
}
// PUT api/values/5
public void Put(int id, [FromBody]string value)
{
}
// DELETE api/values/5
public void Delete(int id)
{
}
}
}

Просмотреть файл

@ -1 +0,0 @@
<%@ Application Codebehind="Global.asax.cs" Inherits="OlympicGames.WebApiApplication" Language="C#" %>

Просмотреть файл

@ -1,23 +0,0 @@
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 OlympicGames
{
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);
}
}
}

Просмотреть файл

@ -1,84 +0,0 @@
using System;
using System.ComponentModel.DataAnnotations;
using Newtonsoft.Json;
namespace OlympicGames.Models
{
// Models used as parameters to AccountController actions.
public class AddExternalLoginBindingModel
{
[Required]
[Display(Name = "External access token")]
public string ExternalAccessToken { get; set; }
}
public class ChangePasswordBindingModel
{
[Required]
[DataType(DataType.Password)]
[Display(Name = "Current password")]
public string OldPassword { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "New password")]
public string NewPassword { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm new password")]
[Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
}
public class RegisterBindingModel
{
[Required]
[Display(Name = "Email")]
public string Email { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
}
public class RegisterExternalBindingModel
{
[Required]
[Display(Name = "Email")]
public string Email { get; set; }
}
public class RemoveLoginBindingModel
{
[Required]
[Display(Name = "Login provider")]
public string LoginProvider { get; set; }
[Required]
[Display(Name = "Provider key")]
public string ProviderKey { get; set; }
}
public class SetPasswordBindingModel
{
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "New password")]
public string NewPassword { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm new password")]
[Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
}
}

Просмотреть файл

@ -1,43 +0,0 @@
using System;
using System.Collections.Generic;
namespace OlympicGames.Models
{
// Models returned by AccountController actions.
public class ExternalLoginViewModel
{
public string Name { get; set; }
public string Url { get; set; }
public string State { get; set; }
}
public class ManageInfoViewModel
{
public string LocalLoginProvider { get; set; }
public string Email { get; set; }
public IEnumerable<UserLoginInfoViewModel> Logins { get; set; }
public IEnumerable<ExternalLoginViewModel> ExternalLoginProviders { get; set; }
}
public class UserInfoViewModel
{
public string Email { get; set; }
public bool HasRegistered { get; set; }
public string LoginProvider { get; set; }
}
public class UserLoginInfoViewModel
{
public string LoginProvider { get; set; }
public string ProviderKey { get; set; }
}
}

Просмотреть файл

@ -1,33 +0,0 @@
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.AspNet.Identity.Owin;
namespace OlympicGames.Models
{
// You can add profile data for the user by adding more properties to your ApplicationUser class, please visit http://go.microsoft.com/fwlink/?LinkID=317594 to learn more.
public class ApplicationUser : IdentityUser
{
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager, string authenticationType)
{
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
var userIdentity = await manager.CreateIdentityAsync(this, authenticationType);
// Add custom user claims here
return userIdentity;
}
}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
}

Просмотреть файл

@ -1,332 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.0\build\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props" Condition="Exists('..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.0\build\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props')" />
<Import Project="..\packages\Microsoft.Net.Compilers.1.0.0\build\Microsoft.Net.Compilers.props" Condition="Exists('..\packages\Microsoft.Net.Compilers.1.0.0\build\Microsoft.Net.Compilers.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>{ABFAA97D-7510-4C0E-B736-FBD01558B628}</ProjectGuid>
<ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>OlympicGames</RootNamespace>
<AssemblyName>OlympicGames</AssemblyName>
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
<MvcBuildViews>false</MvcBuildViews>
<UseIISExpress>true</UseIISExpress>
<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' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.0\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll</HintPath>
<Private>True</Private>
</Reference>
<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.6.0.4\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System.Net.Http">
</Reference>
<Reference Include="System.Net.Http.Formatting, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll</HintPath>
</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.3\lib\net45\System.Web.Helpers.dll</HintPath>
</Reference>
<Reference Include="System.Web.Http, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll</HintPath>
</Reference>
<Reference Include="System.Web.Http.WebHost, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.WebHost.5.2.3\lib\net45\System.Web.Http.WebHost.dll</HintPath>
</Reference>
<Reference Include="System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Private>True</Private>
<HintPath>..\packages\Microsoft.AspNet.Mvc.5.2.3\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.3\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.3\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.3\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.3\lib\net45\System.Web.WebPages.Razor.dll</HintPath>
</Reference>
<Reference Include="WebGrease">
<Private>True</Private>
<HintPath>..\packages\WebGrease.1.5.2\lib\WebGrease.dll</HintPath>
</Reference>
<Reference Include="Antlr3.Runtime">
<Private>True</Private>
<HintPath>..\packages\Antlr.3.4.1.9004\lib\Antlr3.Runtime.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Reference Include="EntityFramework">
<HintPath>..\packages\EntityFramework.6.1.3\lib\net45\EntityFramework.dll</HintPath>
</Reference>
<Reference Include="EntityFramework.SqlServer">
<HintPath>..\packages\EntityFramework.6.1.3\lib\net45\EntityFramework.SqlServer.dll</HintPath>
</Reference>
<Reference Include="Microsoft.AspNet.Identity.Core">
<HintPath>..\packages\Microsoft.AspNet.Identity.Core.2.2.1\lib\net45\Microsoft.AspNet.Identity.Core.dll</HintPath>
</Reference>
<Reference Include="Microsoft.AspNet.Identity.Owin">
<HintPath>..\packages\Microsoft.AspNet.Identity.Owin.2.2.1\lib\net45\Microsoft.AspNet.Identity.Owin.dll</HintPath>
</Reference>
<Reference Include="Microsoft.AspNet.Identity.EntityFramework">
<HintPath>..\packages\Microsoft.AspNet.Identity.EntityFramework.2.2.1\lib\net45\Microsoft.AspNet.Identity.EntityFramework.dll</HintPath>
</Reference>
<Reference Include="Owin">
<HintPath>..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Owin">
<HintPath>..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Owin.Host.SystemWeb">
<HintPath>..\packages\Microsoft.Owin.Host.SystemWeb.3.0.1\lib\net45\Microsoft.Owin.Host.SystemWeb.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Owin.Security">
<HintPath>..\packages\Microsoft.Owin.Security.3.0.1\lib\net45\Microsoft.Owin.Security.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Owin.Security.Facebook">
<HintPath>..\packages\Microsoft.Owin.Security.Facebook.3.0.1\lib\net45\Microsoft.Owin.Security.Facebook.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Owin.Security.Cookies">
<HintPath>..\packages\Microsoft.Owin.Security.Cookies.3.0.1\lib\net45\Microsoft.Owin.Security.Cookies.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Owin.Security.OAuth">
<HintPath>..\packages\Microsoft.Owin.Security.OAuth.3.0.1\lib\net45\Microsoft.Owin.Security.OAuth.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Owin.Security.Google">
<HintPath>..\packages\Microsoft.Owin.Security.Google.3.0.1\lib\net45\Microsoft.Owin.Security.Google.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Owin.Security.Twitter">
<HintPath>..\packages\Microsoft.Owin.Security.Twitter.3.0.1\lib\net45\Microsoft.Owin.Security.Twitter.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Owin.Security.MicrosoftAccount">
<HintPath>..\packages\Microsoft.Owin.Security.MicrosoftAccount.3.0.1\lib\net45\Microsoft.Owin.Security.MicrosoftAccount.dll</HintPath>
</Reference>
<Reference Include="System.Web.Http.Owin">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Owin.5.2.3\lib\net45\System.Web.Http.Owin.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="App_Start\BundleConfig.cs" />
<Compile Include="App_Start\FilterConfig.cs" />
<Compile Include="App_Start\IdentityConfig.cs" />
<Compile Include="App_Start\RouteConfig.cs" />
<Compile Include="App_Start\Startup.Auth.cs" />
<Compile Include="App_Start\WebApiConfig.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="Controllers\AccountController.cs" />
<Compile Include="Controllers\HomeController.cs" />
<Compile Include="Controllers\ValuesController.cs" />
<Compile Include="Global.asax.cs">
<DependentUpon>Global.asax</DependentUpon>
</Compile>
<Compile Include="Models\AccountBindingModels.cs" />
<Compile Include="Models\AccountViewModels.cs" />
<Compile Include="Models\IdentityModels.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Providers\ApplicationOAuthProvider.cs" />
<Compile Include="Results\ChallengeResult.cs" />
<Compile Include="Startup.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="App_Data\Olympics.mdf" />
<Content Include="App_Data\Olympics.sql" />
<Content Include="App_Data\Olympics_log.ldf">
<DependentUpon>Olympics.mdf</DependentUpon>
</Content>
<Content Include="Areas\HelpPage\HelpPage.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="Scripts\bootstrap.min.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" />
<None Include="Scripts\jquery-1.10.2.intellisense.js" />
<Content Include="Scripts\jquery-1.10.2.js" />
<Content Include="Scripts\jquery-1.10.2.min.js" />
<None Include="Scripts\jquery.validate-vsdoc.js" />
<Content Include="Scripts\jquery.validate.js" />
<Content Include="Scripts\jquery.validate.min.js" />
<Content Include="Scripts\jquery.validate.unobtrusive.js" />
<Content Include="Scripts\jquery.validate.unobtrusive.min.js" />
<Content Include="Scripts\modernizr-2.6.2.js" />
<Content Include="Scripts\respond.js" />
<Content Include="Scripts\respond.min.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="Scripts\_references.js" />
<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 />
<ItemGroup>
<Content Include="fonts\glyphicons-halflings-regular.woff" />
<Content Include="fonts\glyphicons-halflings-regular.ttf" />
<Content Include="fonts\glyphicons-halflings-regular.eot" />
<Content Include="packages.config" />
<None Include="Project_Readme.html" />
<Content Include="Scripts\jquery-1.10.2.min.map" />
</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>61109</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>http://localhost:61109/</IISUrl>
<NTLMAuthentication>False</NTLMAuthentication>
<UseCustomServer>False</UseCustomServer>
<CustomServerUrl>
</CustomServerUrl>
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
</WebProjectProperties>
</FlavorProperties>
</VisualStudio>
</ProjectExtensions>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Microsoft.Net.Compilers.1.0.0\build\Microsoft.Net.Compilers.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Net.Compilers.1.0.0\build\Microsoft.Net.Compilers.props'))" />
<Error Condition="!Exists('..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.0\build\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.0\build\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,34 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<UseIISExpress>true</UseIISExpress>
<ProjectView>ShowAllFiles</ProjectView>
<WebStackScaffolding_ControllerDialogWidth>600</WebStackScaffolding_ControllerDialogWidth>
<WebStackScaffolding_DbContextDialogWidth>600</WebStackScaffolding_DbContextDialogWidth>
</PropertyGroup>
<ProjectExtensions>
<VisualStudio>
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
<WebProjectProperties>
<StartPageUrl>
</StartPageUrl>
<StartAction>CurrentPage</StartAction>
<AspNetDebugging>True</AspNetDebugging>
<SilverlightDebugging>False</SilverlightDebugging>
<NativeDebugging>False</NativeDebugging>
<SQLDebugging>False</SQLDebugging>
<ExternalProgram>
</ExternalProgram>
<StartExternalURL>
</StartExternalURL>
<StartCmdLineArguments>
</StartCmdLineArguments>
<StartWorkingDirectory>
</StartWorkingDirectory>
<EnableENC>True</EnableENC>
<AlwaysStartWebServerOnDebug>True</AlwaysStartWebServerOnDebug>
</WebProjectProperties>
</FlavorProperties>
</VisualStudio>
</ProjectExtensions>
</Project>

Просмотреть файл

@ -1,149 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Your ASP.NET application</title>
<style>
body {
background: #fff;
color: #505050;
font: 14px 'Segoe UI', tahoma, arial, helvetica, sans-serif;
margin: 20px;
padding: 0;
}
#header {
background: #efefef;
padding: 0;
}
h1 {
font-size: 48px;
font-weight: normal;
margin: 0;
padding: 0 30px;
line-height: 150px;
}
p {
font-size: 20px;
color: #fff;
background: #969696;
padding: 0 30px;
line-height: 50px;
}
#main {
padding: 5px 30px;
}
.section {
width: 21.7%;
float: left;
margin: 0 0 0 4%;
}
.section h2 {
font-size: 13px;
text-transform: uppercase;
margin: 0;
border-bottom: 1px solid silver;
padding-bottom: 12px;
margin-bottom: 8px;
}
.section.first {
margin-left: 0;
}
.section.first h2 {
font-size: 24px;
text-transform: none;
margin-bottom: 25px;
border: none;
}
.section.first li {
border-top: 1px solid silver;
padding: 8px 0;
}
.section.last {
margin-right: 0;
}
ul {
list-style: none;
padding: 0;
margin: 0;
line-height: 20px;
}
li {
padding: 4px 0;
}
a {
color: #267cb2;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
</style>
</head>
<body>
<div id="header">
<h1>Your ASP.NET application</h1>
<p>Congratulations! You've created a project</p>
</div>
<div id="main">
<div class="section first">
<h2>This application consists of:</h2>
<ul>
<li><a href="http://go.microsoft.com/fwlink/?LinkID=615543">Help Page</a> for documenting your Web APIs</li>
<li>Theming using <a href="http://go.microsoft.com/fwlink/?LinkID=615519">Bootstrap</a></li>
<li><a href="http://go.microsoft.com/fwlink/?LinkID=320957">Authentication</a>, if selected, shows how to register and sign in</li>
<li>ASP.NET features managed using <a href="http://go.microsoft.com/fwlink/?LinkID=320958">NuGet</a></li>
</ul>
</div>
<div class="section">
<h2>Customize app</h2>
<ul>
<li><a href="http://go.microsoft.com/fwlink/?LinkID=320959">Get started with HTTP services using ASP.NET Web API</a></li>
<li><a href="http://go.microsoft.com/fwlink/?LinkID=320960">Change the site's theme</a></li>
<li><a href="http://go.microsoft.com/fwlink/?LinkID=320961">Add more libraries using NuGet</a></li>
<li><a href="http://go.microsoft.com/fwlink/?LinkID=320962">Configure authentication</a></li>
<li><a href="http://go.microsoft.com/fwlink/?LinkID=320963">Scaffold an ASP.NET Web API from a model</a></li>
<li><a href="http://go.microsoft.com/fwlink/?LinkID=615545">Secure your web API</a></li>
<li><a href="http://go.microsoft.com/fwlink/?LinkID=615544">Access your web API on different devices</a></li>
<li><a href="http://go.microsoft.com/fwlink/?LinkID=615546">Enable tracing for testing and debugging</a></li>
<li><a href="http://go.microsoft.com/fwlink/?LinkID=615530">Add real-time web with ASP.NET SignalR</a></li>
<li><a href="http://go.microsoft.com/fwlink/?LinkID=615531">Add components using Scaffolding</a></li>
<li><a href="http://go.microsoft.com/fwlink/?LinkID=615533">Share your project</a></li>
</ul>
</div>
<div class="section">
<h2>Deploy</h2>
<ul>
<li><a href="http://go.microsoft.com/fwlink/?LinkID=615534">Ensure your app is ready for production</a></li>
<li><a href="http://go.microsoft.com/fwlink/?LinkID=615535">Microsoft Azure</a></li>
<li><a href="http://go.microsoft.com/fwlink/?LinkID=615536">Hosting providers</a></li>
</ul>
</div>
<div class="section last">
<h2>Get help</h2>
<ul>
<li><a href="http://go.microsoft.com/fwlink/?LinkID=615537">Get help</a></li>
<li><a href="http://go.microsoft.com/fwlink/?LinkID=615538">Get more templates</a></li>
</ul>
</div>
</div>
</body>
</html>

Просмотреть файл

@ -1,35 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("OlympicGames")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("OlympicGames")]
[assembly: AssemblyCopyright("Copyright © 2016")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("26db3522-ae2f-4f53-8f42-6caae5dd8b62")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

Просмотреть файл

@ -1,98 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.OAuth;
using OlympicGames.Models;
namespace OlympicGames.Providers
{
public class ApplicationOAuthProvider : OAuthAuthorizationServerProvider
{
private readonly string _publicClientId;
public ApplicationOAuthProvider(string publicClientId)
{
if (publicClientId == null)
{
throw new ArgumentNullException("publicClientId");
}
_publicClientId = publicClientId;
}
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>();
ApplicationUser user = await userManager.FindAsync(context.UserName, context.Password);
if (user == null)
{
context.SetError("invalid_grant", "The user name or password is incorrect.");
return;
}
ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager,
OAuthDefaults.AuthenticationType);
ClaimsIdentity cookiesIdentity = await user.GenerateUserIdentityAsync(userManager,
CookieAuthenticationDefaults.AuthenticationType);
AuthenticationProperties properties = CreateProperties(user.UserName);
AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties);
context.Validated(ticket);
context.Request.Context.Authentication.SignIn(cookiesIdentity);
}
public override Task TokenEndpoint(OAuthTokenEndpointContext context)
{
foreach (KeyValuePair<string, string> property in context.Properties.Dictionary)
{
context.AdditionalResponseParameters.Add(property.Key, property.Value);
}
return Task.FromResult<object>(null);
}
public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
// Resource owner password credentials does not provide a client ID.
if (context.ClientId == null)
{
context.Validated();
}
return Task.FromResult<object>(null);
}
public override Task ValidateClientRedirectUri(OAuthValidateClientRedirectUriContext context)
{
if (context.ClientId == _publicClientId)
{
Uri expectedRootUri = new Uri(context.Request.Uri, "/");
if (expectedRootUri.AbsoluteUri == context.RedirectUri)
{
context.Validated();
}
}
return Task.FromResult<object>(null);
}
public static AuthenticationProperties CreateProperties(string userName)
{
IDictionary<string, string> data = new Dictionary<string, string>
{
{ "userName", userName }
};
return new AuthenticationProperties(data);
}
}
}

Просмотреть файл

@ -1,32 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http;
namespace OlympicGames.Results
{
public class ChallengeResult : IHttpActionResult
{
public ChallengeResult(string loginProvider, ApiController controller)
{
LoginProvider = loginProvider;
Request = controller.Request;
}
public string LoginProvider { get; set; }
public HttpRequestMessage Request { get; set; }
public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
Request.GetOwinContext().Authentication.Challenge(LoginProvider);
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
response.RequestMessage = Request;
return Task.FromResult(response);
}
}
}

Двоичные данные
OlympicGames/Scripts/_references.js

Двоичный файл не отображается.

2014
OlympicGames/Scripts/bootstrap.js поставляемый

Разница между файлами не показана из-за своего большого размера Загрузить разницу

21
OlympicGames/Scripts/bootstrap.min.js поставляемый

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Разница между файлами не показана из-за своего большого размера Загрузить разницу

9803
OlympicGames/Scripts/jquery-1.10.2.js поставляемый

Разница между файлами не показана из-за своего большого размера Загрузить разницу

23
OlympicGames/Scripts/jquery-1.10.2.min.js поставляемый

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

1302
OlympicGames/Scripts/jquery.validate-vsdoc.js поставляемый

Разница между файлами не показана из-за своего большого размера Загрузить разницу

1245
OlympicGames/Scripts/jquery.validate.js поставляемый

Разница между файлами не показана из-за своего большого размера Загрузить разницу

16
OlympicGames/Scripts/jquery.validate.min.js поставляемый

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -1,429 +0,0 @@
/* NUGET: BEGIN LICENSE TEXT
*
* Microsoft grants you the right to use these script files for the sole
* purpose of either: (i) interacting through your browser with the Microsoft
* website or online service, subject to the applicable licensing or use
* terms; or (ii) using the files as included with a Microsoft product subject
* to that product's license terms. Microsoft reserves all other rights to the
* files not expressly granted by Microsoft, whether by implication, estoppel
* or otherwise. Insofar as a script file is dual licensed under GPL,
* Microsoft neither took the code under GPL nor distributes it thereunder but
* under the terms set out in this paragraph. All notices and licenses
* below are for informational purposes only.
*
* NUGET: END LICENSE TEXT */
/*!
** Unobtrusive validation support library for jQuery and jQuery Validate
** Copyright (C) Microsoft Corporation. All rights reserved.
*/
/*jslint white: true, browser: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, newcap: true, immed: true, strict: false */
/*global document: false, jQuery: false */
(function ($) {
var $jQval = $.validator,
adapters,
data_validation = "unobtrusiveValidation";
function setValidationValues(options, ruleName, value) {
options.rules[ruleName] = value;
if (options.message) {
options.messages[ruleName] = options.message;
}
}
function splitAndTrim(value) {
return value.replace(/^\s+|\s+$/g, "").split(/\s*,\s*/g);
}
function escapeAttributeValue(value) {
// As mentioned on http://api.jquery.com/category/selectors/
return value.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g, "\\$1");
}
function getModelPrefix(fieldName) {
return fieldName.substr(0, fieldName.lastIndexOf(".") + 1);
}
function appendModelPrefix(value, prefix) {
if (value.indexOf("*.") === 0) {
value = value.replace("*.", prefix);
}
return value;
}
function onError(error, inputElement) { // 'this' is the form element
var container = $(this).find("[data-valmsg-for='" + escapeAttributeValue(inputElement[0].name) + "']"),
replaceAttrValue = container.attr("data-valmsg-replace"),
replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) !== false : null;
container.removeClass("field-validation-valid").addClass("field-validation-error");
error.data("unobtrusiveContainer", container);
if (replace) {
container.empty();
error.removeClass("input-validation-error").appendTo(container);
}
else {
error.hide();
}
}
function onErrors(event, validator) { // 'this' is the form element
var container = $(this).find("[data-valmsg-summary=true]"),
list = container.find("ul");
if (list && list.length && validator.errorList.length) {
list.empty();
container.addClass("validation-summary-errors").removeClass("validation-summary-valid");
$.each(validator.errorList, function () {
$("<li />").html(this.message).appendTo(list);
});
}
}
function onSuccess(error) { // 'this' is the form element
var container = error.data("unobtrusiveContainer"),
replaceAttrValue = container.attr("data-valmsg-replace"),
replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) : null;
if (container) {
container.addClass("field-validation-valid").removeClass("field-validation-error");
error.removeData("unobtrusiveContainer");
if (replace) {
container.empty();
}
}
}
function onReset(event) { // 'this' is the form element
var $form = $(this),
key = '__jquery_unobtrusive_validation_form_reset';
if ($form.data(key)) {
return;
}
// Set a flag that indicates we're currently resetting the form.
$form.data(key, true);
try {
$form.data("validator").resetForm();
} finally {
$form.removeData(key);
}
$form.find(".validation-summary-errors")
.addClass("validation-summary-valid")
.removeClass("validation-summary-errors");
$form.find(".field-validation-error")
.addClass("field-validation-valid")
.removeClass("field-validation-error")
.removeData("unobtrusiveContainer")
.find(">*") // If we were using valmsg-replace, get the underlying error
.removeData("unobtrusiveContainer");
}
function validationInfo(form) {
var $form = $(form),
result = $form.data(data_validation),
onResetProxy = $.proxy(onReset, form),
defaultOptions = $jQval.unobtrusive.options || {},
execInContext = function (name, args) {
var func = defaultOptions[name];
func && $.isFunction(func) && func.apply(form, args);
}
if (!result) {
result = {
options: { // options structure passed to jQuery Validate's validate() method
errorClass: defaultOptions.errorClass || "input-validation-error",
errorElement: defaultOptions.errorElement || "span",
errorPlacement: function () {
onError.apply(form, arguments);
execInContext("errorPlacement", arguments);
},
invalidHandler: function () {
onErrors.apply(form, arguments);
execInContext("invalidHandler", arguments);
},
messages: {},
rules: {},
success: function () {
onSuccess.apply(form, arguments);
execInContext("success", arguments);
}
},
attachValidation: function () {
$form
.off("reset." + data_validation, onResetProxy)
.on("reset." + data_validation, onResetProxy)
.validate(this.options);
},
validate: function () { // a validation function that is called by unobtrusive Ajax
$form.validate();
return $form.valid();
}
};
$form.data(data_validation, result);
}
return result;
}
$jQval.unobtrusive = {
adapters: [],
parseElement: function (element, skipAttach) {
/// <summary>
/// Parses a single HTML element for unobtrusive validation attributes.
/// </summary>
/// <param name="element" domElement="true">The HTML element to be parsed.</param>
/// <param name="skipAttach" type="Boolean">[Optional] true to skip attaching the
/// validation to the form. If parsing just this single element, you should specify true.
/// If parsing several elements, you should specify false, and manually attach the validation
/// to the form when you are finished. The default is false.</param>
var $element = $(element),
form = $element.parents("form")[0],
valInfo, rules, messages;
if (!form) { // Cannot do client-side validation without a form
return;
}
valInfo = validationInfo(form);
valInfo.options.rules[element.name] = rules = {};
valInfo.options.messages[element.name] = messages = {};
$.each(this.adapters, function () {
var prefix = "data-val-" + this.name,
message = $element.attr(prefix),
paramValues = {};
if (message !== undefined) { // Compare against undefined, because an empty message is legal (and falsy)
prefix += "-";
$.each(this.params, function () {
paramValues[this] = $element.attr(prefix + this);
});
this.adapt({
element: element,
form: form,
message: message,
params: paramValues,
rules: rules,
messages: messages
});
}
});
$.extend(rules, { "__dummy__": true });
if (!skipAttach) {
valInfo.attachValidation();
}
},
parse: function (selector) {
/// <summary>
/// Parses all the HTML elements in the specified selector. It looks for input elements decorated
/// with the [data-val=true] attribute value and enables validation according to the data-val-*
/// attribute values.
/// </summary>
/// <param name="selector" type="String">Any valid jQuery selector.</param>
// $forms includes all forms in selector's DOM hierarchy (parent, children and self) that have at least one
// element with data-val=true
var $selector = $(selector),
$forms = $selector.parents()
.addBack()
.filter("form")
.add($selector.find("form"))
.has("[data-val=true]");
$selector.find("[data-val=true]").each(function () {
$jQval.unobtrusive.parseElement(this, true);
});
$forms.each(function () {
var info = validationInfo(this);
if (info) {
info.attachValidation();
}
});
}
};
adapters = $jQval.unobtrusive.adapters;
adapters.add = function (adapterName, params, fn) {
/// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation.</summary>
/// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
/// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).</param>
/// <param name="params" type="Array" optional="true">[Optional] An array of parameter names (strings) that will
/// be extracted from the data-val-nnnn-mmmm HTML attributes (where nnnn is the adapter name, and
/// mmmm is the parameter name).</param>
/// <param name="fn" type="Function">The function to call, which adapts the values from the HTML
/// attributes into jQuery Validate rules and/or messages.</param>
/// <returns type="jQuery.validator.unobtrusive.adapters" />
if (!fn) { // Called with no params, just a function
fn = params;
params = [];
}
this.push({ name: adapterName, params: params, adapt: fn });
return this;
};
adapters.addBool = function (adapterName, ruleName) {
/// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
/// the jQuery Validate validation rule has no parameter values.</summary>
/// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
/// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).</param>
/// <param name="ruleName" type="String" optional="true">[Optional] The name of the jQuery Validate rule. If not provided, the value
/// of adapterName will be used instead.</param>
/// <returns type="jQuery.validator.unobtrusive.adapters" />
return this.add(adapterName, function (options) {
setValidationValues(options, ruleName || adapterName, true);
});
};
adapters.addMinMax = function (adapterName, minRuleName, maxRuleName, minMaxRuleName, minAttribute, maxAttribute) {
/// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
/// the jQuery Validate validation has three potential rules (one for min-only, one for max-only, and
/// one for min-and-max). The HTML parameters are expected to be named -min and -max.</summary>
/// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
/// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).</param>
/// <param name="minRuleName" type="String">The name of the jQuery Validate rule to be used when you only
/// have a minimum value.</param>
/// <param name="maxRuleName" type="String">The name of the jQuery Validate rule to be used when you only
/// have a maximum value.</param>
/// <param name="minMaxRuleName" type="String">The name of the jQuery Validate rule to be used when you
/// have both a minimum and maximum value.</param>
/// <param name="minAttribute" type="String" optional="true">[Optional] The name of the HTML attribute that
/// contains the minimum value. The default is "min".</param>
/// <param name="maxAttribute" type="String" optional="true">[Optional] The name of the HTML attribute that
/// contains the maximum value. The default is "max".</param>
/// <returns type="jQuery.validator.unobtrusive.adapters" />
return this.add(adapterName, [minAttribute || "min", maxAttribute || "max"], function (options) {
var min = options.params.min,
max = options.params.max;
if (min && max) {
setValidationValues(options, minMaxRuleName, [min, max]);
}
else if (min) {
setValidationValues(options, minRuleName, min);
}
else if (max) {
setValidationValues(options, maxRuleName, max);
}
});
};
adapters.addSingleVal = function (adapterName, attribute, ruleName) {
/// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
/// the jQuery Validate validation rule has a single value.</summary>
/// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
/// in the data-val-nnnn HTML attribute(where nnnn is the adapter name).</param>
/// <param name="attribute" type="String">[Optional] The name of the HTML attribute that contains the value.
/// The default is "val".</param>
/// <param name="ruleName" type="String" optional="true">[Optional] The name of the jQuery Validate rule. If not provided, the value
/// of adapterName will be used instead.</param>
/// <returns type="jQuery.validator.unobtrusive.adapters" />
return this.add(adapterName, [attribute || "val"], function (options) {
setValidationValues(options, ruleName || adapterName, options.params[attribute]);
});
};
$jQval.addMethod("__dummy__", function (value, element, params) {
return true;
});
$jQval.addMethod("regex", function (value, element, params) {
var match;
if (this.optional(element)) {
return true;
}
match = new RegExp(params).exec(value);
return (match && (match.index === 0) && (match[0].length === value.length));
});
$jQval.addMethod("nonalphamin", function (value, element, nonalphamin) {
var match;
if (nonalphamin) {
match = value.match(/\W/g);
match = match && match.length >= nonalphamin;
}
return match;
});
if ($jQval.methods.extension) {
adapters.addSingleVal("accept", "mimtype");
adapters.addSingleVal("extension", "extension");
} else {
// for backward compatibility, when the 'extension' validation method does not exist, such as with versions
// of JQuery Validation plugin prior to 1.10, we should use the 'accept' method for
// validating the extension, and ignore mime-type validations as they are not supported.
adapters.addSingleVal("extension", "extension", "accept");
}
adapters.addSingleVal("regex", "pattern");
adapters.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url");
adapters.addMinMax("length", "minlength", "maxlength", "rangelength").addMinMax("range", "min", "max", "range");
adapters.addMinMax("minlength", "minlength").addMinMax("maxlength", "minlength", "maxlength");
adapters.add("equalto", ["other"], function (options) {
var prefix = getModelPrefix(options.element.name),
other = options.params.other,
fullOtherName = appendModelPrefix(other, prefix),
element = $(options.form).find(":input").filter("[name='" + escapeAttributeValue(fullOtherName) + "']")[0];
setValidationValues(options, "equalTo", element);
});
adapters.add("required", function (options) {
// jQuery Validate equates "required" with "mandatory" for checkbox elements
if (options.element.tagName.toUpperCase() !== "INPUT" || options.element.type.toUpperCase() !== "CHECKBOX") {
setValidationValues(options, "required", true);
}
});
adapters.add("remote", ["url", "type", "additionalfields"], function (options) {
var value = {
url: options.params.url,
type: options.params.type || "GET",
data: {}
},
prefix = getModelPrefix(options.element.name);
$.each(splitAndTrim(options.params.additionalfields || options.element.name), function (i, fieldName) {
var paramName = appendModelPrefix(fieldName, prefix);
value.data[paramName] = function () {
var field = $(options.form).find(":input").filter("[name='" + escapeAttributeValue(paramName) + "']");
// For checkboxes and radio buttons, only pick up values from checked fields.
if (field.is(":checkbox")) {
return field.filter(":checked").val() || field.filter(":hidden").val() || '';
}
else if (field.is(":radio")) {
return field.filter(":checked").val() || '';
}
return field.val();
};
});
setValidationValues(options, "remote", value);
});
adapters.add("password", ["min", "nonalphamin", "regex"], function (options) {
if (options.params.min) {
setValidationValues(options, "minlength", options.params.min);
}
if (options.params.nonalphamin) {
setValidationValues(options, "nonalphamin", options.params.nonalphamin);
}
if (options.params.regex) {
setValidationValues(options, "regex", options.params.regex);
}
});
$(function () {
$jQval.unobtrusive.parse(document);
});
}(jQuery));

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

1416
OlympicGames/Scripts/modernizr-2.6.2.js поставляемый

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,340 +0,0 @@
/* NUGET: BEGIN LICENSE TEXT
*
* Microsoft grants you the right to use these script files for the sole
* purpose of either: (i) interacting through your browser with the Microsoft
* website or online service, subject to the applicable licensing or use
* terms; or (ii) using the files as included with a Microsoft product subject
* to that product's license terms. Microsoft reserves all other rights to the
* files not expressly granted by Microsoft, whether by implication, estoppel
* or otherwise. Insofar as a script file is dual licensed under GPL,
* Microsoft neither took the code under GPL nor distributes it thereunder but
* under the terms set out in this paragraph. All notices and licenses
* below are for informational purposes only.
*
* NUGET: END LICENSE TEXT */
/*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas. Dual MIT/BSD license */
/*! NOTE: If you're already including a window.matchMedia polyfill via Modernizr or otherwise, you don't need this part */
window.matchMedia = window.matchMedia || (function(doc, undefined){
var bool,
docElem = doc.documentElement,
refNode = docElem.firstElementChild || docElem.firstChild,
// fakeBody required for <FF4 when executed in <head>
fakeBody = doc.createElement('body'),
div = doc.createElement('div');
div.id = 'mq-test-1';
div.style.cssText = "position:absolute;top:-100em";
fakeBody.style.background = "none";
fakeBody.appendChild(div);
return function(q){
div.innerHTML = '&shy;<style media="'+q+'"> #mq-test-1 { width: 42px; }</style>';
docElem.insertBefore(fakeBody, refNode);
bool = div.offsetWidth == 42;
docElem.removeChild(fakeBody);
return { matches: bool, media: q };
};
})(document);
/*! Respond.js v1.2.0: min/max-width media query polyfill. (c) Scott Jehl. MIT/GPLv2 Lic. j.mp/respondjs */
(function( win ){
//exposed namespace
win.respond = {};
//define update even in native-mq-supporting browsers, to avoid errors
respond.update = function(){};
//expose media query support flag for external use
respond.mediaQueriesSupported = win.matchMedia && win.matchMedia( "only all" ).matches;
//if media queries are supported, exit here
if( respond.mediaQueriesSupported ){ return; }
//define vars
var doc = win.document,
docElem = doc.documentElement,
mediastyles = [],
rules = [],
appendedEls = [],
parsedSheets = {},
resizeThrottle = 30,
head = doc.getElementsByTagName( "head" )[0] || docElem,
base = doc.getElementsByTagName( "base" )[0],
links = head.getElementsByTagName( "link" ),
requestQueue = [],
//loop stylesheets, send text content to translate
ripCSS = function(){
var sheets = links,
sl = sheets.length,
i = 0,
//vars for loop:
sheet, href, media, isCSS;
for( ; i < sl; i++ ){
sheet = sheets[ i ],
href = sheet.href,
media = sheet.media,
isCSS = sheet.rel && sheet.rel.toLowerCase() === "stylesheet";
//only links plz and prevent re-parsing
if( !!href && isCSS && !parsedSheets[ href ] ){
// selectivizr exposes css through the rawCssText expando
if (sheet.styleSheet && sheet.styleSheet.rawCssText) {
translate( sheet.styleSheet.rawCssText, href, media );
parsedSheets[ href ] = true;
} else {
if( (!/^([a-zA-Z:]*\/\/)/.test( href ) && !base)
|| href.replace( RegExp.$1, "" ).split( "/" )[0] === win.location.host ){
requestQueue.push( {
href: href,
media: media
} );
}
}
}
}
makeRequests();
},
//recurse through request queue, get css text
makeRequests = function(){
if( requestQueue.length ){
var thisRequest = requestQueue.shift();
ajax( thisRequest.href, function( styles ){
translate( styles, thisRequest.href, thisRequest.media );
parsedSheets[ thisRequest.href ] = true;
makeRequests();
} );
}
},
//find media blocks in css text, convert to style blocks
translate = function( styles, href, media ){
var qs = styles.match( /@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi ),
ql = qs && qs.length || 0,
//try to get CSS path
href = href.substring( 0, href.lastIndexOf( "/" )),
repUrls = function( css ){
return css.replace( /(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g, "$1" + href + "$2$3" );
},
useMedia = !ql && media,
//vars used in loop
i = 0,
j, fullq, thisq, eachq, eql;
//if path exists, tack on trailing slash
if( href.length ){ href += "/"; }
//if no internal queries exist, but media attr does, use that
//note: this currently lacks support for situations where a media attr is specified on a link AND
//its associated stylesheet has internal CSS media queries.
//In those cases, the media attribute will currently be ignored.
if( useMedia ){
ql = 1;
}
for( ; i < ql; i++ ){
j = 0;
//media attr
if( useMedia ){
fullq = media;
rules.push( repUrls( styles ) );
}
//parse for styles
else{
fullq = qs[ i ].match( /@media *([^\{]+)\{([\S\s]+?)$/ ) && RegExp.$1;
rules.push( RegExp.$2 && repUrls( RegExp.$2 ) );
}
eachq = fullq.split( "," );
eql = eachq.length;
for( ; j < eql; j++ ){
thisq = eachq[ j ];
mediastyles.push( {
media : thisq.split( "(" )[ 0 ].match( /(only\s+)?([a-zA-Z]+)\s?/ ) && RegExp.$2 || "all",
rules : rules.length - 1,
hasquery: thisq.indexOf("(") > -1,
minw : thisq.match( /\(min\-width:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/ ) && parseFloat( RegExp.$1 ) + ( RegExp.$2 || "" ),
maxw : thisq.match( /\(max\-width:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/ ) && parseFloat( RegExp.$1 ) + ( RegExp.$2 || "" )
} );
}
}
applyMedia();
},
lastCall,
resizeDefer,
// returns the value of 1em in pixels
getEmValue = function() {
var ret,
div = doc.createElement('div'),
body = doc.body,
fakeUsed = false;
div.style.cssText = "position:absolute;font-size:1em;width:1em";
if( !body ){
body = fakeUsed = doc.createElement( "body" );
body.style.background = "none";
}
body.appendChild( div );
docElem.insertBefore( body, docElem.firstChild );
ret = div.offsetWidth;
if( fakeUsed ){
docElem.removeChild( body );
}
else {
body.removeChild( div );
}
//also update eminpx before returning
ret = eminpx = parseFloat(ret);
return ret;
},
//cached container for 1em value, populated the first time it's needed
eminpx,
//enable/disable styles
applyMedia = function( fromResize ){
var name = "clientWidth",
docElemProp = docElem[ name ],
currWidth = doc.compatMode === "CSS1Compat" && docElemProp || doc.body[ name ] || docElemProp,
styleBlocks = {},
lastLink = links[ links.length-1 ],
now = (new Date()).getTime();
//throttle resize calls
if( fromResize && lastCall && now - lastCall < resizeThrottle ){
clearTimeout( resizeDefer );
resizeDefer = setTimeout( applyMedia, resizeThrottle );
return;
}
else {
lastCall = now;
}
for( var i in mediastyles ){
var thisstyle = mediastyles[ i ],
min = thisstyle.minw,
max = thisstyle.maxw,
minnull = min === null,
maxnull = max === null,
em = "em";
if( !!min ){
min = parseFloat( min ) * ( min.indexOf( em ) > -1 ? ( eminpx || getEmValue() ) : 1 );
}
if( !!max ){
max = parseFloat( max ) * ( max.indexOf( em ) > -1 ? ( eminpx || getEmValue() ) : 1 );
}
// if there's no media query at all (the () part), or min or max is not null, and if either is present, they're true
if( !thisstyle.hasquery || ( !minnull || !maxnull ) && ( minnull || currWidth >= min ) && ( maxnull || currWidth <= max ) ){
if( !styleBlocks[ thisstyle.media ] ){
styleBlocks[ thisstyle.media ] = [];
}
styleBlocks[ thisstyle.media ].push( rules[ thisstyle.rules ] );
}
}
//remove any existing respond style element(s)
for( var i in appendedEls ){
if( appendedEls[ i ] && appendedEls[ i ].parentNode === head ){
head.removeChild( appendedEls[ i ] );
}
}
//inject active styles, grouped by media type
for( var i in styleBlocks ){
var ss = doc.createElement( "style" ),
css = styleBlocks[ i ].join( "\n" );
ss.type = "text/css";
ss.media = i;
//originally, ss was appended to a documentFragment and sheets were appended in bulk.
//this caused crashes in IE in a number of circumstances, such as when the HTML element had a bg image set, so appending beforehand seems best. Thanks to @dvelyk for the initial research on this one!
head.insertBefore( ss, lastLink.nextSibling );
if ( ss.styleSheet ){
ss.styleSheet.cssText = css;
}
else {
ss.appendChild( doc.createTextNode( css ) );
}
//push to appendedEls to track for later removal
appendedEls.push( ss );
}
},
//tweaked Ajax functions from Quirksmode
ajax = function( url, callback ) {
var req = xmlHttp();
if (!req){
return;
}
req.open( "GET", url, true );
req.onreadystatechange = function () {
if ( req.readyState != 4 || req.status != 200 && req.status != 304 ){
return;
}
callback( req.responseText );
}
if ( req.readyState == 4 ){
return;
}
req.send( null );
},
//define ajax obj
xmlHttp = (function() {
var xmlhttpmethod = false;
try {
xmlhttpmethod = new XMLHttpRequest();
}
catch( e ){
xmlhttpmethod = new ActiveXObject( "Microsoft.XMLHTTP" );
}
return function(){
return xmlhttpmethod;
};
})();
//translate CSS
ripCSS();
//expose update for re-running respond later on
respond.update = ripCSS;
//adjust on resize
function callMedia(){
applyMedia( true );
}
if( win.addEventListener ){
win.addEventListener( "resize", callMedia, false );
}
else if( win.attachEvent ){
win.attachEvent( "onresize", callMedia );
}
})(this);

20
OlympicGames/Scripts/respond.min.js поставляемый
Просмотреть файл

@ -1,20 +0,0 @@
/* NUGET: BEGIN LICENSE TEXT
*
* Microsoft grants you the right to use these script files for the sole
* purpose of either: (i) interacting through your browser with the Microsoft
* website or online service, subject to the applicable licensing or use
* terms; or (ii) using the files as included with a Microsoft product subject
* to that product's license terms. Microsoft reserves all other rights to the
* files not expressly granted by Microsoft, whether by implication, estoppel
* or otherwise. Insofar as a script file is dual licensed under GPL,
* Microsoft neither took the code under GPL nor distributes it thereunder but
* under the terms set out in this paragraph. All notices and licenses
* below are for informational purposes only.
*
* NUGET: END LICENSE TEXT */
/*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas. Dual MIT/BSD license */
/*! NOTE: If you're already including a window.matchMedia polyfill via Modernizr or otherwise, you don't need this part */
window.matchMedia=window.matchMedia||(function(e,f){var c,a=e.documentElement,b=a.firstElementChild||a.firstChild,d=e.createElement("body"),g=e.createElement("div");g.id="mq-test-1";g.style.cssText="position:absolute;top:-100em";d.style.background="none";d.appendChild(g);return function(h){g.innerHTML='&shy;<style media="'+h+'"> #mq-test-1 { width: 42px; }</style>';a.insertBefore(d,b);c=g.offsetWidth==42;a.removeChild(d);return{matches:c,media:h}}})(document);
/*! Respond.js v1.2.0: min/max-width media query polyfill. (c) Scott Jehl. MIT/GPLv2 Lic. j.mp/respondjs */
(function(e){e.respond={};respond.update=function(){};respond.mediaQueriesSupported=e.matchMedia&&e.matchMedia("only all").matches;if(respond.mediaQueriesSupported){return}var w=e.document,s=w.documentElement,i=[],k=[],q=[],o={},h=30,f=w.getElementsByTagName("head")[0]||s,g=w.getElementsByTagName("base")[0],b=f.getElementsByTagName("link"),d=[],a=function(){var D=b,y=D.length,B=0,A,z,C,x;for(;B<y;B++){A=D[B],z=A.href,C=A.media,x=A.rel&&A.rel.toLowerCase()==="stylesheet";if(!!z&&x&&!o[z]){if(A.styleSheet&&A.styleSheet.rawCssText){m(A.styleSheet.rawCssText,z,C);o[z]=true}else{if((!/^([a-zA-Z:]*\/\/)/.test(z)&&!g)||z.replace(RegExp.$1,"").split("/")[0]===e.location.host){d.push({href:z,media:C})}}}}u()},u=function(){if(d.length){var x=d.shift();n(x.href,function(y){m(y,x.href,x.media);o[x.href]=true;u()})}},m=function(I,x,z){var G=I.match(/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi),J=G&&G.length||0,x=x.substring(0,x.lastIndexOf("/")),y=function(K){return K.replace(/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,"$1"+x+"$2$3")},A=!J&&z,D=0,C,E,F,B,H;if(x.length){x+="/"}if(A){J=1}for(;D<J;D++){C=0;if(A){E=z;k.push(y(I))}else{E=G[D].match(/@media *([^\{]+)\{([\S\s]+?)$/)&&RegExp.$1;k.push(RegExp.$2&&y(RegExp.$2))}B=E.split(",");H=B.length;for(;C<H;C++){F=B[C];i.push({media:F.split("(")[0].match(/(only\s+)?([a-zA-Z]+)\s?/)&&RegExp.$2||"all",rules:k.length-1,hasquery:F.indexOf("(")>-1,minw:F.match(/\(min\-width:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:F.match(/\(max\-width:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}}j()},l,r,v=function(){var z,A=w.createElement("div"),x=w.body,y=false;A.style.cssText="position:absolute;font-size:1em;width:1em";if(!x){x=y=w.createElement("body");x.style.background="none"}x.appendChild(A);s.insertBefore(x,s.firstChild);z=A.offsetWidth;if(y){s.removeChild(x)}else{x.removeChild(A)}z=p=parseFloat(z);return z},p,j=function(I){var x="clientWidth",B=s[x],H=w.compatMode==="CSS1Compat"&&B||w.body[x]||B,D={},G=b[b.length-1],z=(new Date()).getTime();if(I&&l&&z-l<h){clearTimeout(r);r=setTimeout(j,h);return}else{l=z}for(var E in i){var K=i[E],C=K.minw,J=K.maxw,A=C===null,L=J===null,y="em";if(!!C){C=parseFloat(C)*(C.indexOf(y)>-1?(p||v()):1)}if(!!J){J=parseFloat(J)*(J.indexOf(y)>-1?(p||v()):1)}if(!K.hasquery||(!A||!L)&&(A||H>=C)&&(L||H<=J)){if(!D[K.media]){D[K.media]=[]}D[K.media].push(k[K.rules])}}for(var E in q){if(q[E]&&q[E].parentNode===f){f.removeChild(q[E])}}for(var E in D){var M=w.createElement("style"),F=D[E].join("\n");M.type="text/css";M.media=E;f.insertBefore(M,G.nextSibling);if(M.styleSheet){M.styleSheet.cssText=F}else{M.appendChild(w.createTextNode(F))}q.push(M)}},n=function(x,z){var y=c();if(!y){return}y.open("GET",x,true);y.onreadystatechange=function(){if(y.readyState!=4||y.status!=200&&y.status!=304){return}z(y.responseText)};if(y.readyState==4){return}y.send(null)},c=(function(){var x=false;try{x=new XMLHttpRequest()}catch(y){x=new ActiveXObject("Microsoft.XMLHTTP")}return function(){return x}})();a();respond.update=a;function t(){j(true)}if(e.addEventListener){e.addEventListener("resize",t,false)}else{if(e.attachEvent){e.attachEvent("onresize",t)}}})(this);

Просмотреть файл

@ -1,18 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Owin;
using Owin;
[assembly: OwinStartup(typeof(OlympicGames.Startup))]
namespace OlympicGames
{
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
ConfigureAuth(app);
}
}
}

Просмотреть файл

@ -1,24 +0,0 @@
<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="http://asp.net" class="btn btn-primary btn-lg">Learn more &raquo;</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="http://go.microsoft.com/fwlink/?LinkId=301870">Learn more &raquo;</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="http://go.microsoft.com/fwlink/?LinkId=301871">Learn more &raquo;</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="http://go.microsoft.com/fwlink/?LinkId=301872">Learn more &raquo;</a></p>
</div>
</div>

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше