初始化

This commit is contained in:
2025-11-20 14:38:48 +08:00
commit f9e0cc8a4a
534 changed files with 247694 additions and 0 deletions

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,27 @@
using System.Web;
using System.Web.Optimization;
namespace BLV_API
{
public class BundleConfig
{
// 有关捆绑的详细信息,请访问 https://go.microsoft.com/fwlink/?LinkId=301862
public static void RegisterBundles(BundleCollection bundles)
{
bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
"~/Scripts/jquery-{version}.js"));
// 使用要用于开发和学习的 Modernizr 的开发版本。然后,当你做好
// 生产准备就绪,请使用 https://modernizr.com 上的生成工具仅选择所需的测试。
bundles.Add(new ScriptBundle("~/bundles/modernizr").Include(
"~/Scripts/modernizr-*"));
bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include(
"~/Scripts/bootstrap.js"));
bundles.Add(new StyleBundle("~/Content/css").Include(
"~/Content/bootstrap.css",
"~/Content/site.css"));
}
}
}

View File

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

View File

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

View File

@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
namespace BLV_API
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API 配置和服务
// Web API 路由
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { code = RouteParameter.Optional }
);
}
}
}

View File

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

View File

@@ -0,0 +1,113 @@
// Uncomment the following to provide samples for PageResult<T>. Must also add the Microsoft.AspNet.WebApi.OData
// package to your project.
////#define Handle_PageResultOfT
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Net.Http.Headers;
using System.Reflection;
using System.Web;
using System.Web.Http;
#if Handle_PageResultOfT
using System.Web.Http.OData;
#endif
namespace PTS_API_V1.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 = "PTS_API_V1.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
}
}

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,467 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Web.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Description;
using PTS_API_V1.Areas.HelpPage.ModelDescriptions;
using PTS_API_V1.Areas.HelpPage.Models;
namespace PTS_API_V1.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);
}
}
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,451 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Reflection;
using System.Runtime.Serialization;
using System.Web.Http;
using System.Web.Http.Description;
using System.Xml.Serialization;
using Newtonsoft.Json;
namespace PTS_API_V1.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;
}
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,444 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Net.Http.Headers;
using System.Web.Http.Description;
using System.Xml.Linq;
using Newtonsoft.Json;
namespace PTS_API_V1.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;
}
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,30 @@
@using System.Net.Http.Headers
@model Dictionary<MediaTypeHeaderValue, object>
@{
// Group the samples into a single tab if they are the same.
Dictionary<string, object> samples = Model.GroupBy(pair => pair.Value).ToDictionary(
pair => String.Join(", ", pair.Select(m => m.Key.ToString()).ToArray()),
pair => pair.Key);
var mediaTypes = samples.Keys;
}
<div>
@foreach (var mediaType in mediaTypes)
{
<h4 class="sample-header">@mediaType</h4>
<div class="sample-content">
<span><b>Sample:</b></span>
@{
var sample = samples[mediaType];
if (sample == null)
{
<p>Sample not available.</p>
}
else
{
@Html.DisplayFor(s => sample);
}
}
</div>
}
</div>

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
@RenderSection("scripts", required: false)
</head>
<body>
@RenderBody()
</body>
</html>

View File

@@ -0,0 +1,41 @@
<?xml version="1.0"?>
<configuration>
<configSections>
<sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
<section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
</sectionGroup>
</configSections>
<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.7.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>

View File

@@ -0,0 +1,4 @@
@{
// Change the Layout path below to blend the look and feel of the help page with your existing web pages
Layout = "~/Views/Shared/_Layout.cshtml";
}

View File

@@ -0,0 +1,161 @@
using System;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Web.Http.Controllers;
using System.Web.Http.Description;
using System.Xml.XPath;
using PTS_API_V1.Areas.HelpPage.ModelDescriptions;
namespace PTS_API_V1.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;
}
}
}

388
BLV_API/BLV_API.csproj Normal file
View File

@@ -0,0 +1,388 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.1\build\net46\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props" Condition="Exists('..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.1\build\net46\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props')" />
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>
</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{749E71B2-D02B-439F-A8D3-623434B7270A}</ProjectGuid>
<ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>BLV_API</RootNamespace>
<AssemblyName>BLV_API</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<MvcBuildViews>false</MvcBuildViews>
<UseIISExpress>true</UseIISExpress>
<Use64BitIISExpress />
<IISExpressSSLPort />
<IISExpressAnonymousAuthentication />
<IISExpressWindowsAuthentication />
<IISExpressUseClassicPipelineMode />
<UseGlobalApplicationHostFile />
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.CSharp" />
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.EnterpriseServices" />
<Reference Include="System.ServiceModel" />
<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.Web.Extensions" />
<Reference Include="System.Web.Services" />
<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.12.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System.Net.Http">
</Reference>
<Reference Include="System.Net.Http.Formatting, Version=5.2.7.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Client.5.2.7\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.7\lib\net45\System.Web.Helpers.dll</HintPath>
</Reference>
<Reference Include="System.Web.Http, Version=5.2.7.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Core.5.2.7\lib\net45\System.Web.Http.dll</HintPath>
</Reference>
<Reference Include="System.Web.Http.WebHost, Version=5.2.7.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.WebHost.5.2.7\lib\net45\System.Web.Http.WebHost.dll</HintPath>
</Reference>
<Reference Include="System.Web.Mvc, Version=5.2.7.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Private>True</Private>
<HintPath>..\packages\Microsoft.AspNet.Mvc.5.2.7\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.7\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.7\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.7\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.7\lib\net45\System.Web.WebPages.Razor.dll</HintPath>
</Reference>
<Reference Include="WebGrease">
<Private>True</Private>
<HintPath>..\packages\WebGrease.1.6.0\lib\WebGrease.dll</HintPath>
</Reference>
<Reference Include="Antlr3.Runtime">
<Private>True</Private>
<HintPath>..\packages\Antlr.3.5.0.2\lib\Antlr3.Runtime.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Reference Include="Microsoft.CodeDom.Providers.DotNetCompilerPlatform">
<HintPath>..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.1\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="App_Start\BundleConfig.cs" />
<Compile Include="App_Start\FilterConfig.cs" />
<Compile Include="App_Start\RouteConfig.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="Connected Services\ServiceReference1\Reference.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Reference.svcmap</DependentUpon>
</Compile>
<Compile Include="Controllers\ApiController.cs" />
<Compile Include="Controllers\HomeController.cs" />
<Compile Include="Controllers\testController.cs" />
<Compile Include="Controllers\ValuesController.cs" />
<Compile Include="Dal\DbProvider.cs" />
<Compile Include="Dal\SqlHelper.cs" />
<Compile Include="Global.asax.cs">
<DependentUpon>Global.asax</DependentUpon>
</Compile>
<Compile Include="LogHelper.cs" />
<Compile Include="Models\CRICSEntity.cs" />
<Compile Include="Models\BLVEntity.cs" />
<Compile Include="Models\ExtraData.cs" />
<Compile Include="Models\Luopan2Entity.cs" />
<Compile Include="Models\LuopanEntity.cs" />
<Compile Include="PMSEntity.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
<DependentUpon>Settings.settings</DependentUpon>
</Compile>
<Compile Include="Tools.cs" />
<Compile Include="Web References\boonliverpms\Reference.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Reference.map</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<Content Include="Areas\HelpPage\HelpPage.css" />
<Content Include="Connected Services\ServiceReference1\BLV_API.ServiceReference1.ChangePhoneNumberResponse.datasource">
<DependentUpon>Reference.svcmap</DependentUpon>
</Content>
<Content Include="Connected Services\ServiceReference1\BLV_API.ServiceReference1.CheckIn2Response.datasource">
<DependentUpon>Reference.svcmap</DependentUpon>
</Content>
<Content Include="Connected Services\ServiceReference1\BLV_API.ServiceReference1.CheckInResponse.datasource">
<DependentUpon>Reference.svcmap</DependentUpon>
</Content>
<Content Include="Connected Services\ServiceReference1\BLV_API.ServiceReference1.CheckOutResponse.datasource">
<DependentUpon>Reference.svcmap</DependentUpon>
</Content>
<Content Include="Connected Services\ServiceReference1\BLV_API.ServiceReference1.RentRoomResponse.datasource">
<DependentUpon>Reference.svcmap</DependentUpon>
</Content>
<Content Include="Connected Services\ServiceReference1\BLV_API.ServiceReference1.UploadPhotoResponse.datasource">
<DependentUpon>Reference.svcmap</DependentUpon>
</Content>
<Content Include="Connected Services\ServiceReference1\BLV_API.ServiceReference1.AddHotelInfoResponse.datasource">
<DependentUpon>Reference.svcmap</DependentUpon>
</Content>
<Content Include="Connected Services\ServiceReference1\BLV_API.ServiceReference1.GetPushBaoJing_IsEnableResponse.datasource">
<DependentUpon>Reference.svcmap</DependentUpon>
</Content>
<Content Include="Connected Services\ServiceReference1\BLV_API.ServiceReference1.PushBaoJing_IsEnableResponse.datasource">
<DependentUpon>Reference.svcmap</DependentUpon>
</Content>
<None Include="Connected Services\ServiceReference1\blwws.disco" />
<None Include="Connected Services\ServiceReference1\configuration91.svcinfo" />
<None Include="Connected Services\ServiceReference1\configuration.svcinfo" />
<None Include="Connected Services\ServiceReference1\Reference.svcmap">
<Generator>WCF Proxy Generator</Generator>
<LastGenOutput>Reference.cs</LastGenOutput>
</None>
<Content Include="Content\bootstrap-theme.css" />
<Content Include="Content\bootstrap-theme.min.css" />
<Content Include="Content\bootstrap.css" />
<Content Include="Content\bootstrap.min.css" />
<Content Include="favicon.ico" />
<Content Include="fonts\glyphicons-halflings-regular.svg" />
<Content Include="Global.asax" />
<Content Include="Scripts\bootstrap.js" />
<Content Include="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="Connected Services\ServiceReference1\blwws.wsdl" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<None Include="Scripts\jquery-3.4.1.intellisense.js" />
<Content Include="Scripts\jquery-3.4.1.js" />
<Content Include="Scripts\jquery-3.4.1.min.js" />
<Content Include="Scripts\jquery-3.4.1.slim.js" />
<Content Include="Scripts\jquery-3.4.1.slim.min.js" />
<Content Include="Scripts\modernizr-2.8.3.js" />
<None Include="Web References\boonliverpms\blwws.disco" />
<Content Include="Web.config" />
<Content Include="Web.Debug.config">
<DependentUpon>Web.config</DependentUpon>
</Content>
<Content Include="Web.Release.config">
<DependentUpon>Web.config</DependentUpon>
</Content>
<Content Include="Areas\HelpPage\Views\_ViewStart.cshtml" />
<Content Include="Content\Site.css" />
<Content Include="Views\Web.config" />
<Content Include="Views\_ViewStart.cshtml" />
<Content Include="Views\Home\Index.cshtml" />
<Content Include="Views\Shared\Error.cshtml" />
<Content Include="Views\Shared\_Layout.cshtml" />
<Content Include="Views\Api\Index.cshtml" />
<None Include="Web References\boonliverpms\blwws.wsdl" />
<None Include="Web References\boonliverpms\Reference.map">
<Generator>MSDiscoCodeGenerator</Generator>
<LastGenOutput>Reference.cs</LastGenOutput>
</None>
</ItemGroup>
<ItemGroup>
<Folder Include="App_Data\" />
<Folder Include="Views\test\" />
</ItemGroup>
<ItemGroup>
<Content Include="fonts\glyphicons-halflings-regular.woff2" />
</ItemGroup>
<ItemGroup>
<Content Include="fonts\glyphicons-halflings-regular.woff" />
</ItemGroup>
<ItemGroup>
<Content Include="fonts\glyphicons-halflings-regular.ttf" />
</ItemGroup>
<ItemGroup>
<Content Include="fonts\glyphicons-halflings-regular.eot" />
</ItemGroup>
<ItemGroup>
<Content Include="Content\bootstrap.min.css.map" />
</ItemGroup>
<ItemGroup>
<Content Include="Content\bootstrap.css.map" />
</ItemGroup>
<ItemGroup>
<Content Include="Content\bootstrap-theme.min.css.map" />
</ItemGroup>
<ItemGroup>
<Content Include="Content\bootstrap-theme.css.map" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
<Content Include="Scripts\jquery-3.4.1.slim.min.map" />
<Content Include="Scripts\jquery-3.4.1.min.map" />
</ItemGroup>
<ItemGroup>
<WCFMetadata Include="Connected Services\" />
</ItemGroup>
<ItemGroup>
<WCFMetadataStorage Include="Connected Services\ServiceReference1\" />
</ItemGroup>
<ItemGroup>
<WebReferences Include="Web References\" />
</ItemGroup>
<ItemGroup>
<WebReferenceUrl Include="http://pms.boonlive-rcu.com:89/blwws.asmx">
<UrlBehavior>Dynamic</UrlBehavior>
<RelPath>Web References\boonliverpms\</RelPath>
<UpdateFromURL>http://pms.boonlive-rcu.com:89/blwws.asmx</UpdateFromURL>
<ServiceLocationURL>
</ServiceLocationURL>
<CachedDynamicPropName>
</CachedDynamicPropName>
<CachedAppSettingsObjectName>Settings</CachedAppSettingsObjectName>
<CachedSettingsPropName>BLV_API_boonliverpms_blwws</CachedSettingsPropName>
</WebReferenceUrl>
</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>58019</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>http://localhost:58019/</IISUrl>
<NTLMAuthentication>False</NTLMAuthentication>
<UseCustomServer>False</UseCustomServer>
<CustomServerUrl>
</CustomServerUrl>
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
</WebProjectProperties>
</FlavorProperties>
</VisualStudio>
</ProjectExtensions>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.1\build\net46\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.1\build\net46\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>

View File

@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<LastActiveSolutionConfig>Debug|Any CPU</LastActiveSolutionConfig>
<UseIISExpress>true</UseIISExpress>
<Use64BitIISExpress />
<IISExpressSSLPort />
<IISExpressAnonymousAuthentication />
<IISExpressWindowsAuthentication />
<IISExpressUseClassicPipelineMode />
<UseGlobalApplicationHostFile />
<NameOfLastUsedPublishProfile>E:\tian\chongxin\PMS\BLV_API\BLV_API\Properties\PublishProfiles\FolderProfile.pubxml</NameOfLastUsedPublishProfile>
<ProjectView>ProjectFiles</ProjectView>
</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>False</AlwaysStartWebServerOnDebug>
</WebProjectProperties>
</FlavorProperties>
</VisualStudio>
</ProjectExtensions>
</Project>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is automatically generated by Visual Studio .Net. It is
used to store generic object data source configuration information.
Renaming the file extension or editing the content of this file may
cause the file to be unrecognizable by the program.
-->
<GenericObjectDataSource DisplayName="AddHotelInfoResponse" Version="1.0" xmlns="urn:schemas-microsoft-com:xml-msdatasource">
<TypeInfo>BLV_API.ServiceReference1.AddHotelInfoResponse, Connected Services.ServiceReference1.Reference.cs.dll, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null</TypeInfo>
</GenericObjectDataSource>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is automatically generated by Visual Studio .Net. It is
used to store generic object data source configuration information.
Renaming the file extension or editing the content of this file may
cause the file to be unrecognizable by the program.
-->
<GenericObjectDataSource DisplayName="ChangePhoneNumberResponse" Version="1.0" xmlns="urn:schemas-microsoft-com:xml-msdatasource">
<TypeInfo>BLV_API.ServiceReference1.ChangePhoneNumberResponse, Connected Services.ServiceReference1.Reference.cs.dll, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null</TypeInfo>
</GenericObjectDataSource>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is automatically generated by Visual Studio .Net. It is
used to store generic object data source configuration information.
Renaming the file extension or editing the content of this file may
cause the file to be unrecognizable by the program.
-->
<GenericObjectDataSource DisplayName="CheckIn2Response" Version="1.0" xmlns="urn:schemas-microsoft-com:xml-msdatasource">
<TypeInfo>BLV_API.ServiceReference1.CheckIn2Response, Connected Services.ServiceReference1.Reference.cs.dll, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null</TypeInfo>
</GenericObjectDataSource>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is automatically generated by Visual Studio .Net. It is
used to store generic object data source configuration information.
Renaming the file extension or editing the content of this file may
cause the file to be unrecognizable by the program.
-->
<GenericObjectDataSource DisplayName="CheckInResponse" Version="1.0" xmlns="urn:schemas-microsoft-com:xml-msdatasource">
<TypeInfo>BLV_API.ServiceReference1.CheckInResponse, Connected Services.ServiceReference1.Reference.cs.dll, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null</TypeInfo>
</GenericObjectDataSource>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is automatically generated by Visual Studio .Net. It is
used to store generic object data source configuration information.
Renaming the file extension or editing the content of this file may
cause the file to be unrecognizable by the program.
-->
<GenericObjectDataSource DisplayName="CheckOutResponse" Version="1.0" xmlns="urn:schemas-microsoft-com:xml-msdatasource">
<TypeInfo>BLV_API.ServiceReference1.CheckOutResponse, Connected Services.ServiceReference1.Reference.cs.dll, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null</TypeInfo>
</GenericObjectDataSource>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is automatically generated by Visual Studio .Net. It is
used to store generic object data source configuration information.
Renaming the file extension or editing the content of this file may
cause the file to be unrecognizable by the program.
-->
<GenericObjectDataSource DisplayName="GetPushBaoJing_IsEnableResponse" Version="1.0" xmlns="urn:schemas-microsoft-com:xml-msdatasource">
<TypeInfo>BLV_API.ServiceReference1.GetPushBaoJing_IsEnableResponse, Connected Services.ServiceReference1.Reference.cs.dll, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null</TypeInfo>
</GenericObjectDataSource>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is automatically generated by Visual Studio .Net. It is
used to store generic object data source configuration information.
Renaming the file extension or editing the content of this file may
cause the file to be unrecognizable by the program.
-->
<GenericObjectDataSource DisplayName="PushBaoJing_IsEnableResponse" Version="1.0" xmlns="urn:schemas-microsoft-com:xml-msdatasource">
<TypeInfo>BLV_API.ServiceReference1.PushBaoJing_IsEnableResponse, Connected Services.ServiceReference1.Reference.cs.dll, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null</TypeInfo>
</GenericObjectDataSource>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is automatically generated by Visual Studio .Net. It is
used to store generic object data source configuration information.
Renaming the file extension or editing the content of this file may
cause the file to be unrecognizable by the program.
-->
<GenericObjectDataSource DisplayName="RentRoomResponse" Version="1.0" xmlns="urn:schemas-microsoft-com:xml-msdatasource">
<TypeInfo>BLV_API.ServiceReference1.RentRoomResponse, Connected Services.ServiceReference1.Reference.cs.dll, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null</TypeInfo>
</GenericObjectDataSource>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is automatically generated by Visual Studio .Net. It is
used to store generic object data source configuration information.
Renaming the file extension or editing the content of this file may
cause the file to be unrecognizable by the program.
-->
<GenericObjectDataSource DisplayName="UploadPhotoResponse" Version="1.0" xmlns="urn:schemas-microsoft-com:xml-msdatasource">
<TypeInfo>BLV_API.ServiceReference1.UploadPhotoResponse, Connected Services.ServiceReference1.Reference.cs.dll, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null</TypeInfo>
</GenericObjectDataSource>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<ReferenceGroup xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ID="8fdadb96-e9f6-4bb9-ae98-9828dca06b86" xmlns="urn:schemas-microsoft-com:xml-wcfservicemap">
<ClientOptions>
<GenerateAsynchronousMethods>false</GenerateAsynchronousMethods>
<GenerateTaskBasedAsynchronousMethod>true</GenerateTaskBasedAsynchronousMethod>
<EnableDataBinding>true</EnableDataBinding>
<ExcludedTypes />
<ImportXmlTypes>false</ImportXmlTypes>
<GenerateInternalTypes>false</GenerateInternalTypes>
<GenerateMessageContracts>false</GenerateMessageContracts>
<NamespaceMappings />
<CollectionMappings />
<GenerateSerializableTypes>true</GenerateSerializableTypes>
<Serializer>Auto</Serializer>
<UseSerializerForFaults>true</UseSerializerForFaults>
<ReferenceAllAssemblies>true</ReferenceAllAssemblies>
<ReferencedAssemblies />
<ReferencedDataContractTypes />
<ServiceContractMappings />
</ClientOptions>
<MetadataSources>
<MetadataSource Address="http://pms.boonlive-rcu.com:89/blwws.asmx" Protocol="http" SourceId="1" />
</MetadataSources>
<Metadata>
<MetadataFile FileName="blwws.disco" MetadataType="Disco" ID="b59debda-a4b8-4b03-9fec-729fa926c54d" SourceId="1" SourceUrl="http://pms.boonlive-rcu.com:89/blwws.asmx?disco" />
<MetadataFile FileName="blwws.wsdl" MetadataType="Wsdl" ID="034b71b0-7d46-4c75-85a9-5488d35a568c" SourceId="1" SourceUrl="http://pms.boonlive-rcu.com:89/blwws.asmx?wsdl" />
</Metadata>
<Extensions>
<ExtensionFile FileName="configuration91.svcinfo" Name="configuration91.svcinfo" />
<ExtensionFile FileName="configuration.svcinfo" Name="configuration.svcinfo" />
</Extensions>
</ReferenceGroup>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<discovery xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.xmlsoap.org/disco/">
<contractRef ref="http://pms.boonlive-rcu.com:89/blwws.asmx?wsdl" docRef="http://pms.boonlive-rcu.com:89/blwws.asmx" xmlns="http://schemas.xmlsoap.org/disco/scl/" />
<soap address="http://pms.boonlive-rcu.com:89/blwws.asmx" xmlns:q1="http://www.blw.com/" binding="q1:blwwsSoap" xmlns="http://schemas.xmlsoap.org/disco/soap/" />
<soap address="http://pms.boonlive-rcu.com:89/blwws.asmx" xmlns:q2="http://www.blw.com/" binding="q2:blwwsSoap12" xmlns="http://schemas.xmlsoap.org/disco/soap/" />
</discovery>

View File

@@ -0,0 +1,456 @@
<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:tns="http://www.blw.com/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" targetNamespace="http://www.blw.com/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:types>
<s:schema elementFormDefault="qualified" targetNamespace="http://www.blw.com/">
<s:element name="CheckIn">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="key" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="code" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="roomNumber" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="checkInDate" type="s:dateTime" />
<s:element minOccurs="0" maxOccurs="1" name="xmlString" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="errorMsg" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="phoneNumber" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="idNumber" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="CheckInResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="CheckInResult" type="s:boolean" />
<s:element minOccurs="0" maxOccurs="1" name="errorMsg" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="CheckIn2">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="key" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="code" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="roomNumber" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="checkInDate" type="s:dateTime" />
<s:element minOccurs="0" maxOccurs="1" name="xmlString" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="errorMsg" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="checkInID" type="s:long" />
<s:element minOccurs="0" maxOccurs="1" name="phoneNumber" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="idNumber" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="CheckIn2Response">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="CheckIn2Result" type="s:boolean" />
<s:element minOccurs="0" maxOccurs="1" name="errorMsg" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="checkInID" type="s:long" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="UploadPhoto">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="key" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="code" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="checkInID" type="s:long" />
<s:element minOccurs="1" maxOccurs="1" name="idType" type="s:int" />
<s:element minOccurs="0" maxOccurs="1" name="idCard" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="name" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="sex" type="s:int" />
<s:element minOccurs="0" maxOccurs="1" name="birthday" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="photoUrl" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="photo" type="s:base64Binary" />
<s:element minOccurs="0" maxOccurs="1" name="errorMsg" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="UploadPhotoResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="UploadPhotoResult" type="s:boolean" />
<s:element minOccurs="0" maxOccurs="1" name="errorMsg" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="ChangePhoneNumber">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="key" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="code" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="roomNumber" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="phoneNumber" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="idNumber" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="errorMsg" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="ChangePhoneNumberResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="ChangePhoneNumberResult" type="s:boolean" />
<s:element minOccurs="0" maxOccurs="1" name="errorMsg" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="CheckOut">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="key" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="code" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="roomNumber" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="checkOutDate" type="s:dateTime" />
<s:element minOccurs="0" maxOccurs="1" name="errorMsg" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="CheckOutResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="CheckOutResult" type="s:boolean" />
<s:element minOccurs="0" maxOccurs="1" name="errorMsg" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="RentRoom">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="key" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="code" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="roomNumber" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="rentDate" type="s:dateTime" />
<s:element minOccurs="0" maxOccurs="1" name="errorMsg" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="RentRoomResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="RentRoomResult" type="s:boolean" />
<s:element minOccurs="0" maxOccurs="1" name="errorMsg" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="PushBaoJing_IsEnable">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="key" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="code" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="isable" type="s:boolean" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="PushBaoJing_IsEnableResponse">
<s:complexType />
</s:element>
<s:element name="GetPushBaoJing_IsEnable">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="key" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="code" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="GetPushBaoJing_IsEnableResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="GetPushBaoJing_IsEnableResult" type="s:int" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="AddHotelInfo">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="key" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="Code" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="HotelName" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="HotelId" type="s:int" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="AddHotelInfoResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="AddHotelInfoResult" type="s:int" />
</s:sequence>
</s:complexType>
</s:element>
</s:schema>
</wsdl:types>
<wsdl:message name="CheckInSoapIn">
<wsdl:part name="parameters" element="tns:CheckIn" />
</wsdl:message>
<wsdl:message name="CheckInSoapOut">
<wsdl:part name="parameters" element="tns:CheckInResponse" />
</wsdl:message>
<wsdl:message name="CheckIn2SoapIn">
<wsdl:part name="parameters" element="tns:CheckIn2" />
</wsdl:message>
<wsdl:message name="CheckIn2SoapOut">
<wsdl:part name="parameters" element="tns:CheckIn2Response" />
</wsdl:message>
<wsdl:message name="UploadPhotoSoapIn">
<wsdl:part name="parameters" element="tns:UploadPhoto" />
</wsdl:message>
<wsdl:message name="UploadPhotoSoapOut">
<wsdl:part name="parameters" element="tns:UploadPhotoResponse" />
</wsdl:message>
<wsdl:message name="ChangePhoneNumberSoapIn">
<wsdl:part name="parameters" element="tns:ChangePhoneNumber" />
</wsdl:message>
<wsdl:message name="ChangePhoneNumberSoapOut">
<wsdl:part name="parameters" element="tns:ChangePhoneNumberResponse" />
</wsdl:message>
<wsdl:message name="CheckOutSoapIn">
<wsdl:part name="parameters" element="tns:CheckOut" />
</wsdl:message>
<wsdl:message name="CheckOutSoapOut">
<wsdl:part name="parameters" element="tns:CheckOutResponse" />
</wsdl:message>
<wsdl:message name="RentRoomSoapIn">
<wsdl:part name="parameters" element="tns:RentRoom" />
</wsdl:message>
<wsdl:message name="RentRoomSoapOut">
<wsdl:part name="parameters" element="tns:RentRoomResponse" />
</wsdl:message>
<wsdl:message name="PushBaoJing_IsEnableSoapIn">
<wsdl:part name="parameters" element="tns:PushBaoJing_IsEnable" />
</wsdl:message>
<wsdl:message name="PushBaoJing_IsEnableSoapOut">
<wsdl:part name="parameters" element="tns:PushBaoJing_IsEnableResponse" />
</wsdl:message>
<wsdl:message name="GetPushBaoJing_IsEnableSoapIn">
<wsdl:part name="parameters" element="tns:GetPushBaoJing_IsEnable" />
</wsdl:message>
<wsdl:message name="GetPushBaoJing_IsEnableSoapOut">
<wsdl:part name="parameters" element="tns:GetPushBaoJing_IsEnableResponse" />
</wsdl:message>
<wsdl:message name="AddHotelInfoSoapIn">
<wsdl:part name="parameters" element="tns:AddHotelInfo" />
</wsdl:message>
<wsdl:message name="AddHotelInfoSoapOut">
<wsdl:part name="parameters" element="tns:AddHotelInfoResponse" />
</wsdl:message>
<wsdl:portType name="blwwsSoap">
<wsdl:operation name="CheckIn">
<wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">开房&lt;br/&gt;key验证码我方提供code编码我方提供roomNumber房号checkInDate入住日期xmlString客人信息errorMsg返回错误信息phoneNumber手机号码多个以英文逗号,隔开idNumber身份证号多个以英文逗号,隔开):获取微信登录验证码</wsdl:documentation>
<wsdl:input message="tns:CheckInSoapIn" />
<wsdl:output message="tns:CheckInSoapOut" />
</wsdl:operation>
<wsdl:operation name="CheckIn2">
<wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">开房&lt;br/&gt;key验证码我方提供code编码我方提供roomNumber房号checkInDate入住日期xmlString客人信息errorMsg返回错误信息checkInID返回入住记录IDphoneNumber手机号码多个以英文逗号,隔开idNumber身份证号多个以英文逗号,隔开):获取微信登录验证码</wsdl:documentation>
<wsdl:input message="tns:CheckIn2SoapIn" />
<wsdl:output message="tns:CheckIn2SoapOut" />
</wsdl:operation>
<wsdl:operation name="UploadPhoto">
<wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">上传入住人信息&lt;br/&gt;key验证码我方提供code编码我方提供checkInID入住记录IDidType证件类型(0身份证1护照2军官证3其他)idCard证件号码name姓名sex性别(0女1男2其他)birthday出生日期(1999-01-01)photoUrl图片路径与photo二选一photo图片二进制errorMsg错误信息</wsdl:documentation>
<wsdl:input message="tns:UploadPhotoSoapIn" />
<wsdl:output message="tns:UploadPhotoSoapOut" />
</wsdl:operation>
<wsdl:operation name="ChangePhoneNumber">
<wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">变更手机号&lt;br/&gt;key验证码我方提供code编码我方提供roomNumber房号errorMsg错误信息phoneNumber手机号码多个以英文逗号,隔开idNumber身份证号获取验证码</wsdl:documentation>
<wsdl:input message="tns:ChangePhoneNumberSoapIn" />
<wsdl:output message="tns:ChangePhoneNumberSoapOut" />
</wsdl:operation>
<wsdl:operation name="CheckOut">
<wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">退房&lt;br/&gt;key验证码我方提供code编码我方提供roomNumber房号checkOutDate退房日期errorMsg错误信息</wsdl:documentation>
<wsdl:input message="tns:CheckOutSoapIn" />
<wsdl:output message="tns:CheckOutSoapOut" />
</wsdl:operation>
<wsdl:operation name="RentRoom">
<wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">待租&lt;br/&gt;key验证码我方提供code编码我方提供roomNumber房号rentDate变更待租日期errorMsg错误信息</wsdl:documentation>
<wsdl:input message="tns:RentRoomSoapIn" />
<wsdl:output message="tns:RentRoomSoapOut" />
</wsdl:operation>
<wsdl:operation name="PushBaoJing_IsEnable">
<wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">推送数据到宝镜</wsdl:documentation>
<wsdl:input message="tns:PushBaoJing_IsEnableSoapIn" />
<wsdl:output message="tns:PushBaoJing_IsEnableSoapOut" />
</wsdl:operation>
<wsdl:operation name="GetPushBaoJing_IsEnable">
<wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">获取是否推送PMS数据到宝镜</wsdl:documentation>
<wsdl:input message="tns:GetPushBaoJing_IsEnableSoapIn" />
<wsdl:output message="tns:GetPushBaoJing_IsEnableSoapOut" />
</wsdl:operation>
<wsdl:operation name="AddHotelInfo">
<wsdl:input message="tns:AddHotelInfoSoapIn" />
<wsdl:output message="tns:AddHotelInfoSoapOut" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="blwwsSoap" type="tns:blwwsSoap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="CheckIn">
<soap:operation soapAction="http://www.blw.com/CheckIn" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="CheckIn2">
<soap:operation soapAction="http://www.blw.com/CheckIn2" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="UploadPhoto">
<soap:operation soapAction="http://www.blw.com/UploadPhoto" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="ChangePhoneNumber">
<soap:operation soapAction="http://www.blw.com/ChangePhoneNumber" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="CheckOut">
<soap:operation soapAction="http://www.blw.com/CheckOut" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="RentRoom">
<soap:operation soapAction="http://www.blw.com/RentRoom" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="PushBaoJing_IsEnable">
<soap:operation soapAction="http://www.blw.com/PushBaoJing_IsEnable" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="GetPushBaoJing_IsEnable">
<soap:operation soapAction="http://www.blw.com/GetPushBaoJing_IsEnable" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="AddHotelInfo">
<soap:operation soapAction="http://www.blw.com/AddHotelInfo" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name="blwwsSoap12" type="tns:blwwsSoap">
<soap12:binding transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="CheckIn">
<soap12:operation soapAction="http://www.blw.com/CheckIn" style="document" />
<wsdl:input>
<soap12:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="CheckIn2">
<soap12:operation soapAction="http://www.blw.com/CheckIn2" style="document" />
<wsdl:input>
<soap12:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="UploadPhoto">
<soap12:operation soapAction="http://www.blw.com/UploadPhoto" style="document" />
<wsdl:input>
<soap12:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="ChangePhoneNumber">
<soap12:operation soapAction="http://www.blw.com/ChangePhoneNumber" style="document" />
<wsdl:input>
<soap12:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="CheckOut">
<soap12:operation soapAction="http://www.blw.com/CheckOut" style="document" />
<wsdl:input>
<soap12:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="RentRoom">
<soap12:operation soapAction="http://www.blw.com/RentRoom" style="document" />
<wsdl:input>
<soap12:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="PushBaoJing_IsEnable">
<soap12:operation soapAction="http://www.blw.com/PushBaoJing_IsEnable" style="document" />
<wsdl:input>
<soap12:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="GetPushBaoJing_IsEnable">
<soap12:operation soapAction="http://www.blw.com/GetPushBaoJing_IsEnable" style="document" />
<wsdl:input>
<soap12:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="AddHotelInfo">
<soap12:operation soapAction="http://www.blw.com/AddHotelInfo" style="document" />
<wsdl:input>
<soap12:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="blwws">
<wsdl:port name="blwwsSoap" binding="tns:blwwsSoap">
<soap:address location="http://pms.boonlive-rcu.com:89/blwws.asmx" />
</wsdl:port>
<wsdl:port name="blwwsSoap12" binding="tns:blwwsSoap12">
<soap12:address location="http://pms.boonlive-rcu.com:89/blwws.asmx" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<configurationSnapshot xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:schemas-microsoft-com:xml-wcfconfigurationsnapshot">
<behaviors />
<bindings>
<binding digest="System.ServiceModel.Configuration.BasicHttpBindingElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089:&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-16&quot;?&gt;&lt;Data name=&quot;blwwsSoap&quot; /&gt;" bindingType="basicHttpBinding" name="blwwsSoap" />
</bindings>
<endpoints>
<endpoint normalizedDigest="&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-16&quot;?&gt;&lt;Data address=&quot;http://pms.boonlive-rcu.com:89/blwws.asmx&quot; binding=&quot;basicHttpBinding&quot; bindingConfiguration=&quot;blwwsSoap&quot; contract=&quot;ServiceReference1.blwwsSoap&quot; name=&quot;blwwsSoap&quot; /&gt;" digest="&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-16&quot;?&gt;&lt;Data address=&quot;http://pms.boonlive-rcu.com:89/blwws.asmx&quot; binding=&quot;basicHttpBinding&quot; bindingConfiguration=&quot;blwwsSoap&quot; contract=&quot;ServiceReference1.blwwsSoap&quot; name=&quot;blwwsSoap&quot; /&gt;" contractName="ServiceReference1.blwwsSoap" name="blwwsSoap" />
</endpoints>
</configurationSnapshot>

View File

@@ -0,0 +1,201 @@
<?xml version="1.0" encoding="utf-8"?>
<SavedWcfConfigurationInformation xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Version="9.1" CheckSum="JnvezQfYz7ntN+hp84vGGVcVeG+SY3Pd5I8mFkPfhoY=">
<bindingConfigurations>
<bindingConfiguration bindingType="basicHttpBinding" name="blwwsSoap">
<properties>
<property path="/name" isComplexType="false" isExplicitlyDefined="true" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>blwwsSoap</serializedValue>
</property>
<property path="/closeTimeout" isComplexType="false" isExplicitlyDefined="true" clrType="System.TimeSpan, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue />
</property>
<property path="/openTimeout" isComplexType="false" isExplicitlyDefined="true" clrType="System.TimeSpan, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue />
</property>
<property path="/receiveTimeout" isComplexType="false" isExplicitlyDefined="true" clrType="System.TimeSpan, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue />
</property>
<property path="/sendTimeout" isComplexType="false" isExplicitlyDefined="true" clrType="System.TimeSpan, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue />
</property>
<property path="/allowCookies" isComplexType="false" isExplicitlyDefined="true" clrType="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue />
</property>
<property path="/bypassProxyOnLocal" isComplexType="false" isExplicitlyDefined="true" clrType="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue />
</property>
<property path="/hostNameComparisonMode" isComplexType="false" isExplicitlyDefined="false" clrType="System.ServiceModel.HostNameComparisonMode, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>StrongWildcard</serializedValue>
</property>
<property path="/maxBufferPoolSize" isComplexType="false" isExplicitlyDefined="true" clrType="System.Int64, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue />
</property>
<property path="/maxBufferSize" isComplexType="false" isExplicitlyDefined="false" clrType="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>65536</serializedValue>
</property>
<property path="/maxReceivedMessageSize" isComplexType="false" isExplicitlyDefined="true" clrType="System.Int64, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue />
</property>
<property path="/proxyAddress" isComplexType="false" isExplicitlyDefined="false" clrType="System.Uri, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue />
</property>
<property path="/readerQuotas" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.XmlDictionaryReaderQuotasElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>System.ServiceModel.Configuration.XmlDictionaryReaderQuotasElement</serializedValue>
</property>
<property path="/readerQuotas/maxDepth" isComplexType="false" isExplicitlyDefined="false" clrType="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>0</serializedValue>
</property>
<property path="/readerQuotas/maxStringContentLength" isComplexType="false" isExplicitlyDefined="false" clrType="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>0</serializedValue>
</property>
<property path="/readerQuotas/maxArrayLength" isComplexType="false" isExplicitlyDefined="false" clrType="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>0</serializedValue>
</property>
<property path="/readerQuotas/maxBytesPerRead" isComplexType="false" isExplicitlyDefined="false" clrType="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>0</serializedValue>
</property>
<property path="/readerQuotas/maxNameTableCharCount" isComplexType="false" isExplicitlyDefined="false" clrType="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>0</serializedValue>
</property>
<property path="/textEncoding" isComplexType="false" isExplicitlyDefined="false" clrType="System.Text.Encoding, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>System.Text.UTF8Encoding</serializedValue>
</property>
<property path="/transferMode" isComplexType="false" isExplicitlyDefined="false" clrType="System.ServiceModel.TransferMode, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>Buffered</serializedValue>
</property>
<property path="/useDefaultWebProxy" isComplexType="false" isExplicitlyDefined="true" clrType="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue />
</property>
<property path="/messageEncoding" isComplexType="false" isExplicitlyDefined="false" clrType="System.ServiceModel.WSMessageEncoding, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>Text</serializedValue>
</property>
<property path="/security" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.BasicHttpSecurityElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>System.ServiceModel.Configuration.BasicHttpSecurityElement</serializedValue>
</property>
<property path="/security/mode" isComplexType="false" isExplicitlyDefined="false" clrType="System.ServiceModel.BasicHttpSecurityMode, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>None</serializedValue>
</property>
<property path="/security/transport" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.HttpTransportSecurityElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>System.ServiceModel.Configuration.HttpTransportSecurityElement</serializedValue>
</property>
<property path="/security/transport/clientCredentialType" isComplexType="false" isExplicitlyDefined="false" clrType="System.ServiceModel.HttpClientCredentialType, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>None</serializedValue>
</property>
<property path="/security/transport/proxyCredentialType" isComplexType="false" isExplicitlyDefined="false" clrType="System.ServiceModel.HttpProxyCredentialType, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>None</serializedValue>
</property>
<property path="/security/transport/extendedProtectionPolicy" isComplexType="true" isExplicitlyDefined="false" clrType="System.Security.Authentication.ExtendedProtection.Configuration.ExtendedProtectionPolicyElement, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>System.Security.Authentication.ExtendedProtection.Configuration.ExtendedProtectionPolicyElement</serializedValue>
</property>
<property path="/security/transport/extendedProtectionPolicy/policyEnforcement" isComplexType="false" isExplicitlyDefined="false" clrType="System.Security.Authentication.ExtendedProtection.PolicyEnforcement, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>Never</serializedValue>
</property>
<property path="/security/transport/extendedProtectionPolicy/protectionScenario" isComplexType="false" isExplicitlyDefined="false" clrType="System.Security.Authentication.ExtendedProtection.ProtectionScenario, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>TransportSelected</serializedValue>
</property>
<property path="/security/transport/extendedProtectionPolicy/customServiceNames" isComplexType="true" isExplicitlyDefined="false" clrType="System.Security.Authentication.ExtendedProtection.Configuration.ServiceNameElementCollection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>(集合)</serializedValue>
</property>
<property path="/security/transport/realm" isComplexType="false" isExplicitlyDefined="false" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue />
</property>
<property path="/security/message" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.BasicHttpMessageSecurityElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>System.ServiceModel.Configuration.BasicHttpMessageSecurityElement</serializedValue>
</property>
<property path="/security/message/clientCredentialType" isComplexType="false" isExplicitlyDefined="false" clrType="System.ServiceModel.BasicHttpMessageCredentialType, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>UserName</serializedValue>
</property>
<property path="/security/message/algorithmSuite" isComplexType="false" isExplicitlyDefined="false" clrType="System.ServiceModel.Security.SecurityAlgorithmSuite, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>Default</serializedValue>
</property>
</properties>
</bindingConfiguration>
</bindingConfigurations>
<endpoints>
<endpoint name="blwwsSoap" contract="ServiceReference1.blwwsSoap" bindingType="basicHttpBinding" address="http://pms.boonlive-rcu.com:89/blwws.asmx" bindingConfiguration="blwwsSoap">
<properties>
<property path="/address" isComplexType="false" isExplicitlyDefined="true" clrType="System.Uri, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>http://pms.boonlive-rcu.com:89/blwws.asmx</serializedValue>
</property>
<property path="/behaviorConfiguration" isComplexType="false" isExplicitlyDefined="false" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue />
</property>
<property path="/binding" isComplexType="false" isExplicitlyDefined="true" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>basicHttpBinding</serializedValue>
</property>
<property path="/bindingConfiguration" isComplexType="false" isExplicitlyDefined="true" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>blwwsSoap</serializedValue>
</property>
<property path="/contract" isComplexType="false" isExplicitlyDefined="true" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>ServiceReference1.blwwsSoap</serializedValue>
</property>
<property path="/headers" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.AddressHeaderCollectionElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>System.ServiceModel.Configuration.AddressHeaderCollectionElement</serializedValue>
</property>
<property path="/headers/headers" isComplexType="false" isExplicitlyDefined="true" clrType="System.ServiceModel.Channels.AddressHeaderCollection, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>&lt;Header /&gt;</serializedValue>
</property>
<property path="/identity" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.IdentityElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>System.ServiceModel.Configuration.IdentityElement</serializedValue>
</property>
<property path="/identity/userPrincipalName" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.UserPrincipalNameElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>System.ServiceModel.Configuration.UserPrincipalNameElement</serializedValue>
</property>
<property path="/identity/userPrincipalName/value" isComplexType="false" isExplicitlyDefined="false" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue />
</property>
<property path="/identity/servicePrincipalName" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.ServicePrincipalNameElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>System.ServiceModel.Configuration.ServicePrincipalNameElement</serializedValue>
</property>
<property path="/identity/servicePrincipalName/value" isComplexType="false" isExplicitlyDefined="false" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue />
</property>
<property path="/identity/dns" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.DnsElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>System.ServiceModel.Configuration.DnsElement</serializedValue>
</property>
<property path="/identity/dns/value" isComplexType="false" isExplicitlyDefined="false" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue />
</property>
<property path="/identity/rsa" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.RsaElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>System.ServiceModel.Configuration.RsaElement</serializedValue>
</property>
<property path="/identity/rsa/value" isComplexType="false" isExplicitlyDefined="false" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue />
</property>
<property path="/identity/certificate" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.CertificateElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>System.ServiceModel.Configuration.CertificateElement</serializedValue>
</property>
<property path="/identity/certificate/encodedValue" isComplexType="false" isExplicitlyDefined="false" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue />
</property>
<property path="/identity/certificateReference" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.CertificateReferenceElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>System.ServiceModel.Configuration.CertificateReferenceElement</serializedValue>
</property>
<property path="/identity/certificateReference/storeName" isComplexType="false" isExplicitlyDefined="false" clrType="System.Security.Cryptography.X509Certificates.StoreName, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>My</serializedValue>
</property>
<property path="/identity/certificateReference/storeLocation" isComplexType="false" isExplicitlyDefined="false" clrType="System.Security.Cryptography.X509Certificates.StoreLocation, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>LocalMachine</serializedValue>
</property>
<property path="/identity/certificateReference/x509FindType" isComplexType="false" isExplicitlyDefined="false" clrType="System.Security.Cryptography.X509Certificates.X509FindType, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>FindBySubjectDistinguishedName</serializedValue>
</property>
<property path="/identity/certificateReference/findValue" isComplexType="false" isExplicitlyDefined="false" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue />
</property>
<property path="/identity/certificateReference/isChainIncluded" isComplexType="false" isExplicitlyDefined="false" clrType="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>False</serializedValue>
</property>
<property path="/name" isComplexType="false" isExplicitlyDefined="true" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>blwwsSoap</serializedValue>
</property>
<property path="/kind" isComplexType="false" isExplicitlyDefined="false" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue />
</property>
<property path="/endpointConfiguration" isComplexType="false" isExplicitlyDefined="false" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue />
</property>
</properties>
</endpoint>
</endpoints>
</SavedWcfConfigurationInformation>

17
BLV_API/Content/Site.css Normal file
View File

@@ -0,0 +1,17 @@
body {
padding-top: 50px;
padding-bottom: 20px;
}
/* Set padding to keep content from hitting the edges */
.body-content {
padding-left: 15px;
padding-right: 15px;
}
/* Set width on the form input elements since they're 100% wide by default */
input,
select,
textarea {
max-width: 280px;
}

587
BLV_API/Content/bootstrap-theme.css vendored Normal file
View File

@@ -0,0 +1,587 @@
/*!
* Bootstrap v3.4.1 (https://getbootstrap.com/)
* Copyright 2011-2019 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/
.btn-default,
.btn-primary,
.btn-success,
.btn-info,
.btn-warning,
.btn-danger {
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2);
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);
}
.btn-default:active,
.btn-primary:active,
.btn-success:active,
.btn-info:active,
.btn-warning:active,
.btn-danger:active,
.btn-default.active,
.btn-primary.active,
.btn-success.active,
.btn-info.active,
.btn-warning.active,
.btn-danger.active {
-webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
}
.btn-default.disabled,
.btn-primary.disabled,
.btn-success.disabled,
.btn-info.disabled,
.btn-warning.disabled,
.btn-danger.disabled,
.btn-default[disabled],
.btn-primary[disabled],
.btn-success[disabled],
.btn-info[disabled],
.btn-warning[disabled],
.btn-danger[disabled],
fieldset[disabled] .btn-default,
fieldset[disabled] .btn-primary,
fieldset[disabled] .btn-success,
fieldset[disabled] .btn-info,
fieldset[disabled] .btn-warning,
fieldset[disabled] .btn-danger {
-webkit-box-shadow: none;
box-shadow: none;
}
.btn-default .badge,
.btn-primary .badge,
.btn-success .badge,
.btn-info .badge,
.btn-warning .badge,
.btn-danger .badge {
text-shadow: none;
}
.btn:active,
.btn.active {
background-image: none;
}
.btn-default {
background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%);
background-image: -o-linear-gradient(top, #fff 0%, #e0e0e0 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#e0e0e0));
background-image: linear-gradient(to bottom, #fff 0%, #e0e0e0 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
background-repeat: repeat-x;
border-color: #dbdbdb;
text-shadow: 0 1px 0 #fff;
border-color: #ccc;
}
.btn-default:hover,
.btn-default:focus {
background-color: #e0e0e0;
background-position: 0 -15px;
}
.btn-default:active,
.btn-default.active {
background-color: #e0e0e0;
border-color: #dbdbdb;
}
.btn-default.disabled,
.btn-default[disabled],
fieldset[disabled] .btn-default,
.btn-default.disabled:hover,
.btn-default[disabled]:hover,
fieldset[disabled] .btn-default:hover,
.btn-default.disabled:focus,
.btn-default[disabled]:focus,
fieldset[disabled] .btn-default:focus,
.btn-default.disabled.focus,
.btn-default[disabled].focus,
fieldset[disabled] .btn-default.focus,
.btn-default.disabled:active,
.btn-default[disabled]:active,
fieldset[disabled] .btn-default:active,
.btn-default.disabled.active,
.btn-default[disabled].active,
fieldset[disabled] .btn-default.active {
background-color: #e0e0e0;
background-image: none;
}
.btn-primary {
background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%);
background-image: -o-linear-gradient(top, #337ab7 0%, #265a88 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#265a88));
background-image: linear-gradient(to bottom, #337ab7 0%, #265a88 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
background-repeat: repeat-x;
border-color: #245580;
}
.btn-primary:hover,
.btn-primary:focus {
background-color: #265a88;
background-position: 0 -15px;
}
.btn-primary:active,
.btn-primary.active {
background-color: #265a88;
border-color: #245580;
}
.btn-primary.disabled,
.btn-primary[disabled],
fieldset[disabled] .btn-primary,
.btn-primary.disabled:hover,
.btn-primary[disabled]:hover,
fieldset[disabled] .btn-primary:hover,
.btn-primary.disabled:focus,
.btn-primary[disabled]:focus,
fieldset[disabled] .btn-primary:focus,
.btn-primary.disabled.focus,
.btn-primary[disabled].focus,
fieldset[disabled] .btn-primary.focus,
.btn-primary.disabled:active,
.btn-primary[disabled]:active,
fieldset[disabled] .btn-primary:active,
.btn-primary.disabled.active,
.btn-primary[disabled].active,
fieldset[disabled] .btn-primary.active {
background-color: #265a88;
background-image: none;
}
.btn-success {
background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%);
background-image: -o-linear-gradient(top, #5cb85c 0%, #419641 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#419641));
background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
background-repeat: repeat-x;
border-color: #3e8f3e;
}
.btn-success:hover,
.btn-success:focus {
background-color: #419641;
background-position: 0 -15px;
}
.btn-success:active,
.btn-success.active {
background-color: #419641;
border-color: #3e8f3e;
}
.btn-success.disabled,
.btn-success[disabled],
fieldset[disabled] .btn-success,
.btn-success.disabled:hover,
.btn-success[disabled]:hover,
fieldset[disabled] .btn-success:hover,
.btn-success.disabled:focus,
.btn-success[disabled]:focus,
fieldset[disabled] .btn-success:focus,
.btn-success.disabled.focus,
.btn-success[disabled].focus,
fieldset[disabled] .btn-success.focus,
.btn-success.disabled:active,
.btn-success[disabled]:active,
fieldset[disabled] .btn-success:active,
.btn-success.disabled.active,
.btn-success[disabled].active,
fieldset[disabled] .btn-success.active {
background-color: #419641;
background-image: none;
}
.btn-info {
background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);
background-image: -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#2aabd2));
background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
background-repeat: repeat-x;
border-color: #28a4c9;
}
.btn-info:hover,
.btn-info:focus {
background-color: #2aabd2;
background-position: 0 -15px;
}
.btn-info:active,
.btn-info.active {
background-color: #2aabd2;
border-color: #28a4c9;
}
.btn-info.disabled,
.btn-info[disabled],
fieldset[disabled] .btn-info,
.btn-info.disabled:hover,
.btn-info[disabled]:hover,
fieldset[disabled] .btn-info:hover,
.btn-info.disabled:focus,
.btn-info[disabled]:focus,
fieldset[disabled] .btn-info:focus,
.btn-info.disabled.focus,
.btn-info[disabled].focus,
fieldset[disabled] .btn-info.focus,
.btn-info.disabled:active,
.btn-info[disabled]:active,
fieldset[disabled] .btn-info:active,
.btn-info.disabled.active,
.btn-info[disabled].active,
fieldset[disabled] .btn-info.active {
background-color: #2aabd2;
background-image: none;
}
.btn-warning {
background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);
background-image: -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#eb9316));
background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
background-repeat: repeat-x;
border-color: #e38d13;
}
.btn-warning:hover,
.btn-warning:focus {
background-color: #eb9316;
background-position: 0 -15px;
}
.btn-warning:active,
.btn-warning.active {
background-color: #eb9316;
border-color: #e38d13;
}
.btn-warning.disabled,
.btn-warning[disabled],
fieldset[disabled] .btn-warning,
.btn-warning.disabled:hover,
.btn-warning[disabled]:hover,
fieldset[disabled] .btn-warning:hover,
.btn-warning.disabled:focus,
.btn-warning[disabled]:focus,
fieldset[disabled] .btn-warning:focus,
.btn-warning.disabled.focus,
.btn-warning[disabled].focus,
fieldset[disabled] .btn-warning.focus,
.btn-warning.disabled:active,
.btn-warning[disabled]:active,
fieldset[disabled] .btn-warning:active,
.btn-warning.disabled.active,
.btn-warning[disabled].active,
fieldset[disabled] .btn-warning.active {
background-color: #eb9316;
background-image: none;
}
.btn-danger {
background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%);
background-image: -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c12e2a));
background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
background-repeat: repeat-x;
border-color: #b92c28;
}
.btn-danger:hover,
.btn-danger:focus {
background-color: #c12e2a;
background-position: 0 -15px;
}
.btn-danger:active,
.btn-danger.active {
background-color: #c12e2a;
border-color: #b92c28;
}
.btn-danger.disabled,
.btn-danger[disabled],
fieldset[disabled] .btn-danger,
.btn-danger.disabled:hover,
.btn-danger[disabled]:hover,
fieldset[disabled] .btn-danger:hover,
.btn-danger.disabled:focus,
.btn-danger[disabled]:focus,
fieldset[disabled] .btn-danger:focus,
.btn-danger.disabled.focus,
.btn-danger[disabled].focus,
fieldset[disabled] .btn-danger.focus,
.btn-danger.disabled:active,
.btn-danger[disabled]:active,
fieldset[disabled] .btn-danger:active,
.btn-danger.disabled.active,
.btn-danger[disabled].active,
fieldset[disabled] .btn-danger.active {
background-color: #c12e2a;
background-image: none;
}
.thumbnail,
.img-thumbnail {
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);
}
.dropdown-menu > li > a:hover,
.dropdown-menu > li > a:focus {
background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8));
background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);
background-repeat: repeat-x;
background-color: #e8e8e8;
}
.dropdown-menu > .active > a,
.dropdown-menu > .active > a:hover,
.dropdown-menu > .active > a:focus {
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
background-repeat: repeat-x;
background-color: #2e6da4;
}
.navbar-default {
background-image: -webkit-linear-gradient(top, #ffffff 0%, #f8f8f8 100%);
background-image: -o-linear-gradient(top, #ffffff 0%, #f8f8f8 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#f8f8f8));
background-image: linear-gradient(to bottom, #ffffff 0%, #f8f8f8 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
border-radius: 4px;
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);
}
.navbar-default .navbar-nav > .open > a,
.navbar-default .navbar-nav > .active > a {
background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);
background-image: -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#dbdbdb), to(#e2e2e2));
background-image: linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);
background-repeat: repeat-x;
-webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075);
box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075);
}
.navbar-brand,
.navbar-nav > li > a {
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.25);
}
.navbar-inverse {
background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%);
background-image: -o-linear-gradient(top, #3c3c3c 0%, #222 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#3c3c3c), to(#222));
background-image: linear-gradient(to bottom, #3c3c3c 0%, #222 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
border-radius: 4px;
}
.navbar-inverse .navbar-nav > .open > a,
.navbar-inverse .navbar-nav > .active > a {
background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%);
background-image: -o-linear-gradient(top, #080808 0%, #0f0f0f 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#080808), to(#0f0f0f));
background-image: linear-gradient(to bottom, #080808 0%, #0f0f0f 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);
background-repeat: repeat-x;
-webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25);
box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25);
}
.navbar-inverse .navbar-brand,
.navbar-inverse .navbar-nav > li > a {
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}
.navbar-static-top,
.navbar-fixed-top,
.navbar-fixed-bottom {
border-radius: 0;
}
@media (max-width: 767px) {
.navbar .navbar-nav .open .dropdown-menu > .active > a,
.navbar .navbar-nav .open .dropdown-menu > .active > a:hover,
.navbar .navbar-nav .open .dropdown-menu > .active > a:focus {
color: #fff;
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
background-repeat: repeat-x;
}
}
.alert {
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.2);
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);
}
.alert-success {
background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);
background-image: -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#c8e5bc));
background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);
background-repeat: repeat-x;
border-color: #b2dba1;
}
.alert-info {
background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%);
background-image: -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#b9def0));
background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);
background-repeat: repeat-x;
border-color: #9acfea;
}
.alert-warning {
background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);
background-image: -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#f8efc0));
background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);
background-repeat: repeat-x;
border-color: #f5e79e;
}
.alert-danger {
background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);
background-image: -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#e7c3c3));
background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);
background-repeat: repeat-x;
border-color: #dca7a7;
}
.progress {
background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);
background-image: -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#ebebeb), to(#f5f5f5));
background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);
background-repeat: repeat-x;
}
.progress-bar {
background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%);
background-image: -o-linear-gradient(top, #337ab7 0%, #286090 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#286090));
background-image: linear-gradient(to bottom, #337ab7 0%, #286090 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);
background-repeat: repeat-x;
}
.progress-bar-success {
background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%);
background-image: -o-linear-gradient(top, #5cb85c 0%, #449d44 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#449d44));
background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);
background-repeat: repeat-x;
}
.progress-bar-info {
background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);
background-image: -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#31b0d5));
background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);
background-repeat: repeat-x;
}
.progress-bar-warning {
background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);
background-image: -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#ec971f));
background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);
background-repeat: repeat-x;
}
.progress-bar-danger {
background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%);
background-image: -o-linear-gradient(top, #d9534f 0%, #c9302c 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c9302c));
background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);
background-repeat: repeat-x;
}
.progress-bar-striped {
background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
}
.list-group {
border-radius: 4px;
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);
}
.list-group-item.active,
.list-group-item.active:hover,
.list-group-item.active:focus {
text-shadow: 0 -1px 0 #286090;
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%);
background-image: -o-linear-gradient(top, #337ab7 0%, #2b669a 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2b669a));
background-image: linear-gradient(to bottom, #337ab7 0%, #2b669a 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);
background-repeat: repeat-x;
border-color: #2b669a;
}
.list-group-item.active .badge,
.list-group-item.active:hover .badge,
.list-group-item.active:focus .badge {
text-shadow: none;
}
.panel {
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
}
.panel-default > .panel-heading {
background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8));
background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);
background-repeat: repeat-x;
}
.panel-primary > .panel-heading {
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
background-repeat: repeat-x;
}
.panel-success > .panel-heading {
background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);
background-image: -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#d0e9c6));
background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);
background-repeat: repeat-x;
}
.panel-info > .panel-heading {
background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);
background-image: -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#c4e3f3));
background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);
background-repeat: repeat-x;
}
.panel-warning > .panel-heading {
background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);
background-image: -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#faf2cc));
background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);
background-repeat: repeat-x;
}
.panel-danger > .panel-heading {
background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%);
background-image: -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#ebcccc));
background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);
background-repeat: repeat-x;
}
.well {
background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);
background-image: -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#e8e8e8), to(#f5f5f5));
background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);
background-repeat: repeat-x;
border-color: #dcdcdc;
-webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);
box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);
}
/*# sourceMappingURL=bootstrap-theme.css.map */

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

6834
BLV_API/Content/bootstrap.css vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

6
BLV_API/Content/bootstrap.min.css vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,867 @@
using BLV_API.Dal;
using BLV_API.Models;
using BLWWS;
//using BLWWS;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using System.Web.Http.Results;
using System.Web.Mvc;
using System.Xml;
using System.Xml.Linq;
using static BLV_API.Models.BLVEntity;
namespace BLV_API.Controllers
{
public class ApiController : Controller
{
public readonly string _bjInterfaceUrl = System.Configuration.ConfigurationManager.AppSettings["bjInterfaceUrl"];
public ActionResult Index()
{
ViewBag.Title = "宝来威客控与PMS对接API";
return View();
}
/// <summary>
/// 入住接口
/// </summary>
/// <returns></returns>
public ActionResult checkin()
{
string IP = Tools.GetClientIP(Request);
Request.InputStream.Position = 0;
byte[] reqBody = new byte[Request.InputStream.Length];
Request.InputStream.Read(reqBody, 0, reqBody.Length);
string reqData = System.Text.Encoding.UTF8.GetString(reqBody);
if (string.IsNullOrEmpty(reqData))
{
return Json(new BLVEntity.Result() { code = 4001, msg = "传递参数不能为空" }, JsonRequestBehavior.AllowGet);
}
try
{
BLVEntity.Root req = JsonConvert.DeserializeObject<BLVEntity.Root>(reqData);
if (string.IsNullOrEmpty(req.hotel_code))
{
LogHelper.WriteLog($"hotel_code({req.hotel_code})不匹配");
return Json(new BLVEntity.Result() { code = 4001, msg = $"hotel_code({req.hotel_code})不匹配" }, JsonRequestBehavior.AllowGet);
}
//ServiceReference1.blwwsSoapClient client = new ServiceReference1.blwwsSoapClient();
boonliverpms.blwws client = new boonliverpms.blwws();
try
{
ExtraData eee = new ExtraData();
eee.OriginalData = reqData;
eee.RequestIP = IP;
string sstr = JsonConvert.SerializeObject(eee);
string RRR = HttpUtility.UrlEncode(sstr);
var cookie = new System.Net.Cookie("order_original", RRR, "/", cookiedomain);
client.CookieContainer = new System.Net.CookieContainer();
client.CookieContainer.Add(cookie);
}
catch (Exception ex)
{
LogHelper.WriteLog("cookie: " + ex.Message);
}
string errorMsg = "";
bool blvResult = false;
StringBuilder xmlString = new StringBuilder();
string phoneNumber = "";
string idNumber = "";
//①转发客控后台
if (req.infos.Count > 0)
{
phoneNumber = req.infos[0].mobile;
idNumber = req.infos[0].idcard;
xmlString.Append("<interface>");
foreach (BLVEntity.InfosItem guest in req.infos)
{
xmlString.Append("<item idtype=\"" + guest.type + "\" idcard = \"" + guest.idcard + "\" customer = \"" + guest.name + "\" sex =\"" +
(guest.sex == 1 ? "男" : "女") + "\" country =\"0\" checkindate = \"" + req.checkIn.ToString("yyyy-MM-dd HH:mm:ss") + "\"/>");
}
xmlString.Append("</interface>");
}
blvResult = client.CheckIn("blw_ws@2015", req.hotel_code, req.room_no, req.checkIn, xmlString.ToString(), ref errorMsg, phoneNumber, idNumber);
//LogHelper.WriteLog($"转发BLV内部开房接口结果{blvResult},消息:{errorMsg}");
//②转发人脸机
//③转发宝镜系统
string strBJResult = Tools.PostWebRequest(_bjInterfaceUrl + "/order/checkIn", reqData);
BLVEntity.Result bjResult = JsonConvert.DeserializeObject<BLVEntity.Result>(strBJResult);
if (bjResult != null && bjResult.code != 200)
{
LogHelper.WriteLog("调用宝镜checkin接口失败原因" + bjResult.msg);
}
/*switch (req.type)
{
case "reg.checkin"://入住
case "guest.checkin"://更新入住人
break;
case "reg.checkout"://退房
//cricsEntity.RoomStatusID = 8;
blvResult = client.CheckOut("blw_ws@2015", hotelCode, req.room_no, req.check_out_time, ref errorMsg);
//LogHelper.WriteLog($"转发BLV内部退房接口结果{blvResult},消息:{errorMsg}");
break;
case "reg.move"://换房
//cricsEntity.RoomStatusID = 2;
//先退房
blvResult = client.CheckOut("blw_ws@2015", hotelCode, req.old_room_no, req.move_time, ref errorMsg);
//LogHelper.WriteLog($"转发BLV内部退房接口结果{blvResult},消息:{errorMsg}");
//再开房
if (req.guests.Count > 0)
{
phoneNumber = req.guests[0].mobile;
idNumber = req.guests[0].id_card_no;
xmlString.Append("<interface>");
foreach (Luopan2Entity.GuestsItem guest in req.guests)
{
xmlString.Append("<item idtype=\"" + guest.id_card_type_id + "\" idcard = \"" + guest.id_card_no + "\" customer = \"" + guest.last_name + guest.first_name + "\" sex =\"" +
(guest.gender_id == 0 ? "男" : "女") + "\" country =\"0\" checkindate = \"" + req.check_in_time.ToString("yyyy-MM-dd HH:mm:ss") + "\"/>");
}
xmlString.Append("</interface>");
}
blvResult = client.CheckIn("blw_ws@2015", hotelCode, req.new_room_no, req.check_in_time, xmlString.ToString(), ref errorMsg, phoneNumber, idNumber);
//LogHelper.WriteLog($"转发BLV内部开房接口结果{blvResult},消息:{errorMsg}");
break;
default:
LogHelper.WriteLog("宝莱威接口未处理type" + req.type);
blvResult = true;
break;
}*/
if (blvResult)
{
return Json(new BLVEntity.Result() { code = 200, msg = "开房成功" }, JsonRequestBehavior.AllowGet);
}
else
{
LogHelper.WriteLog(errorMsg);
LogHelper.WriteLog("收到checkin请求" + reqData);
return Json(new BLVEntity.Result() { code = 4001, msg = errorMsg }, JsonRequestBehavior.AllowGet);
}
}
catch (Exception ex)
{
LogHelper.WriteLog(ex.ToString());
LogHelper.WriteLog("收到checkin请求" + reqData);
return Json(new BLVEntity.Result() { code = 4001, msg = ex.Message }, JsonRequestBehavior.AllowGet);
}
}
/// <summary>
/// 入住接口
/// </summary>
/// <returns></returns>
public ActionResult checkout()
{
Request.InputStream.Position = 0;
byte[] reqBody = new byte[Request.InputStream.Length];
Request.InputStream.Read(reqBody, 0, reqBody.Length);
string reqData = System.Text.Encoding.UTF8.GetString(reqBody);
if (string.IsNullOrEmpty(reqData))
{
return Json(new BLVEntity.Result() { code = 4001, msg = "传递参数不能为空" }, JsonRequestBehavior.AllowGet);
}
try
{
string IP = Tools.GetClientIP(Request);
BLVEntity.Root req = JsonConvert.DeserializeObject<BLVEntity.Root>(reqData);
if (string.IsNullOrEmpty(req.hotel_code))
{
LogHelper.WriteLog($"hotel_code({req.hotel_code})不匹配");
return Json(new BLVEntity.Result() { code = 4001, msg = $"hotel_code({req.hotel_code})不匹配" }, JsonRequestBehavior.AllowGet);
}
//ServiceReference1.blwwsSoapClient client = new ServiceReference1.blwwsSoapClient();
boonliverpms.blwws client = new boonliverpms.blwws();
try
{
ExtraData eee = new ExtraData();
eee.OriginalData = reqData;
eee.RequestIP = IP;
string sstr = JsonConvert.SerializeObject(eee);
string RRR = HttpUtility.UrlEncode(sstr);
var cookie = new System.Net.Cookie("order_original", RRR, "/", cookiedomain);
client.CookieContainer = new System.Net.CookieContainer();
client.CookieContainer.Add(cookie);
}
catch (Exception ex)
{
LogHelper.WriteLog("cookie: " + ex.Message);
}
string errorMsg = "";
bool blvResult = false;
//①转发客控后台
blvResult = client.CheckOut("blw_ws@2015", req.hotel_code, req.room_no, req.checkOut, ref errorMsg);
//②转发人脸机
//③转发宝镜系统
if (blvResult)
{
return Json(new BLVEntity.Result() { code = 200, msg = "退房成功" }, JsonRequestBehavior.AllowGet);
}
else
{
LogHelper.WriteLog(errorMsg);
LogHelper.WriteLog("收到checkout请求" + reqData);
return Json(new BLVEntity.Result() { code = 4001, msg = errorMsg }, JsonRequestBehavior.AllowGet);
}
}
catch (Exception ex)
{
LogHelper.WriteLog(ex.ToString());
LogHelper.WriteLog("收到checkout请求" + reqData);
return Json(new BLVEntity.Result() { code = 4001, msg = ex.Message }, JsonRequestBehavior.AllowGet);
}
}
/// <summary>
/// Luopan2 PMS对接
/// </summary>
/// <returns></returns>
public ActionResult Luopan2ToBLV()
{
Request.InputStream.Position = 0;
byte[] reqBody = new byte[Request.InputStream.Length];
Request.InputStream.Read(reqBody, 0, reqBody.Length);
string reqData = System.Text.Encoding.UTF8.GetString(reqBody);
if (string.IsNullOrEmpty(reqData))
{
return Json(new LuopanEntity.Result() { status = 1, error_msg = "传递参数不能为空" }, JsonRequestBehavior.AllowGet);
}
try
{
Luopan2Entity.Root req = JsonConvert.DeserializeObject<Luopan2Entity.Root>(reqData);
string hotelCode = System.Configuration.ConfigurationManager.AppSettings[req.hotel_id];
if (string.IsNullOrEmpty(hotelCode))
{
LogHelper.WriteLog($"hotel_id({req.hotel_id})不匹配或未配置");
return Json(new LuopanEntity.Result() { status = 1, error_msg = $"hotel_id({req.hotel_id})不匹配或未配置" }, JsonRequestBehavior.AllowGet);
}
ServiceReference1.blwwsSoapClient client = new ServiceReference1.blwwsSoapClient();
string errorMsg = "";
bool blvResult = false;
StringBuilder xmlString = new StringBuilder();
string phoneNumber = "";
string idNumber = "";
switch (req.type)
{
case "reg.checkin"://入住
case "guest.checkin"://更新入住人
//①转发客控后台
if (req.guests.Count > 0)
{
phoneNumber = req.guests[0].mobile;
idNumber = req.guests[0].id_card_no;
xmlString.Append("<interface>");
foreach (Luopan2Entity.GuestsItem guest in req.guests)
{
xmlString.Append("<item idtype=\"" + guest.id_card_type_id + "\" idcard = \"" + guest.id_card_no + "\" customer = \"" + guest.last_name + guest.first_name + "\" sex =\"" +
(guest.gender_id == 0 ? "男" : "女") + "\" country =\"0\" checkindate = \"" + req.check_in_time.Value.ToString("yyyy-MM-dd HH:mm:ss") + "\"/>");
}
xmlString.Append("</interface>");
}
blvResult = client.CheckIn("blw_ws@2015", hotelCode, req.room_no, req.check_in_time.Value, xmlString.ToString(), ref errorMsg, phoneNumber, idNumber);
//LogHelper.WriteLog($"转发BLV内部开房接口结果{blvResult},消息:{errorMsg}");
//②转发人脸机
//③转发宝镜系统
break;
case "reg.checkout"://退房
//cricsEntity.RoomStatusID = 8;
blvResult = client.CheckOut("blw_ws@2015", hotelCode, req.room_no, req.check_out_time.Value, ref errorMsg);
//LogHelper.WriteLog($"转发BLV内部退房接口结果{blvResult},消息:{errorMsg}");
break;
case "reg.move"://换房
//cricsEntity.RoomStatusID = 2;
//先退房
blvResult = client.CheckOut("blw_ws@2015", hotelCode, req.old_room_no, req.move_time.Value, ref errorMsg);
//LogHelper.WriteLog($"转发BLV内部退房接口结果{blvResult},消息:{errorMsg}");
//再开房
if (req.guests.Count > 0)
{
phoneNumber = req.guests[0].mobile;
idNumber = req.guests[0].id_card_no;
xmlString.Append("<interface>");
foreach (Luopan2Entity.GuestsItem guest in req.guests)
{
xmlString.Append("<item idtype=\"" + guest.id_card_type_id + "\" idcard = \"" + guest.id_card_no + "\" customer = \"" + guest.last_name + guest.first_name + "\" sex =\"" +
(guest.gender_id == 0 ? "男" : "女") + "\" country =\"0\" checkindate = \"" + req.check_in_time.Value.ToString("yyyy-MM-dd HH:mm:ss") + "\"/>");
}
xmlString.Append("</interface>");
}
blvResult = client.CheckIn("blw_ws@2015", hotelCode, req.new_room_no, req.check_in_time.Value, xmlString.ToString(), ref errorMsg, phoneNumber, idNumber);
//LogHelper.WriteLog($"转发BLV内部开房接口结果{blvResult},消息:{errorMsg}");
break;
default:
LogHelper.WriteLog("宝莱威接口未处理type" + req.type);
blvResult = true;
break;
}
if (blvResult)
{
return Json(new LuopanEntity.Result() { status = 0, error_msg = "" }, JsonRequestBehavior.AllowGet);
}
else
{
LogHelper.WriteLog(errorMsg);
LogHelper.WriteLog("收到Luopan2请求" + reqData);
return Json(new LuopanEntity.Result() { status = 1, error_msg = errorMsg }, JsonRequestBehavior.AllowGet);
}
}
catch (Exception ex)
{
LogHelper.WriteLog(ex.ToString());
LogHelper.WriteLog("收到Luopan2请求" + reqData);
return Json(new LuopanEntity.Result() { status = 1, error_msg = ex.Message }, JsonRequestBehavior.AllowGet);
}
}
/// <summary>
/// Luopan PMS对接
/// </summary>
/// <returns></returns>
public ActionResult LuopanToBLV()
{
Request.InputStream.Position = 0;
byte[] reqBody = new byte[Request.InputStream.Length];
Request.InputStream.Read(reqBody, 0, reqBody.Length);
string reqData = System.Text.Encoding.UTF8.GetString(reqBody);
if (string.IsNullOrEmpty(reqData))
{
return Json(new LuopanEntity.Result() { status = 1, error_msg = "传递参数不能为空" }, JsonRequestBehavior.AllowGet);
}
try
{
LuopanEntity.Root req = JsonConvert.DeserializeObject<LuopanEntity.Root>(reqData);
string hotelCode = System.Configuration.ConfigurationManager.AppSettings[req.HotelId];
if (string.IsNullOrEmpty(hotelCode))
{
LogHelper.WriteLog($"HotelId({req.HotelId})不匹配或未配置");
return Json(new LuopanEntity.Result() { status = 1, error_msg = $"HotelId({req.HotelId})不匹配或未配置" }, JsonRequestBehavior.AllowGet);
}
ServiceReference1.blwwsSoapClient client = new ServiceReference1.blwwsSoapClient();
string errorMsg = "";
bool blvResult = false;
StringBuilder xmlString = new StringBuilder();
string phoneNumber = "";
string idNumber = "";
switch (req.Action)
{
case "CheckIn"://入住
if (req.GuestInfo.Count > 0)
{
phoneNumber = req.GuestInfo[0].Mobile;
idNumber = req.GuestInfo[0].IDCardNo;
xmlString.Append("<interface>");
foreach (LuopanEntity.GuestInfo guest in req.GuestInfo)
{
xmlString.Append("<item idtype=\"" + guest.IDCardTypeId + "\" idcard = \"" + guest.IDCardNo + "\" customer = \"" + guest.GuestName + "\" sex =\"" +
(guest.Gender == 0 ? "男" : "女") + "\" country =\"0\" checkindate = \"" + req.CheckInTime.ToString("yyyy-MM-dd HH:mm:ss") + "\"/>");
}
xmlString.Append("</interface>");
}
blvResult = client.CheckIn("blw_ws@2015", hotelCode, req.RoomNo, req.CheckInTime, xmlString.ToString(), ref errorMsg, phoneNumber, idNumber);
//LogHelper.WriteLog($"转发BLV内部开房接口结果{blvResult},消息:{errorMsg}");
break;
case "CheckOut"://退房
blvResult = client.CheckOut("blw_ws@2015", hotelCode, req.RoomNo, req.CheckOutTime, ref errorMsg);
//LogHelper.WriteLog($"转发BLV内部退房接口结果{blvResult},消息:{errorMsg}");
break;
case "MoveRoom"://换房
//先退房
blvResult = client.CheckOut("blw_ws@2015", hotelCode, req.OldRoomNo, req.MoveTime, ref errorMsg);
//LogHelper.WriteLog($"转发BLV内部退房接口结果{blvResult},消息:{errorMsg}");
//再开房
if (req.GuestInfo.Count > 0)
{
phoneNumber = req.GuestInfo[0].Mobile;
idNumber = req.GuestInfo[0].IDCardNo;
xmlString.Append("<interface>");
foreach (LuopanEntity.GuestInfo guest in req.GuestInfo)
{
xmlString.Append("<item idtype=\"" + guest.IDCardTypeId + "\" idcard = \"" + guest.IDCardNo + "\" customer = \"" + guest.GuestName + "\" sex =\"" +
(guest.Gender == 0 ? "男" : "女") + "\" country =\"0\" checkindate = \"" + req.CheckInTime.ToString("yyyy-MM-dd HH:mm:ss") + "\"/>");
}
xmlString.Append("</interface>");
}
blvResult = client.CheckIn("blw_ws@2015", hotelCode, req.NewRoomNo, req.CheckInTime, xmlString.ToString(), ref errorMsg, phoneNumber, idNumber);
//LogHelper.WriteLog($"转发BLV内部开房接口结果{blvResult},消息:{errorMsg}");
break;
default:
LogHelper.WriteLog("宝莱威接口未处理Action" + req.Action);
blvResult = true;
break;
}
if (blvResult)
{
return Json(new LuopanEntity.Result() { status = 0, error_msg = "" }, JsonRequestBehavior.AllowGet);
}
else
{
LogHelper.WriteLog(errorMsg);
LogHelper.WriteLog("收到Luopan请求" + reqData);
return Json(new LuopanEntity.Result() { status = 1, error_msg = errorMsg }, JsonRequestBehavior.AllowGet);
}
}
catch (Exception ex)
{
LogHelper.WriteLog(ex.ToString());
LogHelper.WriteLog("收到Luopan请求" + reqData);
return Json(new LuopanEntity.Result() { status = 1, error_msg = ex.Message }, JsonRequestBehavior.AllowGet);
}
}
static string GetMD5Hash(string input)
{
StringBuilder sb = new StringBuilder(32); // 预分配32字符空间
using (HashAlgorithm algorithm = MD5.Create())
{
byte[] inputBytes = Encoding.UTF8.GetBytes(input);
byte[] hashBytes = algorithm.ComputeHash(inputBytes);
foreach (byte b in hashBytes)
{
sb.Append(b.ToString("x2")); // 使用"x2"确保总是两位十六进制
}
}
return sb.ToString();
}
public static string GetMD5(string str)
{
//创建MD5对象
MD5 mD5 = MD5.Create();
byte[] buffer = Encoding.Default.GetBytes(str);
var MD5Buffer = mD5.ComputeHash(buffer);
//将字节数组转换为字符串
//法一:将字节数组中每个元素按照指定的编码格式解析成字符串
//return Encoding.Default.GetString(MD5Buffer);(会造成乱码)
//法二直接将数组tostring
//法三直接将数组中的每个元素ToString()
string s = "";
for (int i = 0; i < MD5Buffer.Length; i++)
{
s += MD5Buffer[i].ToString("x2");//tostring中的参数x是将10进制转化为16进制
}
return s;
}
public static DateTime ToLocalTimeDateByMilliseconds(long unix)
{
var dto = DateTimeOffset.FromUnixTimeMilliseconds(unix);
return dto.ToLocalTime().DateTime;
}
public static readonly string uname = ConfigurationManager.AppSettings["yanzheng_user"];
public static readonly string upassword = ConfigurationManager.AppSettings["yanzheng_password"];
/// <summary>
/// cookie域
/// </summary>
public static readonly string cookiedomain = ConfigurationManager.AppSettings["cookiekey_domain"];
#region
/// <summary>
/// 瑰迈酒店PMS
/// 一个订单可以开好多房
/// </summary>
/// <returns></returns>
public ActionResult GuiMaiHotelToBLV()
{
return TongYi();
}
/// <summary>
/// 旅智PMS
/// </summary>
/// <returns></returns>
[HttpPost()]
public ActionResult LvZhiToBLV()
{
return TongYi();
}
/// <summary>
/// 统一的方法
/// </summary>
/// <returns></returns>
private ActionResult TongYi()
{
ExtraData extradata = new ExtraData();
string IP = Tools.GetClientIP(this.HttpContext.Request);
extradata.RequestIP = IP;
var UUU = Request.Headers["authorization"];
string username = "boot";
string password = "#Ba~rk4ekf2,UdCW";
string u3 = string.Format("{0}:{1}", username, password);
string UUU1 = GetMD5Hash(u3).ToLower();
LogHelper.WriteLog("同城收到的数据为:" + UUU);
if (!UUU.ToLower().Equals(UUU1))
{
//return Json(new ResultAAA() { code = "500", message = "用户名 或者 密码错误" }, JsonRequestBehavior.AllowGet);
}
Request.InputStream.Position = 0;
byte[] reqBody = new byte[Request.InputStream.Length];
Request.InputStream.Read(reqBody, 0, reqBody.Length);
string reqData = System.Text.Encoding.UTF8.GetString(reqBody);
extradata.OriginalData = reqData;
LogHelper.WriteLog("同城收到的data为" + reqData);
if (string.IsNullOrEmpty(reqData))
{
return Json(new ResultAAA() { code = "500", message = "传递参数不能为空" }, JsonRequestBehavior.AllowGet);
}
try
{
PMSEntity req = JsonConvert.DeserializeObject<PMSEntity>(reqData);
int code = req.groupOrder.hotelCode;
string hotelCode = System.Configuration.ConfigurationManager.AppSettings[code.ToString()];
if (string.IsNullOrEmpty(hotelCode))
{
LogHelper.WriteLog($"hotelCode({hotelCode})不匹配或未配置");
return Json(new ResultAAA() { code = "500", message = $"hotel_id({hotelCode})不匹配或未配置" }, JsonRequestBehavior.AllowGet);
}
//ServiceReference1.blwwsSoapClient client = new ServiceReference1.blwwsSoapClient();
boonliverpms.blwws client = new boonliverpms.blwws();
string cookiestr = Newtonsoft.Json.JsonConvert.SerializeObject(extradata);
var cookie = new System.Net.Cookie("order_original", HttpUtility.UrlEncode(cookiestr), "/", cookiedomain);
client.CookieContainer = new System.Net.CookieContainer();
client.CookieContainer.Add(cookie);
bool blvResult = false;
string errorMsg = "";
List<OrderItem> OrderItems = req.groupOrder.orderItems;
foreach (OrderItem item in OrderItems)
{
StringBuilder xmlString = new StringBuilder();
string phoneNumber = "";
string idNumber = "";
var DDD = item.guests;
//一个订单中 登记一下负责人的电话号码即可
phoneNumber = DDD[0].tel;
idNumber = DDD[0].idCardNo;
string RoomNO = item.roomNo;
string Check_InTime = item.checkInTime;
DateTime check_in_time = DateTime.Now;
check_in_time = DateTime.Parse(Check_InTime);
switch (req.type)
{
case "0"://入住
case "1"://入住
case "4"://更新入住人
//①转发客控后台
if (DDD.Count > 0)
{
xmlString.Append("<interface>");
foreach (var guest in DDD)
{
string = guest.gender;
string idcard_type = guest.idCardType;
string idcard_no = guest.idCardNo;
string name = guest.name;
xmlString.Append("<item idtype=\"" + idcard_type + "\" idcard = \"" + idcard_no + "\" customer = \"" + name + "\" sex =\"" +
+ "\" country =\"0\" checkindate = \"" + check_in_time + "\"/>");
}
xmlString.Append("</interface>");
}
blvResult = client.CheckIn("blw_ws@2015", hotelCode, RoomNO, check_in_time, xmlString.ToString(), ref errorMsg, phoneNumber, idNumber);
//LogHelper.WriteLog($"转发BLV内部开房接口结果{blvResult},消息:{errorMsg}");
//②转发人脸机
//③转发宝镜系统
break;
case "5"://退房
case "13"://退房
case "11"://退房
blvResult = client.CheckOut("blw_ws@2015", hotelCode, RoomNO, check_in_time, ref errorMsg);
break;
case "6"://换房
case "7"://换房
//先退房
blvResult = client.CheckOut("blw_ws@2015", hotelCode, RoomNO, check_in_time, ref errorMsg);
//LogHelper.WriteLog($"转发BLV内部退房接口结果{blvResult},消息:{errorMsg}");
//再开房
if (DDD.Count > 0)
{
xmlString.Append("<interface>");
foreach (var guest in DDD)
{
string = guest.gender;
string idcard_type = guest.idCardType;
string idcard_no = guest.idCardNo;
string name = guest.name;
xmlString.Append("<item idtype=\"" + idcard_type + "\" idcard = \"" + idcard_no + "\" customer = \"" + name + "\" sex =\"" +
+ "\" country =\"0\" checkindate = \"" + check_in_time + "\"/>");
}
xmlString.Append("</interface>");
}
blvResult = client.CheckIn("blw_ws@2015", hotelCode, RoomNO, check_in_time, xmlString.ToString(), ref errorMsg, phoneNumber, idNumber);
break;
default:
LogHelper.WriteLog("宝莱威接口未处理type" + req.type);
blvResult = true;
break;
}
}
if (blvResult)
{
return Json(new ResultAAA() { code = "200", message = "SUCCESS" }, JsonRequestBehavior.AllowGet);
}
else
{
LogHelper.WriteLog(errorMsg);
LogHelper.WriteLog("收到Luopan2请求" + reqData);
return Json(new ResultAAA() { code = "500", message = errorMsg }, JsonRequestBehavior.AllowGet);
}
}
catch (Exception ex)
{
LogHelper.WriteLog(ex.ToString());
LogHelper.WriteLog("收到Luopan2请求" + reqData);
return Json(new ResultAAA() { code = "500", message = ex.Message }, JsonRequestBehavior.AllowGet);
}
}
#endregion
/// <summary>
/// XMS 订单信息变更推送接口
/// 西软 艾露酒店 1968
/// 这里面的
/// </summary>
/// <returns></returns>
[HttpPost()]
public ActionResult XMSOrderPush()
{
try
{
string IP = Tools.GetClientIP(Request);
var xrsecret = Request.Headers["xrsecret"];
//密钥Ip202rSR132zJGKH
//if (xrsecret.Equals("Ip202rSR132zJGKH"))
//{
Request.InputStream.Position = 0;
byte[] reqBody = new byte[Request.InputStream.Length];
Request.InputStream.Read(reqBody, 0, reqBody.Length);
string reqData = System.Text.Encoding.UTF8.GetString(reqBody);
if (string.IsNullOrEmpty(reqData))
{
return Json(new ResultAAA() { code = "500", message = "传递参数不能为空" }, JsonRequestBehavior.AllowGet);
}
LogHelper.WriteLog("XMSOrderPush:" + reqData.ToString());
var DDD = JsonConvert.DeserializeObject<XMSData>(reqData);
string username = "boot";
string password = "#Ba~rk4ekf2,UdCW";
string u3 = string.Format("{0}:{1}", username, password);
string UUU1 = GetMD5Hash(u3);
//string hotelCode = System.Configuration.ConfigurationManager.AppSettings[DDD.groupid.ToString()];
string hotelCode = DDD.groupid;
if (string.IsNullOrEmpty(hotelCode))
{
LogHelper.WriteLog($"hotelCode({hotelCode})不匹配或未配置");
return Json(new ResultAAA() { code = "500", message = $"hotel_id({hotelCode})不匹配或未配置" }, JsonRequestBehavior.AllowGet);
}
//ServiceReference1.blwwsSoapClient client = new ServiceReference1.blwwsSoapClient();
boonliverpms.blwws client = new boonliverpms.blwws();
try
{
ExtraData eee = new ExtraData();
eee.OriginalData = reqData;
eee.RequestIP = IP;
string sstr = JsonConvert.SerializeObject(eee);
string RRR = HttpUtility.UrlEncode(sstr);
var cookie = new System.Net.Cookie("order_original", RRR, "/", cookiedomain);
client.CookieContainer = new System.Net.CookieContainer();
client.CookieContainer.Add(cookie);
}
catch (Exception ex)
{
LogHelper.WriteLog("cookie: " + ex.Message);
}
bool blvResult = false;
string errorMsg = "";
var DDD_1 = DDD.extras;
StringBuilder xmlString = new StringBuilder();
//这个PMS 不会上传 手机号和身份证号
string idNumber = "";
string phoneNumber = DDD_1.mobile;
string RoomNO = DDD_1.roomno;
long Check_InTime = long.Parse(DDD_1.arr);
DateTime check_in_time = DateTime.Now;
check_in_time = ToLocalTimeDateByMilliseconds(Check_InTime);
switch (DDD_1.sta)
{
case "I"://入住
string = "";
string idcard_type = "";
string idcard_no = "";
string name = DDD_1.name;
XDocument doc1 = new XDocument();
var Root = new XElement("interface");
var Ele = new XElement("item", new XAttribute("idtype", idcard_type),
new XAttribute("idcard", idcard_no),
new XAttribute("customer", name),
new XAttribute("sex", ),
new XAttribute("country", "0"),
new XAttribute("checkindate", check_in_time));
Root.Add(Ele);
doc1.Add(Root);
string FxmlString = doc1.ToString();
//xmlString.Append("<interface>");
//xmlString.Append("<item idtype=\"" + idcard_type + "\" idcard = \"" + idcard_no + "\" customer = \"" + name + "\" sex =\"" +
// 性别 + "\" country =\"0\" checkindate = \"" + check_in_time + "\"/>");
//xmlString.Append("</interface>");
blvResult = client.CheckIn("blw_ws@2015", hotelCode, RoomNO, check_in_time, FxmlString, ref errorMsg, phoneNumber, idNumber);
break;
case "O"://退房
case "R"://退房
blvResult = client.CheckOut("blw_ws@2015", hotelCode, RoomNO, check_in_time, ref errorMsg);
break;
default:
LogHelper.WriteLog("宝莱威接口未处理type");
blvResult = true;
break;
}
if (blvResult)
{
return Json(new ResultAAA() { code = "200", message = "SUCCESS" }, JsonRequestBehavior.AllowGet);
}
else
{
LogHelper.WriteLog(errorMsg);
LogHelper.WriteLog("收到 XMS 请求:" + reqData);
return Json(new ResultAAA() { code = "500", message = errorMsg }, JsonRequestBehavior.AllowGet);
}
}
catch (Exception ex)
{
return Json(new { code = 500, msg = ex.Message, data = new { } }, JsonRequestBehavior.AllowGet);
}
return Json(new { code = 200, msg = "success", data = new { } }, JsonRequestBehavior.AllowGet);
}
}
//{
// "accnt":"F2506200002",
// "original":{
// "name":"李一"
// },
// "groupid":"1968",
// "name":"李二",
// "extras":{
// "arr":"1750586400000",
// "rtc":"CPC",
// "sta":"R",
// "rmnum":"1",
// "roomno":"",
// "mobile":"1212345678",
// "name":"李二",
// "type":"CPC",
// "dep":"1750651200000"
// },
// "hotelid":"H000068"
//}
public class XMSData
{
public string hotelid { get; set; }
/// <summary>
/// 订单账号(酒店唯一)
/// </summary>
public string accnt { get; set; }
public string groupid { get; set; }
public string name { get; set; }
public Dictionary<string, string> original { get; set; }
public extrasData extras { get; set; }
}
public class originalData
{
//public string name { get; set; }
//public string mobile { get; set; }
//public string roomno { get; set; }
//public string type { get; set; }
//public string rtc { get; set; }
//public string rmnum { get; set; }
//public string sta { get; set; }
}
// "arr":"1750586400000",
// "rtc":"CPC",
// "sta":"R",
// "rmnum":"1",
// "roomno":"",
// "mobile":"1212345678",
// "name":"李二",
// "type":"CPC",
// "dep":"1750651200000"
public class extrasData
{
public string name { get; set; }
public string mobile { get; set; }
/// <summary>
/// 房间号
/// </summary>
public string roomno { get; set; }
public string type { get; set; }
public string rtc { get; set; }
public string rmnum { get; set; }
/// <summary>
/// 订单状态
///Q问询
///X取消预订
///Nnoshow
///R预订
///I在住
///O本日结账
///S挂账退房
///D昨日结账
///H历史订单
/// </summary>
public string sta { get; set; }
public string arr { get; set; }
public string dep { get; set; }
}
}

View File

@@ -0,0 +1,22 @@
using BLV_API.Dal;
using BLV_API.Models;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace BLV_API.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Title = "欢迎访问宝来威客控接口服务";
return View();
}
}
}

View File

@@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
namespace BLV_API.Controllers
{
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)
{
}
}
}

View File

@@ -0,0 +1,184 @@
using BLV_API.Models;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data.SqlTypes;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;
using System.Web.Mvc;
namespace BLV_API.Controllers
{
public class testController : Controller
{
//// GET: test
//public ActionResult Index()
//{
// return View();
//}
public ActionResult LuopanToBonjing()
{
Request.InputStream.Position = 0;
byte[] reqBody = new byte[Request.InputStream.Length];
Request.InputStream.Read(reqBody, 0, reqBody.Length);
string reqData = System.Text.Encoding.UTF8.GetString(reqBody);
if (string.IsNullOrEmpty(reqData))
{
return Json(new LuopanEntity.Result() { status = 1, error_msg = "传递参数不能为空" }, JsonRequestBehavior.AllowGet);
}
try
{
LuopanEntity.Root req = JsonConvert.DeserializeObject<LuopanEntity.Root>(reqData);
ServiceReference1.blwwsSoapClient client = new ServiceReference1.blwwsSoapClient();
string errorMsg = "";
bool blvResult;
StringBuilder xmlString = new StringBuilder();
string phoneNumber = "";
string idNumber = "";
switch (req.Action)
{
case "CheckIn":
if (req.GuestInfo.Count > 0)
{
phoneNumber = req.GuestInfo[0].Mobile;
idNumber = req.GuestInfo[0].IDCardNo;
xmlString.Append("<interface>");
foreach (LuopanEntity.GuestInfo guest in req.GuestInfo)
{
xmlString.Append("<item idtype=\"" + guest.IDCardTypeId + "\" idcard = \"" + guest.IDCardNo + "\" customer = \"" + guest.GuestName + "\" sex =\"" +
(guest.Gender == 0 ? "男" : "女") + "\" country =\"0\" checkindate = \"" + req.CheckInTime.ToString("yyyy-MM-dd HH:mm:ss") + "\"/>");
}
xmlString.Append("</interface>");
}
blvResult = client.CheckIn("blw_ws@2015", req.HotelId, req.RoomNo, req.CheckInTime, xmlString.ToString(), ref errorMsg, phoneNumber, idNumber);
LogHelper.WriteLog($"转发BLV内部开房接口结果{blvResult},消息:{errorMsg}");
bool cbj= CheckInBaoJing.CheckInToBaoJing(req);
break;
default:
break;
}
return Json(new LuopanEntity.Result() { status = 0, error_msg = "" }, JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
return Json(new LuopanEntity.Result() { status = 1, error_msg = ex.Message }, JsonRequestBehavior.AllowGet);
}
}
}
public static class CheckInBaoJing
{
public static bool CheckInToBaoJing(LuopanEntity.Root root)
{
baojinginfoCheckIn bjch = new baojinginfoCheckIn();
//infoslist ils= new infoslist();
bjch.hotel_id = root.HotelId;
bjch.room_no = root.RoomNo;
bjch.checkIn = root.CheckInTime;
bjch.checkOut=root.CheckOutTime;
bjch.is_breakfast = 0;
bjch.breakfast = 0;
bjch.rateCode = "";
bjch.amount = "";
//bjch.infos.Add(ils);
if (root.GuestInfo.Count > 0)
{
foreach (var info in root.GuestInfo)
{
infoslist ils = new infoslist();
ils.name= info.GuestName;
ils.type = (info.IDCardTypeId == "身份证" ? 0 : (info.IDCardTypeId == "护照"?1:2));
ils.idcard = info.IDCardNo;
ils.sex = info.Gender;
ils.address = info.Address;
bjch.infos.Add(ils);
}
}
string url = "http://www.higmkj.com:8056/api/v1/order/checkIn";
string token = "Your token";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
request.ContentType = "application/json";
request.Headers.Add("Authorization", "Bearer " + token);
request.Headers.Add("hotelCode", root.HotelId);
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
baojinginfoCheckIn jsonPayload = bjch;
streamWriter.Write(jsonPayload);
}
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
using (var streamReader = new StreamReader(response.GetResponseStream()))
{
string result = streamReader.ReadToEnd();
Console.WriteLine(result);
}
//public int breakfast { get; set; }
//public string { get; set; }
//public string { get; set; }
return true;
}
}
public class baojinginfoCheckIn
{
public baojinginfoCheckIn()
{
infos = new List<infoslist>();
}
public string hotel_id { get; set; }
public string room_no { get; set;}
public DateTime checkIn { get; set; }
public DateTime checkOut { get; set; }
public int is_breakfast { get; set; }
public int breakfast { get;set; }
public string rateCode { get; set; }
public string amount { get; set; }
public List<infoslist> infos { get; set; }
}
public class infoslist
{
public string name { get; set; }
public string mobile { get; set; }
public int type { get; set; }
public string idcard { get; set; }
public int sex { get; set; }
public string address { get; set; }
}
}

25
BLV_API/Dal/DbProvider.cs Normal file
View File

@@ -0,0 +1,25 @@
namespace BLV_API.Dal
{
public class DbProvider
{
private static string _SqlConnectionStr = null;
public static string SqlConnectionStr
{
get
{
if (_SqlConnectionStr == null)
{
_SqlConnectionStr = System.Configuration.ConfigurationManager.AppSettings["connectionString"];
}
return _SqlConnectionStr;
}
}
public static SqlHelper SqlServer
{
get
{
return new SqlHelper(SqlConnectionStr);
}
}
}
}

399
BLV_API/Dal/SqlHelper.cs Normal file
View File

@@ -0,0 +1,399 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
namespace BLV_API.Dal
{
public class SqlHelper
{
/// <summary>
/// 数据库连接字符串
/// Data Source=数据库地址;Initial Catalog=数据库名称;Persist Security Info=True;User ID=用户名;Password=密码
/// </summary>
private string _SqlConnectionStr = "";
public string SqlConnectionStr { get { return _SqlConnectionStr; } }
public SqlHelper(string connStr)
{
this._SqlConnectionStr = connStr;
}
#region
public string GetSingle(string sqlStr)
{
using (SqlConnection conn = new SqlConnection(this._SqlConnectionStr))
{
using (SqlCommand cmd = new SqlCommand(sqlStr, conn))
{
try
{
conn.Open();
return String.Format("{0}", cmd.ExecuteScalar());
}
catch (SqlException e)
{
throw e;
}
finally
{
conn.Close();
}
}
}
}
public string GetSingle(string sqlStr, SqlParameter[] cmdParams)
{
using (SqlConnection conn = new SqlConnection(this._SqlConnectionStr))
{
using (SqlCommand cmd = new SqlCommand())
{
try
{
conn.Open();
cmd.Connection = conn;
cmd.CommandType = CommandType.Text;
cmd.CommandText = sqlStr;
cmd.Parameters.AddRange(cmdParams);
return String.Format("{0}", cmd.ExecuteScalar());
}
catch (SqlException e)
{
throw e;
}
finally
{
conn.Close();
}
}
}
}
#endregion
#region
public DataSet Query(string sqlStr)
{
using (SqlConnection conn = new SqlConnection(this._SqlConnectionStr))
{
using (SqlDataAdapter ada = new SqlDataAdapter(sqlStr, conn))
{
try
{
conn.Open();
DataSet ds = new DataSet();
ada.Fill(ds);
return ds;
}
catch (SqlException e)
{
throw e;
}
finally
{
conn.Close();
}
}
}
}
public DataSet Query(string sqlStr, SqlParameter[] cmdParams)
{
using (SqlConnection conn = new SqlConnection(this._SqlConnectionStr))
{
using (SqlCommand cmd = new SqlCommand())
{
using (SqlDataAdapter ada = new SqlDataAdapter(cmd))
{
try
{
conn.Open();
cmd.Connection = conn;
cmd.CommandType = CommandType.Text;
cmd.CommandText = sqlStr;
cmd.Parameters.AddRange(cmdParams);
DataSet ds = new DataSet();
ada.Fill(ds);
return ds;
}
catch (SqlException e)
{
throw e;
}
finally
{
conn.Close();
}
}
}
}
}
public DataSet RunProcedure(string procName, SqlParameter[] cmdParams)
{
using (SqlConnection conn = new SqlConnection(this._SqlConnectionStr))
{
using (SqlCommand cmd = new SqlCommand())
{
using (SqlDataAdapter ada = new SqlDataAdapter(cmd))
{
try
{
conn.Open();
cmd.Connection = conn;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = procName;
cmd.Parameters.AddRange(cmdParams);
DataSet ds = new DataSet();
ada.Fill(ds);
return ds;
}
catch (SqlException e)
{
throw e;
}
finally
{
conn.Close();
}
}
}
}
}
#endregion
#region
public DataTable GetQueryData(string sqlStr)
{
DataSet ds = Query(sqlStr);
if (ds != null && ds.Tables.Count > 0)
return ds.Tables[0];
return null;
}
public DataTable GetQueryData(string sqlStr, SqlParameter[] cmdParams)
{
DataSet ds = Query(sqlStr, cmdParams);
if (ds != null && ds.Tables.Count > 0)
return ds.Tables[0];
return null;
}
public DataTable GetProcData(string procName, SqlParameter[] cmdParams)
{
DataSet ds = RunProcedure(procName, cmdParams);
if (ds != null && ds.Tables.Count > 0)
return ds.Tables[0];
return null;
}
#endregion
#region
public DataRow GetQueryRecord(string sqlStr)
{
DataTable dt = GetQueryData(sqlStr);
if (dt != null && dt.Rows.Count > 0)
return dt.Rows[0];
return null;
}
public DataRow GetQueryRecord(string sqlStr, SqlParameter[] cmdParams)
{
DataTable dt = GetQueryData(sqlStr, cmdParams);
if (dt != null && dt.Rows.Count > 0)
return dt.Rows[0];
return null;
}
public DataRow GetProcRecord(string procName, SqlParameter[] cmdParams)
{
DataTable dt = GetProcData(procName, cmdParams);
if (dt != null && dt.Rows.Count > 0)
return dt.Rows[0];
return null;
}
#endregion
#region 使Reader
public SqlDataReader ExecuteReader(string sqlStr)
{
SqlConnection conn = new SqlConnection(this._SqlConnectionStr);
SqlCommand cmd = new SqlCommand(sqlStr, conn);
try
{
conn.Open();
return cmd.ExecuteReader(CommandBehavior.CloseConnection);
}
catch (SqlException e)
{
throw e;
}
}
public SqlDataReader ExecuteReeder(string sqlStr, SqlParameter[] cmdParams)
{
SqlConnection conn = new SqlConnection(this._SqlConnectionStr);
SqlCommand cmd = new SqlCommand();
try
{
conn.Open();
cmd.Connection = conn;
cmd.CommandType = CommandType.Text;
cmd.CommandText = sqlStr;
cmd.Parameters.AddRange(cmdParams);
return cmd.ExecuteReader(CommandBehavior.CloseConnection);
}
catch (SqlException e)
{
throw e;
}
}
#endregion
#region sql语句
public int ExecuteSql(string sqlStr)
{
using (SqlConnection conn = new SqlConnection(this._SqlConnectionStr))
{
using (SqlCommand cmd = new SqlCommand(sqlStr, conn))
{
try
{
conn.Open();
return cmd.ExecuteNonQuery();
}
catch (SqlException e)
{
throw e;
}
finally
{
conn.Close();
}
}
}
}
public int ExecuteSql(string sqlStr, SqlParameter[] cmdParams)
{
using (SqlConnection conn = new SqlConnection(this._SqlConnectionStr))
{
using (SqlCommand cmd = new SqlCommand())
{
try
{
conn.Open();
cmd.Connection = conn;
cmd.CommandType = CommandType.Text;
cmd.CommandText = sqlStr;
cmd.Parameters.AddRange(cmdParams);
return cmd.ExecuteNonQuery();
}
catch (SqlException e)
{
throw e;
}
finally
{
conn.Close();
}
}
}
}
#endregion
#region
public int ExecuteSqlTran(List<string> sqlStrList)
{
using (SqlConnection conn = new SqlConnection(this._SqlConnectionStr))
{
using (SqlCommand cmd = new SqlCommand())
{
using (SqlTransaction tran = conn.BeginTransaction())
{
try
{
cmd.Connection = conn;
cmd.CommandType = CommandType.Text;
cmd.Transaction = tran;
conn.Open();
int count = 0;
foreach (string sql in sqlStrList)
{
cmd.CommandText = sql;
count += cmd.ExecuteNonQuery();
}
tran.Commit();
return count;
}
catch (SqlException e)
{
tran.Rollback();
throw e;
}
finally
{
conn.Close();
}
}
}
}
}
public int ExecuteSqlTran(List<KeyValuePair<string, SqlParameter[]>> sqlStrList)
{
using (SqlConnection conn = new SqlConnection(this._SqlConnectionStr))
{
using (SqlCommand cmd = new SqlCommand())
{
using (SqlTransaction tran = conn.BeginTransaction())
{
try
{
cmd.Connection = conn;
cmd.CommandType = CommandType.Text;
cmd.Transaction = tran;
conn.Open();
int count = 0;
foreach (var item in sqlStrList)
{
cmd.CommandText = item.Key;
cmd.Parameters.Clear();
cmd.Parameters.AddRange(item.Value);
count += cmd.ExecuteNonQuery();
}
tran.Commit();
return count;
}
catch (SqlException e)
{
tran.Rollback();
throw e;
}
finally
{
conn.Close();
}
}
}
}
}
public int ExecuteProc(string procName, SqlParameter[] cmdParams)
{
using (SqlConnection conn = new SqlConnection(this._SqlConnectionStr))
{
using (SqlCommand cmd = new SqlCommand())
{
try
{
conn.Open();
cmd.Connection = conn;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = procName;
cmd.Parameters.AddRange(cmdParams);
return cmd.ExecuteNonQuery();
}
catch (SqlException e)
{
throw e;
}
finally
{
conn.Close();
}
}
}
}
#endregion
}
}

1
BLV_API/Global.asax Normal file
View File

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

23
BLV_API/Global.asax.cs Normal file
View File

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

117
BLV_API/LogHelper.cs Normal file
View File

@@ -0,0 +1,117 @@
using System;
using System.IO;
using System.Text;
namespace BLV_API
{
/// <summary>
/// 日志辅助类
/// </summary>
public static class LogHelper
{
private static string ExePath = Tools.GetApplicationPath();
/// <summary>
/// 日志写入到批定的文件路径下
/// </summary>
/// <param name="msg"></param>
public static void WriteLog(string msg)
{
string path = ExePath + "\\logs\\" + DateTime.Now.ToString("yyyyMMdd") + ".log";
msg = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ":\t " + msg + Environment.NewLine;
WriteLog(path, msg, true);
}
/// <summary>
/// 把数据写入指定的文件里
/// </summary>
/// <param name="path">文件路径(包括文件名称)</param>
/// <param name="msg">写入内容</param>
/// <param name="append">是否追加</param>
public static void WriteLog(string path, string msg, bool append, bool needHidden = false)
{
string folder = Path.GetDirectoryName(path);
if (!Directory.Exists(folder))
{
Directory.CreateDirectory(folder);
}
StreamWriter sw = null;
try
{
sw = new StreamWriter(path, append, Encoding.Unicode);
sw.WriteLine(msg);
}
catch (Exception)
{
}
finally
{
if (sw != null)
{
sw.Close();
}
}
if (needHidden)
{
File.SetAttributes(path, FileAttributes.Hidden);//设置添加隐藏文件夹
}
}
/// <summary>
/// 把数据写入指定的文件里
/// </summary>
/// <param name="path"></param>
/// <param name="msg"></param>
public static void WriteLog(string path, byte[] msg)
{
string folder = Path.GetDirectoryName(path);
if (!Directory.Exists(folder))
{
Directory.CreateDirectory(folder);
}
FileStream fs = null;
try
{
fs = new FileStream(path, FileMode.Append, FileAccess.Write);
fs.Write(msg, 0, msg.Length);
}
catch (Exception)
{
}
finally
{
if (fs != null)
{
fs.Close();
}
}
}
/// <summary>
/// 读取文件内容
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public static string ReadLog(string path)
{
if (File.Exists(path))
{
StreamReader sr = null;
try
{
sr = new StreamReader(path);
return sr.ReadToEnd();
}
catch (Exception)
{
}
finally
{
if (sr != null)
{
sr.Close();
}
}
}
return "";
}
}
}

130
BLV_API/Models/BLVEntity.cs Normal file
View File

@@ -0,0 +1,130 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace BLV_API.Models
{
public class BLVEntity
{
/// <summary>
/// 入住人信息
/// </summary>
public class InfosItem
{
/// <summary>
/// 姓名
/// </summary>
public string name { get; set; }
/// <summary>
/// 手机号
/// </summary>
public string mobile { get; set; }
/// <summary>
/// 证件类型0-身份证1-护照2-其他
/// </summary>
public int type { get; set; }
/// <summary>
/// 证件号
/// </summary>
public string idcard { get; set; }
/// <summary>
/// 性别0-未知1-男2-女
/// </summary>
public int sex { get; set; }
/// <summary>
/// 常住地址
/// </summary>
public string address { get; set; }
}
/// <summary>
/// 主数据入口
/// </summary>
public class Root
{
/// <summary>
/// 酒店编码
/// </summary>
public string hotel_code { get; set; }
/// <summary>
/// 时间戳
/// </summary>
public long time { get; set; }
/// <summary>
/// 签名
/// </summary>
public string sign { get; set; }
/// <summary>
/// 酒店ID
/// </summary>
public string hotel_id { get; set; }
/// <summary>
/// 入住单号
/// </summary>
public string order_no { get; set; }
/// <summary>
/// 房间号
/// </summary>
public string room_no { get; set; }
/// <summary>
/// 新房间号(换房使用)
/// </summary>
public string new_room_no { get; set; }
/// <summary>
/// 入住时间
/// </summary>
public DateTime checkIn { get; set; }
/// <summary>
/// 离店时间
/// </summary>
public DateTime checkOut { get; set; }
/// <summary>
/// 续住时间(续住使用)
/// </summary>
public DateTime stayDateTime { get; set; }
/// <summary>
/// 是否含早1-含早0-未含早
/// </summary>
public int is_breakfast { get; set; }
/// <summary>
/// 早餐数量
/// </summary>
public int breakfast { get; set; }
/// <summary>
/// 房价码
/// </summary>
public string rateCode { get; set; }
/// <summary>
/// 订单总额
/// </summary>
public decimal amount { get; set; }
/// <summary>
/// 入住人信息
/// </summary>
public List<InfosItem> infos { get; set; }
}
public class Result
{
/// <summary>
/// 返回编码200成功4001传参错误30001账号未授权请联系管理员30002Token失效
/// </summary>
public int code { get; set; }
/// <summary>
/// 返回信息
/// </summary>
public string msg { get; set; }
/// <summary>
/// 返回数据
/// </summary>
//public ResultData data { get; set; }
}
public class ResultData
{
/// <summary>
///
/// </summary>
public string token { get; set; }
}
}
}

View File

@@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace BLV_API.Models
{
public class CRICSEntity
{
public class Request
{
/// <summary>
/// 客控后台酒店编码
/// </summary>
public string HotelCode { get; set; }
/// <summary>
/// 房号
/// </summary>
public string RoomNumber { get; set; }
/// <summary>
/// 设置房态2出租4待租8退房16空房
/// </summary>
public int RoomStatusID { get; set; }
}
public class Response
{
/// <summary>
/// 是否成功
/// </summary>
public bool IsSuccess { get; set; }
/// <summary>
/// 结果信息
/// </summary>
public string Result { get; set; }
}
}
}

View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace BLV_API.Models
{
public class ExtraData
{
public string OriginalData { get; set; }
public string RequestIP { get; set; }
}
}

View File

@@ -0,0 +1,249 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace BLV_API.Models
{
public class Luopan2Entity
{
/// <summary>
/// 入住人信息
/// </summary>
public class GuestsItem
{
/// <summary>
///
/// </summary>
public string code { get; set; }
/// <summary>
/// 马建华
/// </summary>
public string last_name { get; set; }
/// <summary>
///
/// </summary>
public string first_name { get; set; }
/// <summary>
///
/// </summary>
public int gender_id { get; set; }
/// <summary>
///
/// </summary>
public int? salutation_id { get; set; }
/// <summary>
///
/// </summary>
public string id_card_no { get; set; }
/// <summary>
///
/// </summary>
public int? id_card_type_id { get; set; }
/// <summary>
///
/// </summary>
public string birthday { get; set; }
/// <summary>
/// 山东省济南市市中区
/// </summary>
public string address { get; set; }
/// <summary>
///
/// </summary>
public string mobile { get; set; }
/// <summary>
///
/// </summary>
public string email { get; set; }
/// <summary>
///
/// </summary>
public string ethnicity { get; set; }
/// <summary>
///
/// </summary>
public string city_code { get; set; }
/// <summary>
///
/// </summary>
public string country_code { get; set; }
/// <summary>
/// 济南
/// </summary>
public string city_name { get; set; }
/// <summary>
///
/// </summary>
public string province_code { get; set; }
/// <summary>
///
/// </summary>
public string locale { get; set; }
/// <summary>
///
/// </summary>
public bool is_main_guest { get; set; }
}
public class Root
{
/// <summary>
/// 接口类型新房间入住reg.checkin在房间添加入住客人guest.checkin退房reg.checkout客人退出房间guest.checkout
/// 登记单整体换房reg.move房间某个住客换房guest.move房间修改离店日期提前离店或者延住reg.change_checkout
/// </summary>
public string type { get; set; }
/// <summary>
///
/// </summary>
public long timestamp { get; set; }
/// <summary>
///
/// </summary>
public string message_id { get; set; }
/// <summary>
///
/// </summary>
public string hotel_id { get; set; }
/// <summary>
///
/// </summary>
public string register_id { get; set; }
/// <summary>
///
/// </summary>
public string resv_id { get; set; }
/// <summary>
/// 范钦浩
/// </summary>
public string operator_name { get; set; }
/// <summary>
///
/// </summary>
public string conf_no { get; set; }
/// <summary>
///
/// </summary>
public string room_no { get; set; }
/// <summary>
///
/// </summary>
public string old_room_no { get; set; }
/// <summary>
///
/// </summary>
public string new_room_no { get; set; }
/// <summary>
///
/// </summary>
public string room_type_code { get; set; }
/// <summary>
///
/// </summary>
public string building_code { get; set; }
/// <summary>
///
/// </summary>
public string floor_code { get; set; }
/// <summary>
///
/// </summary>
public string phone_no { get; set; }
/// <summary>
///
/// </summary>
public string door_no { get; set; }
/// <summary>
///
/// </summary>
public string police_no { get; set; }
/// <summary>
///
/// </summary>
public DateTime? check_in_time { get; set; }= DateTime.Now;
/// <summary>
///
/// </summary>
public DateTime? check_out_time { get; set; }=DateTime.Now;
/// <summary>
///
/// </summary>
public DateTime? move_time { get; set; }= DateTime.Now;
/// <summary>
///
/// </summary>
public DateTime? old_check_out_time { get; set; }
/// <summary>
///
/// </summary>
public string vehicle_no { get; set; }
/// <summary>
///
/// </summary>
public string guest_mobile { get; set; }
/// <summary>
///
/// </summary>
public string guest_old_name { get; set; }
/// <summary>
///
/// </summary>
public long check_in_date { get; set; }
/// <summary>
///
/// </summary>
public long check_out_date { get; set; }
/// <summary>
///
/// </summary>
public string locale { get; set; }
/// <summary>
/// 协议
/// </summary>
public string market_group_name { get; set; }
/// <summary>
///
/// </summary>
public string msg_content { get; set; }
/// <summary>
///
/// </summary>
public string msg_from_name { get; set; }
/// <summary>
///
/// </summary>
public string msg_from_salutation { get; set; }
/// <summary>
///
/// </summary>
public string msg_to_name { get; set; }
/// <summary>
///
/// </summary>
public string blackGuid { get; set; }
/// <summary>
///
/// </summary>
public List<GuestsItem> guests { get; set; }
/// <summary>
///
/// </summary>
public GuestsItem mainGuest { get; set; }
}
/// <summary>
/// 返回数据包
/// </summary>
public class Result
{
/// <summary>
/// 0表示成功1表示失败不再重试2表示失败希望Luopan再重发
/// </summary>
public int status { get; set; }
/// <summary>
/// 如果失败,这里返回失败的描述信息
/// </summary>
public string error_msg { get; set; }
}
}
}

View File

@@ -0,0 +1,253 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace BLV_API.Models
{
public class LuopanEntity
{
/// <summary>
/// 入住人信息
/// </summary>
public class GuestInfo
{
/// <summary>
/// 罗盘系统里对客人的唯一主键标识
/// </summary>
public string Id { get; set; }
/// <summary>
/// 称呼:先生、女士
/// </summary>
public string Salutation { get; set; }
/// <summary>
/// 入住人姓名
/// </summary>
public string GuestName { get; set; }
/// <summary>
/// 证件号
/// </summary>
public string IDCardNo { get; set; }
/// <summary>
/// 证件类型
/// </summary>
public string IDCardTypeId { get; set; }
/// <summary>
/// 性别0男1女
/// </summary>
public int Gender { get; set; }
/// <summary>
/// 生日1992-04-27
/// </summary>
public string Birthday { get; set; }
/// <summary>
/// 身份证地址
/// </summary>
public string Address { get; set; }
/// <summary>
/// 手机号
/// </summary>
public string Mobile { get; set; }
/// <summary>
/// 城市代码
/// </summary>
public string CityCode { get; set; }
/// <summary>
/// 省份代码
/// </summary>
public string ProvinceCode { get; set; }
/// <summary>
/// 乡镇代码
/// </summary>
public string CountryCode { get; set; }
/// <summary>
/// 签证号码
/// </summary>
public string VisaNo { get; set; }
/// <summary>
/// 签证种类代码
/// </summary>
public string VisaTypeId { get; set; }
/// <summary>
/// 签证有效期
/// </summary>
public string VisaValid { get; set; }
/// <summary>
///
/// </summary>
public string VipType { get; set; }
}
/// <summary>
/// 主数据入口
/// </summary>
public class Root
{
/// <summary>
/// 动作:新房间入住或者在房间里添加入住人 CheckIn
/// 退房或移出客人 CheckOut
/// 换房包括将登记单换房以及某个客人从A 房间挪到 B 房间MoveRoom
/// 房间延住 Extend
/// </summary>
public string Action { get; set; }
/// <summary>
/// 酒店ID
/// </summary>
public string HotelId { get; set; }
/// <summary>
/// 注册码
/// </summary>
public string RegisterId { get; set; }
/// <summary>
/// 房间ID
/// </summary>
public string RoomId { get; set; }
/// <summary>
/// 房间号
/// </summary>
public string RoomNo { get; set; }
/// <summary>
/// 房型ID
/// </summary>
public string RoomTypeId { get; set; }
/// <summary>
/// 房型
/// </summary>
public string RoomTypeName { get; set; }
/// <summary>
///
/// </summary>
public string RateCode { get; set; }
/// <summary>
/// 楼名称
/// </summary>
public string RoomBuildingName { get; set; }
/// <summary>
/// 楼编号
/// </summary>
public string RoomBuildingCode { get; set; }
/// <summary>
/// 楼层名称
/// </summary>
public string RoomFloorName { get; set; }
/// <summary>
/// 楼层编号
/// </summary>
public string RoomFloorCode { get; set; }
/// <summary>
/// 入住时间
/// </summary>
public DateTime CheckInTime { get; set; }
/// <summary>
/// 预计离店时间
/// </summary>
public DateTime CheckOutTime { get; set; }
/// <summary>
/// 是否开一个新房间true 表示是新房间入住, false 是挪入新同住
/// </summary>
public bool CheckInRoom { get; set; }
/// <summary>
/// 是否将房间退房false 表示仅客人挪走,房间不退
/// </summary>
public bool CheckOutRoom { get; set; }
/// <summary>
/// 要移出的房间号
/// </summary>
public string OldRoomNo { get; set; }
/// <summary>
///
/// </summary>
public string OldRoomTypeId { get; set; }
/// <summary>
/// 豪华单人间
/// </summary>
public string OldRoomTypeName { get; set; }
/// <summary>
/// 13楼
/// </summary>
public string OldRoomBuildingName { get; set; }
/// <summary>
///
/// </summary>
public string OldRoomBuildingCode { get; set; }
/// <summary>
/// 五楼
/// </summary>
public string OldRoomFloorName { get; set; }
/// <summary>
///
/// </summary>
public string OldRoomFloorCode { get; set; }
/// <summary>
/// 要移到的房间号
/// </summary>
public string NewRoomNo { get; set; }
/// <summary>
///
/// </summary>
public string NewRoomTypeId { get; set; }
/// <summary>
/// 豪华单人间
/// </summary>
public string NewRoomTypeName { get; set; }
/// <summary>
/// 13楼
/// </summary>
public string NewRoomBuildingName { get; set; }
/// <summary>
///
/// </summary>
public string NewRoomBuildingCode { get; set; }
/// <summary>
/// 五楼
/// </summary>
public string NewRoomFloorName { get; set; }
/// <summary>
///
/// </summary>
public string NewRoomFloorCode { get; set; }
/// <summary>
/// 换房时间
/// </summary>
public DateTime MoveTime { get; set; }
/// <summary>
/// 是否对旧房间退房true 表示是整体登记单换房
/// </summary>
public bool CheckOutOldRoom { get; set; }
/// <summary>
/// 是否换到一个已经入住的房间false 表示换到一个空房
/// </summary>
public bool MoveToInHouse { get; set; }
/// <summary>
/// 订单ID
/// </summary>
public string OrderId { get; set; }
/// <summary>
/// /所属团队 ID
/// </summary>
public string GroupId { get; set; }
/// <summary>
/// 车牌号,目前对接停车场系统
/// </summary>
public string RegisterNo { get; set; }
/// <summary>
///
/// </summary>
public string AllocationId { get; set; }
/// <summary>
/// 入住人信息
/// </summary>
public List<GuestInfo> GuestInfo { get; set; }
}
public class Result
{
/// <summary>
/// 0表示成功1表示失败不再重试2表示失败希望Qtels再重发
/// </summary>
public int status { get; set; }
/// <summary>
/// 如果失败,这里返回失败的描述信息
/// </summary>
public string error_msg { get; set; }
}
}
}

View File

@@ -0,0 +1,84 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace BLWWS
{
public class ResultAAA
{
public string code { get; set; }
public string message { get; set; }
}
public class PMSEntity
{
public GroupOrder groupOrder { get; set; }
public string trackingId { get; set; }
/// <summary>
/// 推送的数据类型,字典见 4.1推送数据类型
/// </summary>
public string type { get; set; }
}
public class GroupOrder
{
public int chainId { get; set; }
public int hotelCode { get; set; }
public int orderId { get; set; }
public List<OrderItem> orderItems { get; set; }
public string reserveEmail { get; set; }
public string reserveMemberNo { get; set; }
public string reserveName { get; set; }
public string reserveTel { get; set; }
}
public class OrderItem
{
public string channelName { get; set; }
public string checkInTime { get; set; }
public string checkOutTime { get; set; }
public List<Guest> guests { get; set; }
/// <summary>
/// 换房前的房间号
/// </summary>
public string oldRoomNo { get; set; }
public int orderItemId { get; set; }
public string price { get; set; }
/// <summary>
/// roomNo
/// </summary>
public string roomNo { get; set; }
public int roomTypeCode { get; set; }
public string roomTypeName { get; set; }
/// <summary>
/// 订单状态, 字典见 4.2
/// </summary>
public int state { get; set; }
}
public class Guest
{
public string birthDate { get; set; }
public string carLicense { get; set; }
public string email { get; set; }
public string gender { get; set; }
public string guestId { get; set; }
public string idCardNo { get; set; }
public string idCardType { get; set; }
public string memberNo { get; set; }
public string name { get; set; }
public string oldCardNo { get; set; }
public string tel { get; set; }
}
public enum DicType
{
=0,
=4,
退=5,
=6,
=7,
=11,
退=13
}
}

84
BLV_API/PMSEntity.cs Normal file
View File

@@ -0,0 +1,84 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace BLWWS
{
public class ResultAAA
{
public string code { get; set; }
public string message { get; set; }
}
public class PMSEntity
{
public GroupOrder groupOrder { get; set; }
public string trackingId { get; set; }
/// <summary>
/// 推送的数据类型,字典见 4.1推送数据类型
/// </summary>
public string type { get; set; }
}
public class GroupOrder
{
public int chainId { get; set; }
public int hotelCode { get; set; }
public int orderId { get; set; }
public List<OrderItem> orderItems { get; set; }
public string reserveEmail { get; set; }
public string reserveMemberNo { get; set; }
public string reserveName { get; set; }
public string reserveTel { get; set; }
}
public class OrderItem
{
public string channelName { get; set; }
public string checkInTime { get; set; }
public string checkOutTime { get; set; }
public List<Guest> guests { get; set; }
/// <summary>
/// 换房前的房间号
/// </summary>
public string oldRoomNo { get; set; }
public int orderItemId { get; set; }
public string price { get; set; }
/// <summary>
/// roomNo
/// </summary>
public string roomNo { get; set; }
public int roomTypeCode { get; set; }
public string roomTypeName { get; set; }
/// <summary>
/// 订单状态, 字典见 4.2
/// </summary>
public int state { get; set; }
}
public class Guest
{
public string birthDate { get; set; }
public string carLicense { get; set; }
public string email { get; set; }
public string gender { get; set; }
public string guestId { get; set; }
public string idCardNo { get; set; }
public string idCardType { get; set; }
public string memberNo { get; set; }
public string name { get; set; }
public string oldCardNo { get; set; }
public string tel { get; set; }
}
public enum DicType
{
=0,
=4,
退=5,
=6,
=7,
=11,
退=13
}
}

View File

@@ -0,0 +1,35 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的常规信息是通过以下项进行控制的
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("PTS_API_V1")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("PTS_API_V1")]
[assembly: AssemblyCopyright("版权所有(C) 2023")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 将使此程序集中的类型
// 对 COM 组件不可见。如果需要
// 从 COM 访问此程序集中的某个类型,请针对该类型将 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于 typelib 的 ID
[assembly: Guid("faef0482-a165-4f6b-92af-0753e9006dd6")]
// 程序集的版本信息由下列四个值组成:
//
// 主版本
// 次版本
// 内部版本号
// 修订版本
//
// 你可以指定所有值,也可以让修订版本和内部版本号采用默认值,
// 方法是按如下所示使用 "*":
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

36
BLV_API/Properties/Settings.Designer.cs generated Normal file
View File

@@ -0,0 +1,36 @@
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行时版本:4.0.30319.42000
//
// 对此文件的更改可能会导致不正确的行为,并且如果
// 重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------
namespace BLV_API.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.12.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.SpecialSettingAttribute(global::System.Configuration.SpecialSetting.WebServiceUrl)]
[global::System.Configuration.DefaultSettingValueAttribute("http://pms.boonlive-rcu.com:89/blwws.asmx")]
public string BLV_API_boonliverpms_blwws {
get {
return ((string)(this["BLV_API_boonliverpms_blwws"]));
}
}
}
}

View File

@@ -0,0 +1,9 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="BLV_API.Properties" GeneratedClassName="Settings">
<Profiles />
<Settings>
<Setting Name="BLV_API_boonliverpms_blwws" Type="(Web Service URL)" Scope="Application">
<Value Profile="(Default)">http://pms.boonlive-rcu.com:89/blwws.asmx</Value>
</Setting>
</Settings>
</SettingsFile>

2580
BLV_API/Scripts/bootstrap.js vendored Normal file

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More