first commit

This commit is contained in:
Meik
2025-11-11 11:12:05 +01:00
commit 69e2cda8cd
912 changed files with 428004 additions and 0 deletions

View File

@@ -0,0 +1,18 @@
using System.Net;
using System.Net.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
namespace F4SDwebService.ActionFilters
{
public class CheckCollectorFilter : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
if (WebApiApplication.Collector?.IsValid != true)
actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "Collector was not found or is invalid.");
base.OnActionExecuting(actionContext);
}
}
}

View File

@@ -0,0 +1,19 @@
using C4IT.FASD.Licensing;
using System.Net;
using System.Net.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
namespace F4SDwebService.ActionFilters
{
public class CheckLicenceFilter : AuthorizationFilterAttribute
{
public override void OnAuthorization(HttpActionContext actionContext)
{
if (cF4SDLicense.Instance?.IsValid != true)
actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.Forbidden, "No valid licence was found.");
base.OnAuthorization(actionContext);
}
}
}

View File

@@ -0,0 +1,27 @@
using System.Web;
using System.Web.Optimization;
namespace F4SDwebService
{
public class BundleConfig
{
// For more information on bundling, visit https://go.microsoft.com/fwlink/?LinkId=301862
public static void RegisterBundles(BundleCollection bundles)
{
bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
"~/Scripts/jquery-{version}.js"));
// Use the development version of Modernizr to develop with and learn from. Then, when you're
// ready for production, use the build tool at https://modernizr.com to pick only the tests you need.
bundles.Add(new ScriptBundle("~/bundles/modernizr").Include(
"~/Scripts/modernizr-*"));
bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include(
"~/Scripts/bootstrap.js"));
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 F4SDwebService
{
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 F4SDwebService
{
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,35 @@
using F4SDwebService.ActionFilters;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
namespace F4SDwebService
{
public static class WebApiConfig
{
public static cAuthentication authenticationHandler = new cAuthentication();
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
config.MessageHandlers.Add(authenticationHandler);
config.Filters.Add(new CheckLicenceFilter());
config.Filters.Add(new CheckCollectorFilter());
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
var appXmlType = config.Formatters.XmlFormatter.SupportedMediaTypes.FirstOrDefault(t => t.MediaType == "application/xml");
if (appXmlType != null)
config.Formatters.XmlFormatter.SupportedMediaTypes.Remove(appXmlType);
}
}
}

View File

@@ -0,0 +1,39 @@
using System;
using System.Text;
using System.Web;
using System.Web.Http.Description;
namespace F4SDwebService.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 F4SDwebService.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 = "F4SDwebService.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 "Matrix42TicketFinalization" were returning a string.
//config.SetActualResponseType(typeof(string), "Values", "Matrix42TicketFinalization");
}
#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 F4SDwebService.Areas.HelpPage.ModelDescriptions;
using F4SDwebService.Areas.HelpPage.Models;
namespace F4SDwebService.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 F4SDwebService.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 F4SDwebService.Areas.HelpPage.ModelDescriptions;
using F4SDwebService.Areas.HelpPage.Models;
namespace F4SDwebService.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 F4SDwebService.Areas.HelpPage.ModelDescriptions
{
public class CollectionModelDescription : ModelDescription
{
public ModelDescription ElementDescription { get; set; }
}
}

View File

@@ -0,0 +1,14 @@
using System.Collections.ObjectModel;
namespace F4SDwebService.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 F4SDwebService.Areas.HelpPage.ModelDescriptions
{
public class DictionaryModelDescription : KeyValuePairModelDescription
{
}
}

View File

@@ -0,0 +1,15 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace F4SDwebService.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 F4SDwebService.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 F4SDwebService.Areas.HelpPage.ModelDescriptions
{
public interface IModelDocumentationProvider
{
string GetDocumentation(MemberInfo member);
string GetDocumentation(Type type);
}
}

View File

@@ -0,0 +1,9 @@
namespace F4SDwebService.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 F4SDwebService.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 F4SDwebService.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 F4SDwebService.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 F4SDwebService.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 F4SDwebService.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 F4SDwebService.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 F4SDwebService.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 F4SDwebService.Areas.HelpPage.ModelDescriptions;
namespace F4SDwebService.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 F4SDwebService.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 F4SDwebService.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 F4SDwebService.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 F4SDwebService.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 F4SDwebService.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 F4SDwebService.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 F4SDwebService.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 F4SDwebService.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 F4SDwebService.Areas.HelpPage
@using F4SDwebService.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 F4SDwebService.Areas.HelpPage.ModelDescriptions
@model CollectionModelDescription
@if (Model.ElementDescription is ComplexTypeModelDescription)
{
@Html.DisplayFor(m => m.ElementDescription)
}

View File

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

View File

@@ -0,0 +1,4 @@
@using F4SDwebService.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 F4SDwebService.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 F4SDwebService.Areas.HelpPage.Models
@using F4SDwebService.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 F4SDwebService.Areas.HelpPage
@model ImageSample
<img src="@Model.Src" />

View File

@@ -0,0 +1,13 @@
@using F4SDwebService.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 F4SDwebService.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 F4SDwebService.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 F4SDwebService.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 F4SDwebService.Areas.HelpPage.ModelDescriptions
@model SimpleTypeModelDescription
@Model.Documentation

View File

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

View File

@@ -0,0 +1,37 @@
@using System.Web.Http
@using System.Web.Http.Controllers
@using System.Web.Http.Description
@using System.Collections.ObjectModel
@using F4SDwebService.Areas.HelpPage.Models
@model Collection<ApiDescription>
@{
ViewBag.Title = "F4SD 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">
<h1>@ViewBag.Title<br></h1>
</div>
</header>
<div id="body" class="help-page">
<section class="featured">
<div class="content-wrapper">
<h2></h2>
<p>
Provide a general description of the APIs here.
</p>
</div>
</section>
<section class="content-wrapper main-content clear-fix">
<br>
@foreach (var group in apiGroups)
{
@Html.DisplayFor(m => group, "ApiGroup")
}
</section>
</div>

View File

@@ -0,0 +1,19 @@
@using System.Web.Http
@using F4SDwebService.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.3.0.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 F4SDwebService.Areas.HelpPage.ModelDescriptions;
namespace F4SDwebService.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;
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -0,0 +1,239 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Threading;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using Newtonsoft.Json;
using C4IT.Security;
using C4IT.Logging;
using C4IT.XML;
using C4IT.FASD.Base;
using C4IT.DataHistoryProvider;
using static C4IT.Logging.cLogManager;
using System.Web.Http.Controllers;
using System.Reflection;
using Microsoft.Ajax.Utilities;
namespace F4SDwebService
{
public class cAuthentication : DelegatingHandler
{
private const string WwwAuthenticateHeader = "WWW-Authenticate";
private const string Basic = "Basic";
public cDataHistoryCollector Collector = null;
public Dictionary<string, cOneTimePW> OTPWs = null;
protected override async Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
if (Collector == null || OTPWs == null)
return await base.SendAsync(request, cancellationToken);
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
var Path = request.RequestUri.LocalPath.ToLowerInvariant();
var UserInfo = ValidateBearer(request);
if (UserInfo != null)
{
request.Properties.Add("F4SD_UserInfo", UserInfo);
return await base.SendAsync(request, cancellationToken);
}
if (!cLogManager.DefaultLogger.IsDebug
&& !Path.EndsWith("checkconnection")
&& !Path.EndsWith("logon/logon")
)
{
var response = ValidateOTP(request);
if (response != null)
{
var tsc = new TaskCompletionSource<HttpResponseMessage>();
tsc.SetResult(response);
return await tsc.Task;
}
}
var _res = await base.SendAsync(request, cancellationToken);
return _res;
}
catch (System.OperationCanceledException EC)
{
LogEntry($"The operation of the request '{request.RequestUri} was canceled.'", LogLevels.Debug);
LogException(EC, LogLevels.Debug);
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
var responseErr = new HttpResponseMessage(HttpStatusCode.InternalServerError);
var tsc2 = new TaskCompletionSource<HttpResponseMessage>();
tsc2.SetResult(responseErr);
return await tsc2.Task;
}
private cF4sdUserInfo ValidateBearer(HttpRequestMessage request)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
if (Collector == null)
return null;
var authenticationHeaderValue = request.Headers.Authorization;
if (authenticationHeaderValue == null || string.IsNullOrEmpty(authenticationHeaderValue.Scheme) || !authenticationHeaderValue.Scheme.Equals("Bearer") || string.IsNullOrEmpty(authenticationHeaderValue.Parameter))
{
LogEntry($"no valid bearer authentication header", LogLevels.Debug);
return null;
}
var _res = Collector.JwtTokenHandler.ValidateToken(authenticationHeaderValue.Parameter, Collector.JwtTokenValidationParameters, out var _res2);
if (!(_res?.Identity?.IsAuthenticated == true))
{
LogEntry($"bearer token could not validated", LogLevels.Debug);
return null;
}
if (!(_res2 is JwtSecurityToken _sec))
{
LogEntry($"bearer token is not a JwtSecurityToken", LogLevels.Debug);
return null;
}
var _now = DateTime.UtcNow;
if (_sec.ValidFrom > _now || _sec.ValidTo < _now)
{
LogEntry($"bearer token could is not a JwtSecurityToken", LogLevels.Debug);
return null;
}
var strNameId = _sec.Claims.First(c => c.Type == JwtRegisteredClaimNames.NameId)?.Value;
if (!Guid.TryParse(strNameId, out var _nameId))
{
LogEntry($"bearer token has no valid NameId property", LogLevels.Debug);
return null;
}
var _retVal = new cF4sdUserInfo() { Id = _nameId, ValidUntil = _sec.ValidTo, LogonTime = _sec.ValidFrom };
_retVal.Name = _sec.Claims.First(c => c.Type == JwtRegisteredClaimNames.UniqueName).Value;
var strAuthTime = _sec.Claims.First(c => c.Type == JwtRegisteredClaimNames.AuthTime).Value;
if (DateTime.TryParseExact(strAuthTime, "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff'z'", null, System.Globalization.DateTimeStyles.AssumeUniversal, out var _AuthTime))
_retVal.LogonTime = _AuthTime;
var _strLoginMethod = _sec.Claims.First(c => c.Type == "login_method").Value;
_retVal.AccountType = cXmlParser.GetEnumFromString<cF4sdUserInfo.enumAccountType>(_strLoginMethod, cF4sdUserInfo.enumAccountType.unknown);
_retVal.AdAccount = _sec.Claims.First(c => c.Type == "login_account").Value;
_retVal.AdSid = _sec.Claims.First(c => c.Type == "account_sid").Value;
_retVal.Language = _sec.Claims.First(c => c.Type == "language").Value;
var _roles = _sec.Claims.Where(c => c.Type == "roles")?.Select(c => c.Value)?.ToList();
if (_roles?.Count() > 0)
_retVal.Roles = _roles;
if (cLogManager.DefaultLogger.IsDebug)
{
var _str = JsonConvert.SerializeObject(_retVal, Formatting.Indented);
var _lst = new List<string>(2) { "Bearer user info:", _str };
cLogManager.DefaultLogger.LogList(LogLevels.Debug, _lst);
}
return _retVal;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return null;
}
private HttpResponseMessage ValidateOTP(HttpRequestMessage request)
{
bool auth = false;
try
{
var authenticationHeaderValue = request.Headers.Authorization;
if (authenticationHeaderValue == null || string.IsNullOrEmpty(authenticationHeaderValue.Scheme) || !authenticationHeaderValue.Scheme.Equals(Basic) || string.IsNullOrEmpty(authenticationHeaderValue.Parameter))
{
var response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
response.Headers.Add(WwwAuthenticateHeader, Basic);
return response;
}
string authValue = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(authenticationHeaderValue.Parameter));
string[] authParts = authValue.Split(':');
if (authParts.Length == 2)
{
if (OTPWs == null)
cLogManager.DefaultLogger.LogEntry(LogLevels.Debug, "no OTP providers configured.");
cOneTimePW OTP;
if ((OTPWs != null) && OTPWs.TryGetValue(authParts[0], out OTP))
{
UInt32 Id;
if (UInt32.TryParse(authParts[1], System.Globalization.NumberStyles.Integer, null, out Id))
{
auth = OTP.Check(Id);
}
}
}
else
cLogManager.DefaultLogger.LogEntry(LogLevels.Debug, string.Format("Key contains {0} items!", authParts.Length));
}
catch { }
if (!auth)
{
var response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
response.Headers.Add(WwwAuthenticateHeader, Basic);
return response;
}
return null;
}
static public cF4sdUserInfo GetUserInfo(HttpActionContext context)
{
try
{
var _props = context?.Request?.Properties;
if (_props == null)
return null;
if (!_props.TryGetValue("F4SD_UserInfo", out var _objUI))
return null;
if (_objUI is cF4sdUserInfo userInfo)
return userInfo;
}
catch (Exception E)
{
LogException(E);
}
return null;
}
}
}

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8" ?>
<F4SD-CopyTemplate-Configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="F4SD-CopyTemplate-Configuration.xsd">
<CopyTemplates Default="Ticket-Information">
<CopyTemplate Name="Ticket-Information">
<Name Lang="DE">Ticket-Information</Name>
<Description Lang="EN">Transfers the relevant information for ticket creation to the clipboard.</Description>
<Description Lang="DE">Überträgt die relevanten Informationen für eine Ticket Erstellung in den Zwischenspeicher.</Description>
<Icon Name="misc_ticket" IconType="intern"/>
<CopyContent Format="UNICODE">%DeviceName.Label% %DeviceName.Value%
%UserFullName.Label% %UserFullName.Value%
%UserAccount.Label% %UserAccount.Value%
%DeviceModel.Label% %DeviceModel.Value%
%OsInfo.Label% %OsInfo.Value%
%IpAddress.Label% %IpAddress.Value%
%LastBoot.Label% %LastBoot.Value%
%LastSeen.Label% %LastSeen.Value%</CopyContent>
<CopyContent Format="HTML">&lt;table border=&quot;1&quot; cellpadding=&quot;5,1,5,1&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;em&gt;%DeviceName.Label%&lt;/em&gt;&lt;/td&gt;&lt;td style=&quot;color: #0000ff;&quot;&gt;%DeviceName.Value%&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;em&gt;%UserFullName.Label%&lt;/em&gt;&lt;/td&gt;&lt;td&gt;%UserFullName.Value%&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;em&gt;%UserAccount.Label%&lt;/em&gt;&lt;/td&gt;&lt;td&gt;%UserAccount.Value%&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;em&gt;%OsInfo.Label%&lt;/em&gt;&lt;/td&gt;&lt;td&gt;%OsInfo.Value%&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;em&gt;%IpAddress.Label%&lt;/em&gt;&lt;/td&gt;&lt;td&gt;%IpAddress.Value%&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;em&gt;%LastBoot.Label%&lt;/em&gt;&lt;/td&gt;&lt;td&gt;%LastBoot.Value%&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;em&gt;%LastSeen.Label%&lt;/em&gt;&lt;/td&gt;&lt;td&gt;%LastSeen.Value%&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;</CopyContent>
</CopyTemplate>
<CopyTemplate Name="Computer name">
<Name Lang="DE">Computer Name</Name>
<Section>DemoActions</Section>
<Icon Name="misc_computer" IconType="intern"/>
<CopyContent Format="UNICODE">%DeviceName.Value%</CopyContent>
</CopyTemplate>
<CopyTemplate Name="User name">
<Name Lang="DE">Anwendername</Name>
<Icon Name="misc_user" IconType="intern"/>
<CopyContent Format="UNICODE">%UserFullName.Value%</CopyContent>
</CopyTemplate>
<CopyTemplate Name="User account">
<Name Lang="DE">Anwender Account</Name>
<Icon Name="misc_user" IconType="intern"/>
<CopyContent Format="UNICODE">%UserAccount.Value%</CopyContent>
</CopyTemplate>
</CopyTemplates>
</F4SD-CopyTemplate-Configuration>

View File

@@ -0,0 +1,110 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:simpleType name="CopyTemplateFormatTypeEnum">
<xs:restriction base="xs:NCName">
<xs:enumeration value="HTML"/>
<xs:enumeration value="UNICODE"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="LanguageId">
<xs:restriction base="xs:string">
<xs:pattern value="[A-Z]{2}" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="IconTypes">
<xs:restriction base="xs:NCName">
<xs:enumeration value="material" />
<xs:enumeration value="intern" />
<xs:enumeration value="byImage" />
</xs:restriction>
</xs:simpleType>
<xs:element name="F4SD-CopyTemplate-Configuration">
<xs:complexType>
<xs:sequence>
<xs:element ref="CopyTemplates" minOccurs="1" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="CopyTemplates">
<xs:complexType>
<xs:sequence>
<xs:element ref="CopyTemplate" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="Default" type="xs:string" use="optional"/>
</xs:complexType>
<xs:key name ="CopyTemplateId">
<xs:selector xpath ="./CopyTemplate"/>
<xs:field xpath ="@Name"/>
</xs:key>
<xs:keyref name="CopyTemplateKeyRef" refer="CopyTemplateId">
<xs:selector xpath="."/>
<xs:field xpath="@Default"/>
</xs:keyref>
</xs:element>
<xs:element name="CopyTemplate">
<xs:complexType>
<xs:sequence>
<xs:element ref="Name" minOccurs="0" maxOccurs="unbounded"/>
<xs:element ref="Section" minOccurs="0" maxOccurs="unbounded"/>
<xs:element ref="Description" minOccurs="0" maxOccurs="unbounded"/>
<xs:element ref="Icon" minOccurs="0" maxOccurs="1"/>
<xs:element ref="CopyContent" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="Name" type="xs:string" use="optional"/>
<xs:attribute name="Section" type="xs:NCName" use="optional"/>
<xs:attribute name="Description" type="xs:string" use="optional"/>
<xs:attribute name="HiddenInTicketDialog" type="xs:boolean" use="optional" default="false"/>
</xs:complexType>
</xs:element>
<xs:element name="Name">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="Lang" type="LanguageId" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="Section">
<xs:simpleType>
<xs:restriction base="xs:NCName" />
</xs:simpleType>
</xs:element>
<xs:element name="Icon">
<xs:complexType>
<xs:attribute name="Name" type="xs:NCName" use="required" />
<xs:attribute name="IconType" type="IconTypes" use="required" />
</xs:complexType>
</xs:element>
<xs:element name="Description">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="Lang" type="LanguageId" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="CopyContent">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="Format" type="CopyTemplateFormatTypeEnum" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:schema>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<F4SD-Global-Configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="F4SD-Global-Configuration.xsd">
<ShouldSkipSlimView Policy="Default" Value="true" />
<SmallViewAlignment Policy="Default" Value="Right" />
<FavouriteBarAlignment Policy="Default" Value="Right" />
<InformationClassSearchPriority Policy="Hidden">
<InformationClass Type="User" />
<InformationClass Type="Computer" />
<InformationClass Type="VirtualSession" />
<InformationClass Type="Ticket" />
</InformationClassSearchPriority>
</F4SD-Global-Configuration>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8" ?>
<F4SD-Icon-Configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="F4SD-Icon-Configuration.xsd">
<IconDefinitions>
<IconDefinition-Image Name="TestImage" IconType="byImage">
<IconImage SizeX="10" SizeY="10">iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKBAMAAAB/HNKOAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAGUExURf8AbgAAAJpakjMAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAaSURBVBjTY4ADARDBCCYFQCQjRAQLCQEMDAAQ+wCDR98HLQAAAABJRU5ErkJggg==</IconImage>
<IconImage SizeX="20" SizeY="20">iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAANjgAADY4BAtAkWgAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xOdTWsmQAAAFwSURBVDhPY5CzydVStM+ZoGifNZMynDMBZBaDrEX8A0WHnP/UwCCzGEAMBfvsbbJWSVKUYJAZILMgBjpkr2WgEIDMGDgDgWqSFe2zTwAD/i7Qa3eA7AuKdllVksZpXFAlpBmo4JCVJ2+fZSBvl+MJZPsr2mXrAvVVgWioEtIMVLNPE1F0yL4GVDcNlDwU7HOuyNtlB0KlwYAkA0FA1SldGujdqQoOOfMU7fJMGUJDmaFSYECygQqOWfIgVynYZrrJ22U6QoXhgCQDFe0ym7DlDqg0GJBkoIJ91k2QOnQMlQYDVAPx5BQZi0JOsIH22V+AmnYDI+cckH4I0mdsnMYKU4ecU+6DGLgwMLlEggwERsYvIB8U00DDst+D5Z0y9ZDVAvF9wqWNbboZxMtgQyYB1W4AJpuLIANU7HNlEGqhpQ0xABaGQIM+QLwOdi1KGJIEwF4GGWaXvQgSjjnXKDYQZAA6hkqTDqhuIDEJGwIYGACByknB6/EnhgAAAABJRU5ErkJggg==</IconImage>
<!--<IconImage SizeX="30" SizeY="30">iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeBAMAAADJHrORAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAGUExURQD//wAAALEGeLIAAAAJcEhZcwAADsMAAA7DAcdvqGQAAABLSURBVCjPYyAPCAoKoHAZGBiRBMBsZD6cYEATJIEviMYXQFOOymcUROOia0dTj0VAgIADiHYw1GSEeeDAQ7YP6DpUB2O6lyzAwAAAsakB4ouF7nUAAAAASUVORK5CYII=</IconImage>-->
<!--<IconImage SizeX="40" SizeY="40">iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAIAAAADnC86AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAL9SURBVFhH7ZdLaBNRFIb/mTxa+ohtfFRFxQbrq+haoaCgG0UXbqQ7V4IoqKCLghSX4kI3LgSh6kah6kJwKbhxValdKF0UFVubNpQ2zaOvZJ6eM7lJKprOnRmJiH6Em5szM/efc+65594op2z8EVTxXXf+HmHLgpZBdhimJiz+8CxcTGH0Kj5ewvxbYfGHN2Hbxvg9TD/Fwof6Ci9NYHoQtoFwDB2nhdEfHoQtE8kBFKb4oQ3HETso7P7wILz8Faln7G6kDdvOQY0Iuz9khS0DE/dZm56IH0HbIWEnbBMrUyjOcQbIIyVMI2aGMPWE3Y3GsfMiIq3VS4ufMNaP7JCwSCIlrM1j7Aa0WSghdJxBew8URVyyipxuqRfQM8Iiibsw5dTkQ8chG00JdF5BuFFcIrQ5pN/AXIKxKCySuAsXJpF8xJ6FmpG4jtY9wl5Cz0JL8ztZK8IiiYswTeG3ASx9BhTEe7DlLEd7NXoORo47ls7y8rgIU+IkH8PWEWnHrj5EYsJewcjCLPlqOq00awmbBr7cRmGa79p4AusOV3OqAq0iq8Ady+O+vpZwbhgzL2lINGxGVx/CUWFfjZ52gkx4FK55AinmMHQM+ffcbzmATSe5VCn0nipUmuaQUy5szL5GhnYLG103sbufU+HnqPySmsLjDzB6GXaR+0qYR3R65aY8OrtrcSdxDXtv8Z2SwjVD3bofzZ1QyMsGp6URQ+xxaVxyt/SpRFgEXJqaHhtF5N4hM8zpyhG2uJJQS5WZCmeFmVfIj/Br7biA7rsePA50yiSPR3qReg61EdvPo/sOVJoUOdbKalfMZeh57pAerfXfWUBcoMg7i1iJOvGnn9LawYQVx0mb884swHbSW5JAwqEm/hDkrpmvozBlu+qUM4qwpf2Q7a4ECzVRmlTylWqZl6UcVNhY4JZ2a9q+KuVMhqDCLft4DCpt648iXD6IyRBUmCor6akN7DHNt2TZIoL+P9ZySA1ykLf2Vo+eMgQV9k3grPbLf+G68a8JA98BgX8KuPKybbkAAAAASUVORK5CYII=</IconImage>-->
</IconDefinition-Image>
</IconDefinitions>
</F4SD-Icon-Configuration>

View File

@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:simpleType name="LanguageId">
<xs:restriction base="xs:string">
<xs:pattern value="[A-Z]{2}" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="IconTypes">
<xs:restriction base="xs:NCName">
<xs:enumeration value="material" />
<xs:enumeration value="intern" />
<xs:enumeration value="byImage" />
</xs:restriction>
</xs:simpleType>
<xs:complexType name="MultiLanguageEntry">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="Lang" type="LanguageId" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name="F4SD-Icon-Configuration">
<xs:complexType>
<xs:sequence>
<xs:element ref="IconDefinitions" minOccurs="1" maxOccurs="1" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="IconDefinitions">
<xs:complexType>
<xs:sequence>
<xs:element ref="IconDefinition-Image" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="IconDefinition-Image">
<xs:complexType>
<xs:sequence>
<xs:element ref="IconImage" minOccurs="1" maxOccurs="unbounded" />
<xs:element ref="Description" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="Name" type="xs:NCName" use="required" />
<xs:attribute name="IconType" type="IconTypes" use="required" />
<xs:attribute name="Description" type="IconTypes" use="optional" />
</xs:complexType>
</xs:element>
<xs:element name="Description">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="MultiLanguageEntry" />
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="IconImage">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="SizeX" type="xs:integer" />
<xs:attribute name="SizeY" type="xs:integer" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:schema>

View File

@@ -0,0 +1,126 @@
<?xml version="1.0" encoding="utf-8"?>
<F4SD-Infrastructure-Configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="F4SD-Infrastructure-Configuration.xsd">
<Credentials>
<Credential Name="SQL" Domain="c4it" User="tusr_nxt_collector">vmmiabBaKKefRcRRwaKiJCLniIPEzOu+BGwMLrnlNq6jANT4P3Z0802c8XMxEQgxcITj9J3pb9uIGjZUM+nfM719dHbAmS3z6glAre0Wae+uIBTNbDpn3KVjkCJwbQsOk+yeRrGhWwuWAP7DCUYq9OyGd+DY7dYAF2qKFO7zaeo=</Credential>
<Credential Name="SQLTest" Domain="" User="sa">WSof9/qG1DikRY7NLa1Bt5hYKQsm9YvNFXukg95J5OvCR/Z0c8U1bo+QvKLW+/K8L9wgVvVbyzJQiSYeWNktbdK5qMkcphw4mciJkLkzYyeRgx27Vr7KzBOlmK9JQ1Z0c40VebDzGOh6mB+s+STfOLp2Tseq5lcz9qf8oP6XlkM=</Credential>
<!--qMfZiLQTbTdFmgusoJX4-->
<Credential Name="NXT" Domain="" User="tusr_nxt_collector@c4it.intra">R0ICvoG+yjJFGXGgagNQbzAwcBacJr47wRHOIwYhBl/YGDmxpoRWrI1GZ9x1C7ofSqeE1UeZNHX/oqMo/04h+jfUrqk1QHo/6e43Lns1z7UVhWrzOlPSxYwCjv7e4+6wqTWTx6UNGR5jCeD/eHAXHW24dGu7mph9xhcB3VC1kRY=</Credential>
<Credential Name="NXCLOUD" Domain="" User="sd002">ZLAAU+jFXU/+x9FVjx4EAZRnK/D+G/OpZGkn4ek56vhDUeoR5QnSAsNu/cMa1yM3Zxa3CgmSjUmpBy+X2gr1Vo8yAeLVhqI8k9hzev+/LhrinTZIqVZZ4CaA5TEiBuNAy2uB8WEkned6uh3hRyIVNavlfoO9sToZn8f+xn8NKrM=</Credential>
<Credential Name="AGENTAPI" Domain="" User="management-client">gdZccNCwzFrAdA+qGOA9I9ChD8hJQq/4Xuc5iC2i2I+Rtp6KCRrlgqPU0Wn6zwQ8SKitRLUSeNCJcspzkpewfv0Lnb2VIDMhdDeA5zyxVss0dZqDrMgYRhZcT+odtFTX8GlWUTyqBSQpUh8YQYdggvFZkE5ZOTaFU6kqUoKAgcs=</Credential>
<Credential Name="M42API-Demo" Domain="" User="F4SD API Access">a2btKvTS6UnTiD3vTaLX4JjQe3YB8iOpgqwDD3Imy9QzfIZwOBkKuI+jZDtea9VPpFsO6P7pVPmL5y3eZQpVe9oBlw74Ve0hMvX+RrNjAO5DINbBNG8JxZ4gPIMQsUnYVVkHH3pvoiJIJ8AlctQuMEQ2v2slnOvEhTMWiJF2vzQWPgY7vCu6hp92AJvalKIOmK6qT3u7gf45L06R16hpzxD73DbmYwEnMs1ZuF9e1NrLdXRBr+/m4/K8RneZf/hLnW70JJm1IfA/PEVYUEk5HG0fWZFTnsBI3xNXuxXg4OdiR/7Bcrmpj36ATEU6XfWnJBP5qZwhvNzIdMMcDLOnk52b56Szjr5wEOSJIvG93knmZJAFPDIqnRY9BLYtZb6rZ6sCpLMD7R97HKhUy0CFgNNY43CniAtIiARpnGFpdxPISSWeVFsqrckEDeya4hUpZQRUf7T53nTnOBFMuygDgWxfJnMxEl0tg6m5kfAhkguyFDRueA/XkSs0bXQ8xuERBZpKCWA7TJZnMbljK9G22VMYPFCJbB8hHkBjW49wsM8rF0MAS2KvweJdvFjclhqRNSH6sXHKTh4r870YYhYXNnrqobikmP81ZCoq6avKH10/1UPJJAQjBT4MwM488M7TfPv4q9l0ezi7v91fnl2MORRlZljoQ57ao6flIf/KCgQhxl20PtYPz4TcRU/onZ5OKRDXEgaWpkJZkt4ZZX2NgjIvEI8wTEATY3Eu2dBOKeWKD7jwhkPJtnRka8+miNSFanhwJ78WjIx1B/s9jMJ2njCMAzsabjVDMZPwedXigz67zcSl3NnCg4ycCukPnk/Vs2r90XjYKOCuvlU6CsTCeQLLX28Y2AaABY+7vQIEV3XPZVc4kimy6EEShfNZkkLNHQjoZqVXkFp8AKxWCZLzJOFyGFTAX0UqsN9O6soJ/rzAF68ByjYT2y9iggA8GDYUAHZxe0fX/b01+8D+I14c9qPctBaEPhJ2DjYOfJhKRglP1nkIX6U/wd0A19brME7fr50k/ndYpavzGOhVFHrcnxufn6CDJ9/8XeeQ3XdqHwCnYT4G0dUBDEQXcCGWJa0KVkefl4vW25A8Uz5aa4yQoOj7wsnJdLVoijClWEj4a7AWP1AaH9l+dQels1ek7nJ5M8BgjGK5QSSbSrgdNLVRTRZ8PxsSdSjs1tXpSZB6SfSIWW0l48HADpUdmJjr8RlARLvpeHJs+Sqw03TnAPZo+0NOrjrfFnH0UNCVcIaNYwunMhp76s77sUpmozOxL0s95hXNlGPRcJMF5kxTXzV5hbTFr0ZsG/33gmbup9Vo9OJza9EeSbQUZj26TWotabTFrrzU/OgboiHWUmXM9HSwrXatWsCjdOr602+Hve5eDcbYUMAWvXz77QfniJgj54dM4kdNRP3e4iWQRD/EW2crlacOPEyqCGYoHm+BlgtXg2IUUYxuqYJi3/RAn0TZzEKe9oDET2jc7RRRXUzglPVU6LPnw4qPbpu054GVDfddTvPthIPKBwyB21laqmFIDRCqkcmOuVuXBxhF5DLJh7dXl7Azo3X1R7sBhX3gFOynvbDYoGmxpxetR0rKxWP9toh/UPubuYYTtOeAuLGdhIFu9LdeV/LkRHeHlFgtaZjd/CmmHavRMiKs8rKlXCRQAJYIu6DzcDCjkDfOOhEKOoi9PVzCJsLahRmlsvty+bVrbgZwNJoBH9p50dx+5rw9diNKXJrY5zCl5YnacXDHQ7lY4VV8a0f7I3zGOffTYSbADOrQ+V35YQIkzQ8yBNTKHxkKUY+qR4YHkN5P3Wq/xhZkVwAO1UEMyjdZCyibAMnvNsGSZiZSvn1374ygn1xL/gKU7nGGh4xtBU3cCzHkxfWMSDmk3m9Gp7cdFd8/jr0TLaLT1roEO6/Btdwh17XSFU2xUQzYieMIESuZuO/NzEem0V8qtT7Jh3AkfXumzvhBysc2PG0/ydghgL8kO+42zU+bslPhk+hQ7w1UouGNhtMgMi31sjxizjoeS7z2v7qCmC8P9ho3Lsexxoefj/pJ3wgF</Credential>
<!-- M42 API KEY: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1bmlxdWVfbmFtZSI6ImltYWdvdmVydW0uY29tXFx2dm9nZWwiLCJuYW1laWQiOiJpbWFnb3ZlcnVtLmNvbVxcdnZvZ2VsIiwiVXNlckZyYWdtZW50SWQiOiI3ZWRhYTljNy03YjMzLWU1MTEtODBmNi0wMDUwNTYyZjk1MTYiLCJpc3MiOiJodHRwczovL3N0cy5tYXRyaXg0Mi5jb20iLCJhdWQiOiJ1cm46bWF0cml4NDJBcGkiLCJleHAiOjIxNDc0ODM2MTIsIm5iZiI6MTY2NTU4Mzc3Mn0.MQntDtbSafCY42UDkyEHiSE8VLZX6B_EIkSg04wdrAc-->
<Credential Name="M42API-Demo-Dieter" Domain="" User="F4SD API Access">QbduWLGx6U0/XFMzVkVF4UZGxLrCx3c/R+GpiRctqCbf1mLApqNxMrctKpdUjfSwW04UgCl+ERtERvkgr5gluxto+oY6AtmHhCdANU1ZpzAFObEhjxGA1rQGp4PRBcpLPVg3AyBw0mNv8GqrJSdt/+sDcQY7R405ZNMUaBGdkh6CxZNo8OFstpZ9Q4QlRljO9sh62uTMGTqPw+DCaJnFlcAvRMCas1oVJ4bUJ0ODiaBmjf7N9+aO1OnOFYK5XLnlyRvlBSNMPftjbQewA46efMe8kG1t50drtObXJLsQs/FM6BkmDzKlclG3crSPBWL6MH6QVhf/NDL/Spntxpu+o4a/cfR4BpIyZc/GnLnHDwCzCv7l5uLG+T8GXoFLTbjNTKpdSHFD3EZrOXs9BdFXHxCs2zHDtSZBhftzvDrzRUPyD0t9p6Q4FVT4KTv8QGPCFme+sYLy1I20n9QH4736Dvx0IZO6TBPZc7ryIjvChmWQojudhIz/eObraSsRI2DYfU5COLCESDKd4SwwyAHkwJmh1Qc1YMGBNv9mxOn6qbFk/HQ9me2VxVw1p+YwgFH7xcfWEpk3kyIBxGdDfAqzhWBirYjsFWDbSkRyloczdh8VI1A+51ABIBB9Bd1pMyDbXfZWi/UpIlLjRRJzdfwBJ0U/xlFS2BE5N7hmUOqFIMx+8ZSJoJ0NJLWcerVa6OA3P0IxZukyOxuW9GamX58jyNwdZVY5Mydit/8FS5d/v0JGdiK0EVdCj/snyflHeNukeOsy/lAfkjoX+lDX5/BN6cM+JJtWGoLPY6w5WdrNff/Y+8GzK3m5u2fz60Kfjbmh+X4jGA775xTEZoOsGHGU56WwdVixPQAJBQcQPyulf7I23mKQkOXBQiQi7405sBS0cEnuZdxpi6oBknDs5442P4GFHhNTL5zCRL34zUpSMxelETjKyqMuxsTs5+UFycEmLkgWw6Jxz9hc8uoWAaPkqlhMEJc9aae6z2b4EJr3guKkMOA5A1V8Y9x+rOQxTcCsFU6Sxk5PI4phlfU+yyhgcYtAI5bvNkAo02hBCYwZQdTsrBj/E4bqghwJs42QDYL3Y9etWFUgcDniKTsRN4ig9IWQcJL/VrpcAhWneC+Ih0etKX9YAFFdn1sXhLsamr0RSzP/g587XxdnTi8CYN7cijwNmzXCnNjJy5N55P1+dEKPSwoAcm2fh8oM8XPIV7CLpzt61Vb6CuT08jAWKYfq/gAHN/6KAxhZ7PcstYMkz5z4fieEfpto0yaz6GcAE5Y6SGOqz9P4fyCmxVj4yz4wwBi/QEyWCXeguQoIXgkWtaVm+iLuliMNV7BM1PkFNu/ugQqgqAU4yPd7Zr398aWi/Y77ESvtRylmanZB4yU2KmdTFUCYrFSOImyqe2hz4BcpQeQTCp95UNn/zQ3PdAFlkQM3mde0x0WoxNfQiA1jqOU7GOOzYngSvQNHh3VEno0X7wdzi9bVT2JkNvmGoipjRL6PabhzlphkosV+WuJSIk0xOZa2wGCGNPp92rD2f3YmLACTeYoyReb/C6NzVetroTgdVoULTVPf9nlM9P87tJZlLBQBAU5T4zbhjU4fCCdTSJnW/B2GntO5bioC3ngDCG95pgUjC0Wq8Yl7x+WjK5hBCBWYE8pTLF2pwlBE+xB8QZOM48gh/b23rGrhZMwxix62KgbSyIUvvPjrPwRc+2NMOP13UQe6RK28aomg1M6eqRIT04m4SUMVX4/vdUrqSmzX09FF/Eyw4PlRf5eazXswa6XL+cNiOL+hvnj0kpUgYO9tWRYJJ6UfXHQsVxwBsCjXjQUrvvDd5rNaKQRi68P96nMTNWLFK4nxuJVey1mBBJ2zpx+gCglwXyy+Q+egcQWmsnrus7EZ7VHhRUlg3j76MnMJSJR6SaBFRQQKjOWJxCA5sSVL8lCalojS8gReVqW44LzNAclVMBJtaCOnM9JIj9bq5av1DYxxrGrzNrKQMmSLFsCOlXhT42a89S+l7VzFMBH7YMypyczIEswUsTss4APTMa3fCv2CDZUY4W07ojMQINHqwCy5ip5X/9G19Y5/DY8mu+iu0wmE2VEWuwnRqYrtdAEYCXOpstWbVqkqPTL1O37FTBKvF+pMqiKv4l6tDl4vMoBPhhrByqa+nF92JnXecZoXKxlVz1ksiUH+7CR34EAmryG7nJGNATNvh9bc2oPcAIwdApflNFe8tEs=</Credential>
<!-- M42 API KEY: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1bmlxdWVfbmFtZSI6ImltYWdvdmVydW0uY29tXFx3c21zZXJ2aWNlcyIsIm5hbWVpZCI6ImltYWdvdmVydW0uY29tXFx3c21zZXJ2aWNlcyIsIlVzZXJGcmFnbWVudElkIjoiYmZlY2IxOWUtY2MwOS1lNTExLWQzODAtMDA1MDU2MmY5NTE2IiwiaXNzIjoiaHR0cHM6Ly9zdHMubWF0cml4NDIuY29tIiwiYXVkIjoidXJuOm1hdHJpeDQyQXBpIiwiZXhwIjoyMTQ3NDgzNjA3LCJuYmYiOjE2ODMwMjI0MDd9.k4lcNXAHQfkRH28MVOZz6cONe794JoZW3wV9A0V7PAQ -->
<Credential Name="AzureAccess" Domain="" User="a818cddc-4c80-4600-bd6d-2f25b65fb679">ZU68NkYtmNMVx9gQiACXzLKXrRT9PsxEtO5mYutTgPD5yX19EBPAy/lHY/7SD8Mqrhx4OWSsYKSg3Zc2E5PzVVm+9HGf68BnsUZqH0AMbh7F7R9cYumOTQ5g9d8KYyTXdpkHaqx+z/Oey/hE/Dbj0AT3p48/+DfpysgPWv8seh0CkewE9Sj7CPEitSxBdRi64L2W5BX6Mo/kkJKxolwY6qjSIFDES9IS5O0pXxVZ3P6N8jriMTuAobk3XSAg9m4l+JNvo7bt137s9dhNqqDVlpVNtcGLhiNlnOVmfCvps56LWu+yF0reqL6VxlSFmD418P2mvhQegVtR151J2QF6kA==</Credential>
<Credential Name="AzureAccess_Dieter" Domain="" User="c1cf923b-f286-407b-ae4f-bf60c4c5a85a">BS5gl9Ch0SwtWg2DNwVaphKTtcIDH0KtLnDryUEb4MD+/9Wm8ox01MiB/PgnSQ1mj2RVOv+LPq8Ax7liwuou+BlJMyIM2Z0+V8dCif8zYS6Tnsk/fgv0yP0bvxk9GFOroW5amdQQTpMUEg3jIWwXqNRG0MHwKDwNS+PxqGjfcv9061Q2o1ZPDtkhaxpa+lpNzly6Vl4lyTpUI6aUaMaAETX/qrzB1TdxBBeJN5d7TLAUp5/qVX09Qsol8nC018KgtyI+q2ir1mqGLtmgzQaxpg4NBwStpjfSAHUezV80tGK+je5dVnYZrKuirSNY5l+f+PL5YdrGXxX0vAqAwgT2tw==</Credential>
<Credential Name="CitrixAccess" Domain="" User="bd3b468a-8ea2-4e48-9c04-eece3ccda693">N/yOeyE/pc81TA36JWPWws+2tB3pIfteJZp0u/Ko9dKTUaOmJHuvL8qJ+C2cEth0XZC91V6rQQOyoC1bDfrgM7eRvGGn92T01YaVlMI1RPVy/r1OUOGRhCilE7jFoiuEYMxvXLCAOT02j0noNNZn2ko/ssG4scWIf0HHJr71kFE=</Credential>
</Credentials>
<DB-Connections>
<SQL-Connection Name="DataHistoryDB" Credential="SQL" NativeAccount="false" Server="c4-sql03.c4it.intra" Database="C4-FASD-2.0-Dev" Timeout="60"/>
<!--<SQL-Connection Name="F4SDAnalyticsDB" Credential="SQL" NativeAccount="false" Server="c4-sql03.c4it.intra" Database="C4-F4SD-Analytics" Timeout="60"/>-->
<SQL-Connection Name="F4SDAnalyticsDB" Credential="SQLTest" NativeAccount="true" Server="localhost" Database="C4-F4SD-Analytics_Test2" Timeout="60"/>
<!--<SQL-Connection Name="DataHistoryDB" Credential="SQL" NativeAccount="false" Server="localhost" Instance ="MSSQLSERVER17" Database="C4-FASD-2.0-Dev" Timeout="60"/>-->
<!--<SQL-Connection Name="DataHistoryDB" Credential="SQL" NativeAccount="false" Server="localhost" Database="C4-FASD-2.0-Dev" Timeout="60"/>-->
<SQL-Connection Name="ClientAgentDB" Credential="SQL" NativeAccount="false" Server="c4-sql03.c4it.intra" Database="c4it-fasd-prod-v2" Timeout="60"/>
<!--<SQL-Connection Name="ClientAgentDB" Credential="SQL" NativeAccount="false" Server="localhost" Instance ="MSSQLSERVER17" Database="C4IT-F4SD-Agent" Timeout="60"/>-->
</DB-Connections>
<DataHistory-DB DB-Connection="DataHistoryDB" SearchForPhoneNumbers="true" SearchWithLike="true" DaysToCache="30">
<Cleanup-Timeframe StartDay="Mon" StartTime="19:00" StopTime="05:00" Timezone="W. Europe Standard Time"/>
<Cleanup-Timeframe StartDay="Tue" StartTime="19:00" StopTime="05:00" Timezone="W. Europe Standard Time"/>
<Cleanup-Timeframe StartDay="Wed" StartTime="19:00" StopTime="05:00" Timezone="W. Europe Standard Time"/>
<Cleanup-Timeframe StartDay="Thu" StartTime="19:00" StopTime="05:00" Timezone="W. Europe Standard Time"/>
<Cleanup-Timeframe StartDay="Fri" StartTime="19:00" StopDay="Mon" StopTime="05:00" Timezone="W. Europe Standard Time"/>
</DataHistory-DB>
<F4SDAnalytics-DB EnableUserId="false" SessionTimeout = "60" CaseTimeout="2" SessionCheckInterval="20" CaseCheckInterval="1" DB-Connection="F4SDAnalyticsDB"/>
<ClientAgent DB-Connection="ClientAgentDB" Server-Url="https://f4sd01.consulting4it.de/f4sdagent/server/" MaxDeviceAge="30" Organization="Consulting4IT" Api-Credential="AGENTAPI">
<Scan-Timing ScanInterval="01:00" ScanOffset="20:05" Timezone="W. Europe Standard Time"/>
<Local-Account-Assignment Domain="C4IT" RegExFilter="" AccountMask ="*" />
<Local-Account-Assignment Domain="Training" RegExFilter="" AccountMask ="*" />
</ClientAgent>
<Active-Directory ScanPhoneNumbers ="true">
<Scan-Timing ScanInterval="24:00" ScanOffset="00:10" Timezone="W. Europe Standard Time"/>
<AD-Domains>
<AD-Domain Name="C4IT" FQDN="c4it.intra" Credential="SQL">
<AD-Server FQDN="c4-dc04.c4it.intra" UseSSL="true" Port="636"/>
<AD-Server FQDN="c4-dc01.c4it.intra" UseSSL="true"/>
</AD-Domain>
<AD-Domain Name="Training" FQDN="training.local" Credential="SQL">
<AD-Server FQDN="C4-SCHUL-DC01.Training.local" UseSSL="false"/>
</AD-Domain>
</AD-Domains>
<AD-Scans>
<AD-Scan Name="Employee" Type="User">
<AD-Scan-Node AD-Domain="C4IT" Path="OU=Employees,OU=_Users" LDAP-Filter="" Filter-Property="distinguishedName" Wildcard-Filter="" RegEx-Filter="" />
</AD-Scan>
<AD-Scan Name="AdminUser" Type="User">
<AD-Scan-Node AD-Domain="C4IT" Path="OU=C4IT-Admins,OU=_Users" LDAP-Filter="" RegEx-Filter=""/>
</AD-Scan>
<AD-Scan Name="C4itComputer" Type="Computer">
<AD-Scan-Node AD-Domain="C4IT" Path="OU=Consulting4IT,OU=Clients,OU=_Computers" LDAP-Filter="" RegEx-Filter=""/>
</AD-Scan>
<AD-Scan Name="TelesalesComputer" Type="Computer">
<AD-Scan-Node AD-Domain="C4IT" Path="OU=Telesales4U,OU=Clients,OU=_Computers" LDAP-Filter="" RegEx-Filter=""/>
</AD-Scan>
<AD-Scan Name="RemainingUser" Type="User">
<AD-Scan-Node AD-Domain="C4IT" Path="" LDAP-Filter="" RegEx-Filter=""/>
</AD-Scan>
<AD-Scan Name="RemainingComputer" Type="Computer">
<AD-Scan-Node AD-Domain="C4IT" Path="" LDAP-Filter="" RegEx-Filter=""/>
</AD-Scan>
<AD-Scan Name="TrainingUser" Type="User">
<AD-Scan-Node AD-Domain="Training" Path="" LDAP-Filter="" Wildcard-Filter="" RegEx-Filter="" />
</AD-Scan>
<AD-Scan Name="TrainingComputer" Type="Computer">
<AD-Scan-Node AD-Domain="Training" Path="" LDAP-Filter="" Wildcard-Filter="" RegEx-Filter="" />
</AD-Scan>
</AD-Scans>
</Active-Directory>
<Azure-AD>
<Azure-Tenant Domain="c4it365.onmicrosoft.com" TenantID="8f773186-362b-4432-a3e9-d3ad4685f3f1" Credential="AzureAccess" ScanIntuneDevices = "true" />
<!--<Azure-Tenant Domain="sd0024.onmicrosoft.com" TenantID="07362148-410e-4636-a9cb-795fba1a5452" Credential="AzureAccess_Dieter"/>-->
</Azure-AD>
<Matrix42-WPM Server="srvwsm001.imagoverum.com" Credential="M42API-Demo" ClosedTicketHistory="9999" DisplayName="M42 Demo server (imagoverum)" ApiTokenLifetime ="30 days" ActivityQueueFilter="ticketsAndListedQueues">
<Matrix42-Ticket DisableAutomaticTimeTracking="1"
ShowDocumentCaseDialog="ifRequired"/>
<DisplayName Lang="DE">M42 Demo Server (Imagoverum)</DisplayName>
<Queues>
<Queue QueueName="HR" QueueID="2a7e8099-3d57-f011-1988-00155d320605" />
<Queue QueueName="FM" QueueID="2a7a8099-3d47-f011-1988-00155d320505" />
</Queues>
</Matrix42-WPM>
<!--<Matrix42-WPM Server="m42server.imagoverum.com" Credential="M42API-Demo-Dieter" ClosedTicketHistory="9999"/>-->
<Nexthink>
<Scan-Timing ScanInterval="24:00" ScanOffset="00:10" Timezone="W. Europe Standard Time"/>
<!--
<Nxt-Portal Name="NxtLocal" Address="c4-nexthink.c4it.intra" Credential="NXT" IsCloud="false">
<Nxt-Engine Name="NEXThink" Address="10.33.1.65" Port="1671"/>
</Nxt-Portal>
-->
<Nxt-Portal Name="NxtCloud" Address="c4it.demo.nexthink.cloud" Credential="NXCLOUD" IsCloud="true">
<Nxt-Engine Name="engine-1" Address="c4it-engine-1.demo.nexthink.cloud" Port="443"/>
</Nxt-Portal>
</Nexthink>
<Citrix>
<Scan-Timing ScanInterval="24:00" ScanOffset="00:10" Timezone="W. Europe Standard Time"/>
<Citrix-Tenant Domain="api.cloud.com" TenantID="7wxfk9afgnd7" InstanceID="07ac970e-8bde-454e-b14d-9c7f58cf8a8d" Credential="CitrixAccess"/>
</Citrix>
<Authorization>
<Membership-Groups>
<Membership-Groups-AD Domain="C4IT">
<Membership-Group-AD Name="C4IT-F4SD-Users" Account="C4IT-F4SD-Users"/>
<Membership-Group-AD Name="C4IT-F4SD-Admins" Account="C4IT-F4SD-Admins"/>
</Membership-Groups-AD>
<Membership-Groups-Matrix42>
<Membership-Group-Matrix42 Name="M42_Incident_Management" RoleName="Incident Management" RoleID="2E9F1A61-17C4-42F3-9514-66B5C61E7E17"/>
</Membership-Groups-Matrix42>
</Membership-Groups>
<Roles>
<Role Name="Cockpit.User" Group="C4IT-F4SD-Users"/>
<Role Name="Cockpit.Admin">
<GroupRef Name="C4IT-F4SD-Admins"/>
</Role>
<Role Name="Cockpit.TicketAgent" Group="M42_Incident_Management"/>
</Roles>
</Authorization>
</F4SD-Infrastructure-Configuration>

View File

@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="utf-8" ?>
<F4SD-MenuSection-Configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="F4SD-MenuSection-Configuration.xsd">
<Sections>
<Section TechName="Ticket" Name="Ticket" Description="Scripts dealing with tickets.">
<Name Lang="DE">Ticket</Name>
<Description Lang="DE">Skripte, die sich mit Tickets beschäftigen.</Description>
<Icon Name="ic_mail" IconType="material"/>
</Section>
<Section TechName="Favourites" Name="Favourites">
<Name Lang="DE">Favoriten</Name>
<Icon Name="ic_star" IconType="material"/>
</Section>
<Section TechName="Communication" Name="Communication" Description="Quick Actions dealing with communication.">
<Name Lang="DE">Kommunikation</Name>
<Description Lang="DE">Quick Actions, die mit Kommunikation zu tun haben</Description>
<Icon IconType="material" Name="ic_perm_phone_msg"/>
</Section>
<!-- <Section TechName="ActiveDirectory" Name="Active Directory" Description="Scripts dealing with the active directory.">
<Name Lang="DE">Active Directory</Name>
<Description Lang="DE">Skripte, die sich mit dem Active Directory beschäftigen.</Description>
<Icon Name="misc_user" IconType="intern"/>
</Section> -->
<Section TechName="FastBoot" Name="Fast boot options" Description="Scripts dealing with the windows fast boot option.">
<Name Lang="DE">Schnellstart Optionen</Name>
<Description Lang="DE">Skripte, die die Windows Schnellstart Option betreffen.</Description>
<Icon Name="ic_directions_run" IconType="material"/>
</Section>
<Section TechName="ClearCache" Name="Clear Cache" Description="Quick Actions for clearing cache.">
<Name Lang="DE">Cache leeren</Name>
<Description Lang="DE">Quick Actions um Caches zu leeren.</Description>
<Icon IconType="material" Name="ic_delete_sweep"/>
</Section>
<Section TechName="GetInfo" Name="Obtain information" Description="Obtain further information about the computer.">
<Name Lang="DE">Informationen einholen</Name>
<Description Lang="DE">Weitere Informationen über den Computer einholen.</Description>
<Icon IconType="material" Name="ic_add_to_photos"/>
</Section>
<Section TechName="Intune" Name="Intune">
<Name Lang="DE">Intune</Name>
<Icon IconType="material" Name="ic_assessment"/>
</Section>
<Section TechName="Citrix" Name="Citrix">
<Name Lang="DE">Citrix</Name>
<Icon IconType="material" Name="ic_assessment"/>
</Section>
<Section TechName="C4ITIntern" Name="C4IT internal" Description="Scripts for C4IT internal purposes.">
<Name Lang="DE">C4IT Intern</Name>
<Description Lang="DE">Skripte für den internen C4IT Gebrauch.</Description>
<Icon IconType="intern" Name="misc_tool" />
</Section>
<Section TechName="TestSection" Name="Test" Description="Scripts that need testing for release.">
<Name Lang="DE">Test</Name>
<Description Lang="DE">Skripte, die für das nächste Release getestet werden.</Description>
<Icon IconType="intern" Name="misc_tool"/>
</Section>
<Section TechName="Sandbox" Name="Quick Actions Sandbox" Description="Experimental scripts.">
<Name Lang="DE">Quick Actions Sandbox</Name>
<Description Lang="DE">Experimentelle Skripte.</Description>
<Icon IconType="intern" Name="misc_tool"/>
</Section>
</Sections>
</F4SD-MenuSection-Configuration>

View File

@@ -0,0 +1,80 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:simpleType name="LanguageId">
<xs:restriction base="xs:string">
<xs:pattern value="[A-Z]{2}" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="IconTypes">
<xs:restriction base="xs:NCName">
<xs:enumeration value="material" />
<xs:enumeration value="intern" />
<xs:enumeration value="byImage" />
</xs:restriction>
</xs:simpleType>
<xs:element name="F4SD-MenuSection-Configuration">
<xs:complexType>
<xs:sequence>
<xs:element ref="Sections" minOccurs="1" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Sections">
<xs:complexType>
<xs:sequence>
<xs:element ref="Section" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Section">
<xs:complexType>
<xs:sequence>
<xs:element ref="Name" minOccurs="0" maxOccurs="unbounded" />
<xs:element ref="Description" minOccurs="0" maxOccurs="unbounded" />
<xs:element ref="Icon" minOccurs="0" maxOccurs="1" />
</xs:sequence>
<xs:attribute name="TechName" type="xs:NCName" use="required" />
<xs:attribute name="Name" type="xs:string" use="optional" />
<xs:attribute name="Title" type="xs:string" use="optional" />
<xs:attribute name="Description" type="xs:string" use="optional" />
</xs:complexType>
</xs:element>
<xs:complexType name="MultiLanguageEntry">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="Lang" type="LanguageId" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name="Name">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="MultiLanguageEntry" />
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="Description">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="MultiLanguageEntry" />
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="Icon">
<xs:complexType>
<xs:attribute name="Name" type="xs:NCName" use="required" />
<xs:attribute name="IconType" type="IconTypes" use="required" />
</xs:complexType>
</xs:element>
</xs:schema>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,650 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:simpleType name="guid">
<xs:restriction base="xs:string">
<xs:pattern value="[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="LanguageId">
<xs:restriction base="xs:string">
<xs:pattern value="[A-Z]{2}" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="IconTypes">
<xs:restriction base="xs:NCName">
<xs:enumeration value="material" />
<xs:enumeration value="intern" />
<xs:enumeration value="byImage" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="InformationClass">
<xs:restriction base="xs:string">
<xs:enumeration value="Main" />
<xs:enumeration value="User" />
<xs:enumeration value="Computer" />
<xs:enumeration value="Ticket" />
<xs:enumeration value="VirtuelSession" />
<xs:enumeration value="MobileDevice" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="DisplayTypes">
<xs:restriction base="xs:NCName">
<xs:enumeration value="STRING" />
<xs:enumeration value="INTEGER" />
<xs:enumeration value="PERCENT" />
<xs:enumeration value="PERCENT100" />
<xs:enumeration value="TIME" />
<xs:enumeration value="DATE" />
<xs:enumeration value="DATETIME" />
<xs:enumeration value="DURATION_DAY" />
<xs:enumeration value="DURATION_HOUR" />
<xs:enumeration value="DURATION_MILLI" />
<xs:enumeration value="DURATION_DAY_SINCE_NOW" />
<xs:enumeration value="BITS_PERSECOND" />
<xs:enumeration value="BYTES" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="Browsers">
<xs:restriction base="xs:string">
<xs:enumeration value="Default" />
<xs:enumeration value="Google Chrome" />
<xs:enumeration value="Internet Explorer" />
<xs:enumeration value="Microsoft Edge" />
<xs:enumeration value="Mozilla Firefox" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="ResultTypes">
<xs:restriction base="xs:string">
<xs:enumeration value="Undefined" />
<xs:enumeration value="Information" />
<xs:enumeration value="Repair" />
<xs:enumeration value="ExternalApplication" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="ExecutionTypes">
<xs:restriction base="xs:string">
<xs:enumeration value="Undefined" />
<xs:enumeration value="LocalScript" />
<xs:enumeration value="RemoteScript" />
<xs:enumeration value="ExternalApplication" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="StateLevels">
<xs:restriction base="xs:NCName">
<xs:enumeration value="None" />
<xs:enumeration value="Ok" />
<xs:enumeration value="Warning" />
<xs:enumeration value="Error" />
<xs:enumeration value="Info" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="QuickActionSuccess">
<xs:restriction base="xs:NCName">
<xs:enumeration value="finished" />
<xs:enumeration value="successfull" />
</xs:restriction>
</xs:simpleType>
<xs:element name="F4SD-QuickAction-Configuration">
<xs:complexType>
<xs:sequence>
<xs:element ref="Translations" minOccurs="0" maxOccurs="1" />
<xs:element ref="QuickActions" minOccurs="1" maxOccurs="1" />
<xs:element ref="QuickTips" minOccurs="0" maxOccurs="1" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Translations">
<xs:complexType>
<xs:choice maxOccurs="unbounded">
<xs:element ref="Translator" minOccurs="0" maxOccurs="unbounded" />
</xs:choice>
</xs:complexType>
</xs:element>
<xs:element name="Translator">
<xs:complexType>
<xs:sequence>
<xs:element ref="DefaultTranslation" minOccurs="0" maxOccurs="1" />
<xs:element ref="Translation" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="Name" type="xs:NCName" use="required" />
</xs:complexType>
</xs:element>
<xs:element name="DefaultTranslation">
<xs:complexType>
<xs:sequence>
<xs:element ref="Name" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="Name" type="xs:string" use="required" />
<xs:attribute name="StateLevel" type="StateLevels" use="optional" default="None" />
</xs:complexType>
</xs:element>
<xs:element name="Translation">
<xs:complexType>
<xs:sequence>
<xs:element ref="Name" minOccurs="0" maxOccurs="unbounded" />
<xs:element name="Value" minOccurs="0" maxOccurs="unbounded">
<xs:simpleType>
<xs:restriction base="xs:string" />
</xs:simpleType>
</xs:element>
</xs:sequence>
<xs:attribute name="Name" type="xs:string" use="required" />
<xs:attribute name="StateLevel" type="StateLevels" use="optional" default="None" />
</xs:complexType>
</xs:element>
<xs:element name="QuickActions">
<xs:complexType>
<xs:sequence>
<xs:element ref="QuickAction" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="QuickAction" abstract="true" />
<xs:complexType name="QuickAction" abstract="true">
<xs:sequence>
<xs:element ref="Name" minOccurs="0" maxOccurs="unbounded"/>
<xs:element ref="Section" minOccurs="0" maxOccurs="unbounded"/>
<xs:element ref="Description" minOccurs="0" maxOccurs="unbounded"/>
<xs:element ref="AlternativeDescription" minOccurs="0" maxOccurs="unbounded"/>
<xs:element ref="Icon" minOccurs="0" maxOccurs="1"/>
<xs:element ref="CheckNamedParameterValues" minOccurs="0" maxOccurs="1" />
<xs:element ref="AdjustableParameters" minOccurs="0" maxOccurs="1"/>
<xs:element ref="ColumnOutputFormattings" minOccurs="0" maxOccurs="1" />
</xs:sequence>
<xs:attribute name="Id" type="guid" use="optional" />
<xs:attribute name="Name" type="xs:string" use="required"/>
<xs:attribute name="InformationClass" use="required">
<xs:simpleType>
<xs:list itemType="InformationClass" />
</xs:simpleType>
</xs:attribute>
<xs:attribute name="Description" type="xs:string" use="optional" />
<xs:attribute name="Section" type="xs:NCName" use="optional" />
<xs:attribute name="Params" type="xs:string" use="optional" />
<xs:attribute name="CheckNamedParameter" type="xs:NCName" use="optional" />
<xs:attribute name="CheckFilePath" type="xs:string" use="optional" />
<xs:attribute name="CheckRegistryEntry" type="xs:string" use="optional" />
<xs:attribute name="Hidden" type="xs:boolean" use="optional" />
<xs:attribute name="RunImmediate" type="xs:boolean" use="optional" />
<xs:attribute name="ExecutionType" type="ExecutionTypes" use="optional" default="Undefined" />
<xs:attribute name="ResultType" type="ResultTypes" use="optional" default="Undefined" />
</xs:complexType>
<xs:complexType name="QuickAction-Local" abstract="true">
<xs:complexContent>
<xs:extension base="QuickAction">
<xs:attribute name="RequireAdministrator" use="optional" />
<xs:attribute name="StartWithAlternateCredentials" type="xs:boolean" use="optional" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="QuickAction-Local-Script" substitutionGroup="QuickAction">
<xs:complexType>
<xs:complexContent>
<xs:extension base="QuickAction-Local">
<xs:sequence>
<xs:element ref="Script" minOccurs="1" maxOccurs="1"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:element>
<xs:element name="QuickAction-Local-Cmd" substitutionGroup="QuickAction">
<xs:complexType>
<xs:complexContent>
<xs:extension base="QuickAction-Local">
<xs:attribute name="Cmd" type="xs:string" use="required" />
<xs:attribute name="DontUseShell" type="xs:boolean" use="required" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:element>
<xs:element name="QuickAction-Local-WebRequest" substitutionGroup="QuickAction">
<xs:complexType>
<xs:complexContent>
<xs:extension base="QuickAction-Local">
<xs:sequence>
<xs:element ref="QueryString" minOccurs="1" maxOccurs="1"/>
<xs:element ref="QueryParameter" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="Browser" type="Browsers" use="optional" default="Default" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:element>
<xs:element name="QuickAction-Server" substitutionGroup="QuickAction">
<xs:complexType>
<xs:complexContent>
<xs:extension base="QuickAction-Remote">
<xs:attribute name="Category" use="optional" />
<xs:attribute name="Action" use="optional" />
<xs:attribute name="ParamaterType" use="optional" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:element>
<xs:element name="QuickActionMeasure">
<xs:complexType>
<xs:sequence>
<xs:element ref="Name" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="Name" type="xs:string" use="required" />
<xs:attribute name="MeasureId" type="xs:int" use="required" />
<xs:attribute name="Display" type="DisplayTypes" use="optional" default="STRING" />
</xs:complexType>
</xs:element>
<xs:element name="QuickActionMeasures">
<xs:complexType>
<xs:sequence>
<xs:element ref="QuickActionMeasure" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="QuickActionMeasureResult">
<xs:complexType>
<xs:attribute name="Id" type="xs:positiveInteger" use="required" />
<xs:attribute name="Value" type="xs:string" use="required" />
<xs:attribute name="PostValue" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="QuickActionMeasureResults">
<xs:complexType>
<xs:sequence>
<xs:element ref="QuickActionMeasureResult" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="QuickAction-Demo" substitutionGroup="QuickAction">
<xs:complexType>
<xs:complexContent>
<xs:extension base="QuickAction">
<xs:sequence>
<xs:element ref="DemoResult" minOccurs="0" maxOccurs="1"/>
<xs:element ref="QuickActionMeasures" minOccurs="0" maxOccurs="1" />
<xs:element ref="QuickActionMeasureResults" minOccurs="0" maxOccurs="1" />
</xs:sequence>
<xs:attribute name="SimulatedClientConnect" type="xs:nonNegativeInteger" use="optional" />
<xs:attribute name="SimulatedRuntime" type="xs:nonNegativeInteger" use="optional" />
<xs:attribute name="Type" type="ExecutionTypes" use="optional" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:element>
<xs:element name="DemoResult">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="Result" type="QuickActionSuccess" use="optional" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="QueryString">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="ParameterName" type="xs:NCName" use="optional" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="QueryParameter">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="Name" type="xs:string" use="required"/>
<xs:attribute name="ParameterName" type="xs:NCName" use="optional" />
<xs:attribute name="ValueRequired" type="xs:boolean" use="optional" default="false" />
<xs:attribute name="UseHtmlValue" type="xs:boolean" use="optional" default="false" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:complexType name="QuickAction-Remote" abstract="true">
<xs:complexContent>
<xs:extension base="QuickAction">
<xs:sequence>
<xs:element ref="QuickActionMeasures" minOccurs="0" maxOccurs="1" />
</xs:sequence>
<xs:attribute name="ScriptId" use="optional" />
<xs:attribute name="ScriptName" use="optional" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="QuickAction-Remote-User" substitutionGroup="QuickAction">
<xs:complexType>
<xs:complexContent>
<xs:extension base="QuickAction-Remote">
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:element>
<xs:element name="QuickAction-Remote-Computer" substitutionGroup="QuickAction">
<xs:complexType>
<xs:complexContent>
<xs:extension base="QuickAction-Remote">
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:element>
<xs:element name="QuickAction-Chained" substitutionGroup="QuickAction">
<xs:complexType>
<xs:complexContent>
<xs:extension base="QuickAction">
<xs:sequence>
<xs:element ref="QuickAction-Reference" minOccurs="1" maxOccurs="unbounded" />
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:element>
<xs:element name="QuickAction-Reference">
<xs:complexType>
<xs:attribute name="Name" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
<xs:complexType name="MultiLanguageEntry">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="Lang" type="LanguageId" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name="Name">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="MultiLanguageEntry" />
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="Section">
<xs:simpleType>
<xs:restriction base="xs:NCName" />
</xs:simpleType>
</xs:element>
<xs:element name="Description">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="MultiLanguageEntry" />
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="AlternativeDescription">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="MultiLanguageEntry" />
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="Script">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="IsBase64" type="xs:boolean" use="optional" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="Icon">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="IconType" type="IconTypes" use="required" />
<xs:attribute name="Name" type="xs:string" use="required" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="CheckNamedParameterValues">
<xs:complexType>
<xs:sequence>
<xs:element ref="CheckNamedParameterValue" minOccurs="1" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="CheckNamedParameterValue">
<xs:simpleType>
<xs:restriction base="xs:string" />
</xs:simpleType>
</xs:element>
<xs:element name="AdjustableParameters">
<xs:complexType>
<xs:sequence>
<xs:element ref="AdjustableParameter" minOccurs="1" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="AdjustableParameter" abstract="true" />
<xs:complexType name="AdjustableParameter" abstract="true">
<xs:sequence>
<xs:element ref="Name" minOccurs="0" maxOccurs="unbounded"/>
<xs:element ref="Description" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="Name" type="xs:string" use="required"/>
<xs:attribute name="ParameterName" type="xs:NCName" use="required" />
<xs:attribute name="IsOptional" type="xs:boolean" use="optional" default="false" />
</xs:complexType>
<xs:element name="AdjustableParameter-Boolean" substitutionGroup="AdjustableParameter">
<xs:complexType>
<xs:complexContent>
<xs:extension base="AdjustableParameter">
<xs:attribute name="Default" type="xs:boolean" use="optional" default="false" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:element>
<xs:element name="AdjustableParameter-Numerical" substitutionGroup="AdjustableParameter">
<xs:complexType>
<xs:complexContent>
<xs:extension base="AdjustableParameter">
<xs:attribute name="Default" type="xs:double" use="optional" default="0" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:element>
<xs:element name="AdjustableParameter-DropDown" substitutionGroup="AdjustableParameter">
<xs:complexType>
<xs:complexContent>
<xs:extension base="AdjustableParameter">
<xs:sequence>
<xs:element ref="AdjustableParameter-DropDownValue" minOccurs="1" maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="Default" type="xs:string" use="optional" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:element>
<xs:element name="AdjustableParameter-DropDownValue">
<xs:complexType>
<xs:sequence>
<xs:element ref="AdjustableParameter-DropDownDisplayValue" minOccurs="1" maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="Value" use="required" />
</xs:complexType>
</xs:element>
<xs:element name="AdjustableParameter-DropDownDisplayValue">
<xs:complexType>
<xs:complexContent>
<xs:extension base="MultiLanguageEntry" />
</xs:complexContent>
</xs:complexType>
</xs:element>
<xs:element name="ColumnOutputFormattings">
<xs:complexType>
<xs:sequence>
<xs:element ref="ColumnOutputFormatting" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="ShowAllOutputContent" type="xs:boolean" use="optional" default="false" />
</xs:complexType>
</xs:element>
<xs:element name="ColumnOutputFormatting">
<xs:complexType>
<xs:sequence>
<xs:element ref="Name" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="ValueName" type="xs:NCName" use="required" />
<xs:attribute name="Name" type="xs:string" use="optional" />
<xs:attribute name="Translation" type="xs:NCName" use="optional" />
<xs:attribute name="Display" type="DisplayTypes" use="optional" />
<xs:attribute name="Hidden" type="xs:boolean" use="optional" default="false" />
<xs:attribute name="IsSecret" type="xs:boolean" use="optional" default="false" />
</xs:complexType>
</xs:element>
<xs:element name="QuickTips">
<xs:complexType>
<xs:sequence>
<xs:element ref="QuickTip" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="QuickTip">
<xs:complexType>
<xs:sequence>
<xs:element ref="Name" minOccurs="0" maxOccurs="unbounded" />
<xs:element ref="Section" minOccurs="0" maxOccurs="unbounded" />
<xs:element ref="Description" minOccurs="0" maxOccurs="unbounded" />
<xs:element ref="AlternativeDescription" minOccurs="0" maxOccurs="unbounded" />
<xs:element ref="Icon" minOccurs="0" maxOccurs="1" />
<xs:element ref="QuickTipElements" minOccurs="1" maxOccurs="1" />
</xs:sequence>
<xs:attribute name="Id" type="guid" use="optional" />
<xs:attribute name="Name" type="xs:string" use="required" />
<xs:attribute name="Description" type="xs:string" use="optional" />
<xs:attribute name="Section" type="xs:NCName" use="optional" />
<xs:attribute name="Hidden" type="xs:boolean" use="optional" />
<xs:attribute name="FixedSequence" type="xs:boolean" use="optional" />
<xs:attribute name="InformationClass" use="required">
<xs:simpleType>
<xs:list itemType="InformationClass" />
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="QuickTipElements">
<xs:complexType>
<xs:sequence>
<xs:element ref="QuickTipElement" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="QuickTipElement" abstract="true" />
<xs:complexType name="QuickTipElement" abstract="true">
<xs:sequence>
<xs:element ref="Name" minOccurs="0" maxOccurs="unbounded" />
<xs:element ref="TextBlock" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="Name" type="xs:string" use="required" />
<xs:attribute name="IsRequired" type="xs:boolean" use="optional" />
</xs:complexType>
<xs:element name="TextBlock">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="MultiLanguageEntry" />
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="TextElement" substitutionGroup="QuickTipElement">
<xs:complexType>
<xs:complexContent>
<xs:extension base="QuickTipElement" />
</xs:complexContent>
</xs:complexType>
</xs:element>
<xs:element name="ManualStep" substitutionGroup="QuickTipElement">
<xs:complexType>
<xs:complexContent>
<xs:extension base="QuickTipElement">
<xs:sequence>
<xs:element ref="Icon" minOccurs="0" maxOccurs="1" />
<xs:element ref="Summary" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:element>
<xs:element name="Summary">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="MultiLanguageEntry" />
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="AutomatedStep" substitutionGroup="QuickTipElement">
<xs:complexType>
<xs:complexContent>
<xs:extension base="QuickTipElement">
<xs:attribute name="QuickAction" type="xs:string" use="required" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:element>
</xs:schema>

View File

@@ -0,0 +1,58 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:simpleType name="LanguageId">
<xs:restriction base="xs:string">
<xs:pattern value="[A-Z]{2}|[.]" />
</xs:restriction>
</xs:simpleType>
<xs:element name="UILanguage">
<xs:complexType>
<xs:sequence>
<xs:element ref="UIImage" minOccurs="0" maxOccurs="unbounded"/>
<xs:element ref="UISubstitution" minOccurs="0" maxOccurs="unbounded"/>
<xs:element ref="UIItem" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="UIImage">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="Lang" type="LanguageId" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="UISubstitution">
<xs:complexType>
<xs:sequence>
<xs:element ref="Language" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="Lang" type="LanguageId" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="UIItem">
<xs:complexType>
<xs:sequence>
<xs:element ref="Language" minOccurs="1" maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="Name" type="xs:NCName" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="Language">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="Lang" type="LanguageId" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:schema>

View File

@@ -0,0 +1,26 @@
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;
}
.navbar-toggle .icon-bar {
display: block;
width: 22px;
height: 0.15rem;
background-color: #4f4f4f;
border-radius: 1px;
margin: 4px;
}

3872
F4SDwebService/Content/bootstrap-grid.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

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,325 @@
/*!
* Bootstrap Reboot v4.6.2 (https://getbootstrap.com/)
* Copyright 2011-2022 The Bootstrap Authors
* Copyright 2011-2022 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/
*,
*::before,
*::after {
box-sizing: border-box;
}
html {
font-family: sans-serif;
line-height: 1.15;
-webkit-text-size-adjust: 100%;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
article, aside, figcaption, figure, footer, header, hgroup, main, nav, section {
display: block;
}
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
font-size: 1rem;
font-weight: 400;
line-height: 1.5;
color: #212529;
text-align: left;
background-color: #fff;
}
[tabindex="-1"]:focus:not(:focus-visible) {
outline: 0 !important;
}
hr {
box-sizing: content-box;
height: 0;
overflow: visible;
}
h1, h2, h3, h4, h5, h6 {
margin-top: 0;
margin-bottom: 0.5rem;
}
p {
margin-top: 0;
margin-bottom: 1rem;
}
abbr[title],
abbr[data-original-title] {
text-decoration: underline;
-webkit-text-decoration: underline dotted;
text-decoration: underline dotted;
cursor: help;
border-bottom: 0;
-webkit-text-decoration-skip-ink: none;
text-decoration-skip-ink: none;
}
address {
margin-bottom: 1rem;
font-style: normal;
line-height: inherit;
}
ol,
ul,
dl {
margin-top: 0;
margin-bottom: 1rem;
}
ol ol,
ul ul,
ol ul,
ul ol {
margin-bottom: 0;
}
dt {
font-weight: 700;
}
dd {
margin-bottom: .5rem;
margin-left: 0;
}
blockquote {
margin: 0 0 1rem;
}
b,
strong {
font-weight: bolder;
}
small {
font-size: 80%;
}
sub,
sup {
position: relative;
font-size: 75%;
line-height: 0;
vertical-align: baseline;
}
sub {
bottom: -.25em;
}
sup {
top: -.5em;
}
a {
color: #007bff;
text-decoration: none;
background-color: transparent;
}
a:hover {
color: #0056b3;
text-decoration: underline;
}
a:not([href]):not([class]) {
color: inherit;
text-decoration: none;
}
a:not([href]):not([class]):hover {
color: inherit;
text-decoration: none;
}
pre,
code,
kbd,
samp {
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
font-size: 1em;
}
pre {
margin-top: 0;
margin-bottom: 1rem;
overflow: auto;
-ms-overflow-style: scrollbar;
}
figure {
margin: 0 0 1rem;
}
img {
vertical-align: middle;
border-style: none;
}
svg {
overflow: hidden;
vertical-align: middle;
}
table {
border-collapse: collapse;
}
caption {
padding-top: 0.75rem;
padding-bottom: 0.75rem;
color: #6c757d;
text-align: left;
caption-side: bottom;
}
th {
text-align: inherit;
text-align: -webkit-match-parent;
}
label {
display: inline-block;
margin-bottom: 0.5rem;
}
button {
border-radius: 0;
}
button:focus:not(:focus-visible) {
outline: 0;
}
input,
button,
select,
optgroup,
textarea {
margin: 0;
font-family: inherit;
font-size: inherit;
line-height: inherit;
}
button,
input {
overflow: visible;
}
button,
select {
text-transform: none;
}
[role="button"] {
cursor: pointer;
}
select {
word-wrap: normal;
}
button,
[type="button"],
[type="reset"],
[type="submit"] {
-webkit-appearance: button;
}
button:not(:disabled),
[type="button"]:not(:disabled),
[type="reset"]:not(:disabled),
[type="submit"]:not(:disabled) {
cursor: pointer;
}
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
padding: 0;
border-style: none;
}
input[type="radio"],
input[type="checkbox"] {
box-sizing: border-box;
padding: 0;
}
textarea {
overflow: auto;
resize: vertical;
}
fieldset {
min-width: 0;
padding: 0;
margin: 0;
border: 0;
}
legend {
display: block;
width: 100%;
max-width: 100%;
padding: 0;
margin-bottom: .5rem;
font-size: 1.5rem;
line-height: inherit;
color: inherit;
white-space: normal;
}
progress {
vertical-align: baseline;
}
[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
height: auto;
}
[type="search"] {
outline-offset: -2px;
-webkit-appearance: none;
}
[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
::-webkit-file-upload-button {
font: inherit;
-webkit-appearance: button;
}
output {
display: inline-block;
}
summary {
display: list-item;
cursor: pointer;
}
template {
display: none;
}
[hidden] {
display: none !important;
}
/*# sourceMappingURL=bootstrap-reboot.css.map */

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,8 @@
/*!
* Bootstrap Reboot v4.6.2 (https://getbootstrap.com/)
* Copyright 2011-2022 The Bootstrap Authors
* Copyright 2011-2022 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus:not(:focus-visible){outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([class]){color:inherit;text-decoration:none}a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit;text-align:-webkit-match-parent}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}
/*# sourceMappingURL=bootstrap-reboot.min.css.map */

File diff suppressed because one or more lines are too long

10332
F4SDwebService/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

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,27 @@
using C4IT.FASD.Base;
using F4SDwebService;
using System;
using System.Web.Http;
namespace FasdWebService.Controllers
{
public class CheckConnectionController : ApiController
{
public IHttpActionResult Get()
{
var SupportAuthorisation = WebApiApplication.Collector?.InfrastructureConfig?.Authorisation != null;
// the use of ticket completition policy in this request is deprecated, but kept for backwards compatibility
var completitionPolicy = enumShowDocumentCaseDialog.ifRequired;
if (WebApiApplication.Collector != null)
{
var globalConfig = WebApiApplication.Collector.GetGlobalConfig();
completitionPolicy = globalConfig.TicketConfiguration.CompletitionPolicy;
}
var output = new cFasdApiConnectionInfo() { ServerVersion = cInfo.ProductVersion(), MinCockpitVersion = cInfo.MinClientVersion(), ConfigRevision = 0, SupportAuthorisation = SupportAuthorisation, WebServerStatus = WebApiApplication.Collector?.ServerStatus ?? enumWebServerStatus.starting, showDocumentCaseDialog = completitionPolicy };
return Ok(output);
}
}
}

View File

@@ -0,0 +1,280 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using System.Threading;
using System.Web.Http;
using C4IT.FASD.Base;
using C4IT.Logging;
using static C4IT.Logging.cLogManager;
using C4IT.DataHistoryProvider;
namespace F4SDwebService.Controllers
{
public class F4SDAnalyticsDataController : ApiController
{
[HttpGet]
[Route("api/F4SDAnalytics/GetF4SDAnalyticsState")]
public IHttpActionResult GetF4SDAnalyticsState()
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
if (!WebApiApplication.Collector.F4SDAnalyticsValid)
return Ok<bool>(false);
return Ok<bool>(true);
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return BadRequest();
}
[HttpPost]
[Route("api/F4SDAnalytics/CreateUserSession")]
public async Task<IHttpActionResult> CreateUserSession([FromBody] cF4SDUserSessionParameters jsonRequest)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
var requestInfo = new cF4sdWebRequestInfo("CreateUserSession", jsonRequest?.SessionId?.ToString());
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceStart(0, requestInfo.requestName, requestInfo.id, requestInfo.created); }
var apiError = 0;
try
{
if (!WebApiApplication.Collector.F4SDAnalyticsValid)
return NotFound();
if (await WebApiApplication.Collector.CreateUserSessionAsync(jsonRequest, requestInfo, 1, CancellationToken.None))
return Ok();
}
catch (Exception E)
{
apiError = E.HResult;
LogException(E);
}
finally
{
if (WebApiApplication.Debug_apiTiming) WebApiApplication.SaveApiTimingEntry(requestInfo.requestName, requestInfo.id, requestInfo.created, apiError);
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(0, requestInfo.requestName, requestInfo.id, requestInfo.created, requestInfo.created, ErrorCode: apiError); }
if (CM != null) LogMethodEnd(CM);
}
return BadRequest();
}
[HttpPost]
[Route("api/F4SDAnalytics/CloseUserSession")]
public async Task<IHttpActionResult> CloseUserSession([FromBody] cF4SDUserSessionParameters jsonRequest)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
var requestInfo = new cF4sdWebRequestInfo("CloseUserSession", jsonRequest?.SessionId?.ToString());
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceStart(0, requestInfo.requestName, requestInfo.id, requestInfo.created); }
var apiError = 0;
try
{
if (!WebApiApplication.Collector.F4SDAnalyticsValid)
return NotFound();
if (await WebApiApplication.Collector.CloseUserSessionAsync(jsonRequest, requestInfo, 1 , CancellationToken.None))
return Ok();
}
catch (Exception E)
{
apiError = E.HResult;
LogException(E);
}
finally
{
if (WebApiApplication.Debug_apiTiming) WebApiApplication.SaveApiTimingEntry(requestInfo.requestName, requestInfo.id, requestInfo.created, apiError);
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(0, requestInfo.requestName, requestInfo.id, requestInfo.created, requestInfo.created, ErrorCode: apiError); }
if (CM != null) LogMethodEnd(CM);
}
return BadRequest();
}
[HttpPost]
[Route("api/F4SDAnalytics/CreateCase")]
public async Task<IHttpActionResult> CreateCase([FromBody] cF4SDCaseParameters jsonRequest)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
var requestInfo = new cF4sdWebRequestInfo("CreateCase", jsonRequest?.SessionId?.ToString());
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceStart(0, requestInfo.requestName, requestInfo.id, requestInfo.created); }
var apiError = 0;
try
{
if (!WebApiApplication.Collector.F4SDAnalyticsValid)
{
return NotFound();
}
if (await WebApiApplication.Collector.CreateCaseAsync(jsonRequest, requestInfo, 1, CancellationToken.None))
{
return Ok();
}
}
catch (Exception E)
{
apiError = E.HResult;
LogException(E);
}
finally
{
if (WebApiApplication.Debug_apiTiming) WebApiApplication.SaveApiTimingEntry(requestInfo.requestName, requestInfo.id, requestInfo.created, apiError);
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(0, requestInfo.requestName, requestInfo.id, requestInfo.created, requestInfo.created, ErrorCode: apiError); }
if (CM != null) LogMethodEnd(CM);
}
return BadRequest();
}
[HttpPost]
[Route("api/F4SDAnalytics/UpdateCaseState")]
public async Task<IHttpActionResult> UpdateCaseState([FromBody] cF4SDCaseTimeParameters jsonRequest)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
var requestInfo = new cF4sdWebRequestInfo("UpdateCaseState", jsonRequest?.CaseId?.ToString());
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceStart(0, requestInfo.requestName, requestInfo.id, requestInfo.created); }
var apiError = 0;
try
{
if (!WebApiApplication.Collector.F4SDAnalyticsValid)
return NotFound();
if (await WebApiApplication.Collector.UpdateCaseStateAsync(jsonRequest, requestInfo, 1, CancellationToken.None))
return Ok();
}
catch (Exception E)
{
apiError = E.HResult;
LogException(E);
}
finally
{
if (WebApiApplication.Debug_apiTiming) WebApiApplication.SaveApiTimingEntry(requestInfo.requestName, requestInfo.id, requestInfo.created, apiError);
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(0, requestInfo.requestName, requestInfo.id, requestInfo.created, requestInfo.created, ErrorCode: apiError); }
if (CM != null) LogMethodEnd(CM);
}
return BadRequest();
}
[HttpPost]
[Route("api/F4SDAnalytics/ReportQuickActionExecution")]
public async Task<IHttpActionResult> ReportQuickActionExecution([FromBody] cF4SDQuickActionParameters jsonRequest)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
var requestInfo = new cF4sdWebRequestInfo("ReportQuickActionExecution", jsonRequest?.DeviceId?.ToString());
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceStart(0, requestInfo.requestName, requestInfo.id, requestInfo.created); }
var apiError = 0;
try
{
if (!WebApiApplication.Collector.IsValid)
return NotFound();
List<Task<bool>> taskList = new List<Task<bool>>();
if (WebApiApplication.Collector.F4SDAnalyticsValid)
taskList.Add(WebApiApplication.Collector.ReportQuickActionExecutionAsync(jsonRequest, WebApiApplication.Collector.InfrastructureConfig.F4SDAnalyticsDB.Connection, requestInfo, 1, CancellationToken.None));
await Task.WhenAll(taskList).ConfigureAwait(false);
if (taskList.All(taskResult => taskResult.Result.Equals(true)))
return Ok();
return BadRequest();
}
catch (Exception E)
{
apiError = E.HResult;
LogException(E);
}
finally
{
if (WebApiApplication.Debug_apiTiming) WebApiApplication.SaveApiTimingEntry(requestInfo.requestName, requestInfo.id, requestInfo.created, apiError);
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(0, requestInfo.requestName, requestInfo.id, requestInfo.created, requestInfo.created, ErrorCode: apiError); }
if (CM != null) LogMethodEnd(CM);
}
return BadRequest();
}
[HttpPost]
[Route("api/F4SDAnalytics/KeepAliveSession")]
public IHttpActionResult KeepAliveSession([FromBody] Guid SessionId)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
LogEntry($"API Call KeepAliveSession: " + SessionId.ToString());
if (!WebApiApplication.Collector.F4SDAnalyticsValid)
return NotFound();
if (WebApiApplication.Collector.KeepAliveSession(SessionId, CancellationToken.None))
return Ok();
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return BadRequest();
}
[HttpPost]
[Route("api/F4SDAnalytics/KeepAliveCase")]
public async Task<IHttpActionResult> KeepAliveCase([FromBody] Guid CaseId)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
var requestInfo = new cF4sdWebRequestInfo("KeepAliveCase", CaseId.ToString());
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceStart(0, requestInfo.requestName, requestInfo.id, requestInfo.created); }
var apiError = 0;
try
{
LogEntry($"API Call KeepAliveSession: " + CaseId.ToString());
if (!WebApiApplication.Collector.F4SDAnalyticsValid)
{
return NotFound();
}
if (await WebApiApplication.Collector.KeepAliveCase(CaseId, requestInfo, 1, CancellationToken.None))
return Ok();
}
catch (Exception E)
{
apiError = E.HResult;
LogException(E);
}
finally
{
if (WebApiApplication.Debug_apiTiming) WebApiApplication.SaveApiTimingEntry(requestInfo.requestName, requestInfo.id, requestInfo.created, apiError);
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(0, requestInfo.requestName, requestInfo.id, requestInfo.created, requestInfo.created, ErrorCode: apiError); }
if (CM != null) LogMethodEnd(CM);
}
return BadRequest();
}
}
}

View File

@@ -0,0 +1,21 @@
using C4IT.FASD.Base;
using F4SDwebService;
using System;
using System.Web.Http;
namespace FasdWebService.Controllers
{
public class GetAgentApiConfigurationController : ApiController
{
public IHttpActionResult Get()
{
var AgentConfig = WebApiApplication.Collector?.InfrastructureConfig?.ClientAgent;
if (AgentConfig == null)
return NotFound();
var output = WebApiApplication.Collector.F4sdAgent.GetAgentApiConfiguration(false);
return Ok(output);
}
}
}

View File

@@ -0,0 +1,88 @@
using C4IT.DataHistoryProvider;
using C4IT.FASD.Base;
using C4IT.Logging;
using F4SDwebService;
using System;
using System.Net;
using System.Reflection;
using System.Web.Http;
using static C4IT.Logging.cLogManager;
namespace FasdWebService.Controllers
{
public class GetConfigurationController : ApiController
{
public IHttpActionResult Get(string configType)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
var requestInfo = new cF4sdWebRequestInfo("GetConfiguration", configType, cAuthentication.GetUserInfo(ActionContext));
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceStart(0, requestInfo.requestName, requestInfo.id, requestInfo.created); }
var apiError = 0;
try
{
if (!Enum.TryParse(configType, true, out enumFasdConfigurationType configurationType) || configurationType == enumFasdConfigurationType.unknown)
{
LogEntry($"Couldn't find a configuration with name '{configType}'");
apiError = (int)HttpStatusCode.NotFound;
return NotFound();
}
var output = cConfigCache.Get(configurationType);
if (output != null)
return Ok(output.Content);
apiError = (int)HttpStatusCode.NotFound;
}
catch (Exception E)
{
apiError = E.HResult;
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(0, requestInfo.requestName, requestInfo.id, requestInfo.created, requestInfo.created, ErrorCode: apiError); }
if (WebApiApplication.Debug_apiTiming) WebApiApplication.SaveApiTimingEntry(requestInfo.requestName, requestInfo.id, requestInfo.created, apiError);
if (CM != null) LogMethodEnd(CM);
}
LogEntry("Bad request happended when calling GetConfiguration Controller.");
return BadRequest();
}
[Route("api/GetCockpitConfiguration")]
public IHttpActionResult GetCockpitConfiguration()
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
var requestInfo = new cF4sdWebRequestInfo("GetCockpitConfiguration", "configCockpit", cAuthentication.GetUserInfo(ActionContext));
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceStart(0, requestInfo.requestName, requestInfo.id, requestInfo.created); }
var apiError = 0;
try
{
var retVal = WebApiApplication.Collector.GetCockpitConfiguration(requestInfo);
if (retVal != null)
return Ok(retVal);
apiError = (int)HttpStatusCode.BadRequest;
}
catch (Exception E)
{
apiError = E.HResult;
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(0, requestInfo.requestName, requestInfo.id, requestInfo.created, requestInfo.created, ErrorCode: apiError); }
if (WebApiApplication.Debug_apiTiming) WebApiApplication.SaveApiTimingEntry(requestInfo.requestName, requestInfo.id, requestInfo.created, apiError);
if (CM != null) LogMethodEnd(CM);
}
return BadRequest();
}
}
}

View File

@@ -0,0 +1,64 @@
using C4IT.DataHistoryProvider;
using C4IT.FASD.Base;
using C4IT.Logging;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http;
using static C4IT.Logging.cLogManager;
namespace F4SDwebService.Controllers
{
public class GetDetailsDataController : ApiController
{
public async Task<IHttpActionResult> Get(string jsonRequest)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
var Request = JsonConvert.DeserializeObject<cF4sdHealthCardRawDataRequest>(jsonRequest);
var requestId = Request.Identities?.First()?.Id.ToString();
var requestInfo = new cF4sdWebRequestInfo("GetDetailsData", requestId, cAuthentication.GetUserInfo(ActionContext));
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceStart(0, requestInfo.requestName, requestInfo.id, requestInfo.created); }
var apiError = 0;
try
{
var RetVal = await WebApiApplication.Collector.GetDetailsTableResultsAsync(Request.Tables, Request.Identities, Request.RefTime, Request.MaxAge, CancellationToken.None, requestInfo, 1).ConfigureAwait(false);
if (RetVal != null)
return Ok(RetVal);
return Ok(new List<cF4SDHealthCardRawData.cHealthCardDetailsTable>());
}
catch (Exception E)
{
apiError = E.HResult;
LogException(E);
}
finally
{
if (WebApiApplication.Debug_apiTiming) WebApiApplication.SaveApiTimingEntry(requestInfo.requestName, requestInfo.id, requestInfo.created, apiError);
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(0, requestInfo.requestName, requestInfo.id, requestInfo.created, requestInfo.created, ErrorCode: apiError); }
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return BadRequest();
}
}
}

View File

@@ -0,0 +1,144 @@
using C4IT.DataHistoryProvider;
using C4IT.FASD.Base;
using C4IT.Logging;
using Newtonsoft.Json;
using System;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http;
using static C4IT.Logging.cLogManager;
namespace F4SDwebService.Controllers
{
public class GetRawDataController : ApiController
{
public async Task<IHttpActionResult> Get(string jsonRequest)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
var Request = JsonConvert.DeserializeObject<cF4sdHealthCardRawDataRequest>(jsonRequest);
var requestInfo = new cF4sdWebRequestInfo("GetRawData", Request.Identities?.First()?.Id.ToString(), cAuthentication.GetUserInfo(ActionContext));
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceStart(0, requestInfo.requestName, requestInfo.id, requestInfo.created); }
var apiError = 0;
try
{
var RetVal = await WebApiApplication.Collector.GetTableResults(Request.Tables, Request.Identities, Request.RefTime, Request.MaxAge, true, CancellationToken.None, requestInfo, 1).ConfigureAwait(false);
if (RetVal != null)
return Ok(RetVal);
return Ok(new cF4SDHealthCardRawData());
}
catch (Exception E)
{
apiError = E.HResult;
LogException(E);
}
finally
{
if (WebApiApplication.Debug_apiTiming) WebApiApplication.SaveApiTimingEntry(requestInfo.requestName, requestInfo.id, requestInfo.created, apiError);
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(0, requestInfo.requestName, requestInfo.id, requestInfo.created, requestInfo.created, ErrorCode: apiError); }
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return BadRequest();
}
[Route("api/GetRawDataStart")]
public async Task<IHttpActionResult> GetWithSuccsession(string jsonRequest)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
var Request = JsonConvert.DeserializeObject<cF4sdHealthCardRawDataRequest>(jsonRequest);
var requestInfo = new cF4sdWebRequestInfo("GetRawDataStart", Request.Identities?.First()?.Id.ToString(), cAuthentication.GetUserInfo(ActionContext));
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceStart(0, requestInfo.requestName, requestInfo.id, requestInfo.created); }
var apiError = 0;
try
{
var RetVal = await WebApiApplication.Collector.GetTableResults(Request.Tables, Request.Identities, Request.RefTime, Request.MaxAge, false, CancellationToken.None, requestInfo, 1).ConfigureAwait(false);
if (RetVal != null)
return Ok(RetVal);
return Ok(new cF4SDHealthCardRawData());
}
catch (Exception E)
{
apiError = E.HResult;
LogException(E);
}
finally
{
if (WebApiApplication.Debug_apiTiming) WebApiApplication.SaveApiTimingEntry(requestInfo.requestName, requestInfo.id, requestInfo.created, apiError);
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(0, requestInfo.requestName, requestInfo.id, requestInfo.created, requestInfo.created, ErrorCode: apiError); }
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return BadRequest();
}
[Route("api/GetRawDataNext")]
public async Task<IHttpActionResult> GetNext(Guid RequestId)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
var requestInfo = new cF4sdWebRequestInfo("GetRawDataNext", RequestId.ToString(), cAuthentication.GetUserInfo(ActionContext));
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceStart(0, requestInfo.requestName, requestInfo.id, requestInfo.created); }
var apiError = 0;
try
{
var res = await SuccessorCache.GetNextResult(WebApiApplication.Collector, RequestId, false, requestInfo, 1);
return Ok(res);
}
catch (Exception E)
{
apiError = E.HResult;
LogException(E);
}
finally
{
if (WebApiApplication.Debug_apiTiming) WebApiApplication.SaveApiTimingEntry(requestInfo.requestName, requestInfo.id, requestInfo.created, apiError);
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(0, requestInfo.requestName, requestInfo.id, requestInfo.created, requestInfo.created, ErrorCode: apiError); }
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return BadRequest();
}
}
}

View File

@@ -0,0 +1,97 @@
using C4IT.DataHistoryProvider;
using C4IT.FASD.Base;
using C4IT.Logging;
using Newtonsoft.Json;
using System;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http;
using static C4IT.Logging.cLogManager;
namespace F4SDwebService.Controllers
{
public class GetSelectionDataController : ApiController
{
[Route("api/GetSelectionCount")]
public async Task<IHttpActionResult> GetCount(string jsonRequest)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
var Request = JsonConvert.DeserializeObject<cF4sdHealthSelectionDataRequest>(jsonRequest);
var requestInfo = new cF4sdWebRequestInfo("GetSelectionCount", Request.Identities?.First()?.Id.ToString(), cAuthentication.GetUserInfo(ActionContext));
var apiError = 0;
try
{
var RetVal = await WebApiApplication.Collector.GetSelectionTableResultCountAsync(Request.Table, Request.Identities, Request.Search, requestInfo, CancellationToken.None, Request.ResetFilter, Request.FilterParams).ConfigureAwait(false);
return Ok(RetVal);
}
catch (Exception E)
{
apiError = E.HResult;
LogException(E);
}
finally
{
if (WebApiApplication.Debug_apiTiming) WebApiApplication.SaveApiTimingEntry(requestInfo.requestName, requestInfo.id, requestInfo.created, apiError);
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(0, requestInfo.requestName, requestInfo.id, requestInfo.created, requestInfo.created, ErrorCode: apiError); }
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return BadRequest();
}
[Route("api/GetSelectionData")]
public async Task<IHttpActionResult> Get(string jsonRequest)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
var Request = JsonConvert.DeserializeObject<cF4sdHealthSelectionDataRequest>(jsonRequest);
var requestInfo = new cF4sdWebRequestInfo("GetSelectionData", Request.Identities?.First()?.Id.ToString(), cAuthentication.GetUserInfo(ActionContext));
var apiError = 0;
try
{
var RetVal = await WebApiApplication.Collector.GetSelectionTableResultAsync(Request.Table, Request.Identities, Request.Search, Request.PageSize, Request.Page, requestInfo, CancellationToken.None, Request.ResetFilter, Request.FilterParams).ConfigureAwait(false);
if (RetVal != null)
return Ok(RetVal);
return Ok();
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (WebApiApplication.Debug_apiTiming) WebApiApplication.SaveApiTimingEntry(requestInfo.requestName, requestInfo.id, requestInfo.created, apiError);
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(0, requestInfo.requestName, requestInfo.id, requestInfo.created, requestInfo.created, ErrorCode: apiError); }
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return BadRequest();
}
}
}

View File

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

View File

@@ -0,0 +1,214 @@
using C4IT.DataHistoryProvider;
using C4IT.FASD.Base;
using C4IT.Logging;
using C4IT.XML;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Net;
using System.Net.Http.Headers;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;
using static C4IT.Logging.cLogManager;
namespace F4SDwebService.Controllers
{
public class LogonController : ApiController
{
[Route("api/Logon/GetUserIdByAccount")]
public async Task<IHttpActionResult> GetUserIdByAccount(string Account, string Domain)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
var requestInfo = new cF4sdWebRequestInfo("SearchDefault", (Domain ?? "") + ":" + (Account ?? ""));
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceStart(0, requestInfo.requestName, requestInfo.id, requestInfo.created); }
var apiError = 0;
try
{
var res = await WebApiApplication.Collector.GetUserIdFromAccountAsync(Account, Domain, requestInfo, 1, CancellationToken.None);
if (res != null)
return Ok((Guid)res);
return Ok(Guid.Empty);
}
catch (Exception E)
{
apiError = E.HResult;
LogException(E);
}
finally
{
if (WebApiApplication.Debug_apiTiming) WebApiApplication.SaveApiTimingEntry(requestInfo.requestName, requestInfo.id, requestInfo.created, apiError);
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(0, requestInfo.requestName, requestInfo.id, requestInfo.created, requestInfo.created, ErrorCode: apiError); }
if (CM != null) LogMethodEnd(CM);
}
return NotFound();
}
[Route("api/Logon/Logon")]
[HttpGet]
[Authorize]
public async Task<IHttpActionResult> WinLogon(string lang = null)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
var _id = HttpContext.Current?.User?.Identity;
var requestInfo = new cF4sdWebRequestInfo("RegisterExternalToken", _id == null ? _id.Name : "unknown user");
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceStart(0, requestInfo.requestName, requestInfo.id, requestInfo.created); }
var apiError = 0;
try
{
LogEntry($"WinLogon with language: {lang}", LogLevels.Debug);
if (WebApiApplication.Collector == null)
return NotFound();
try
{
var _regBase = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32);
var _regKey = _regBase.OpenSubKey("SOFTWARE\\Consulting4IT GmbH\\First Aid Service Desk\\Cockpit", false);
if (_regKey != null && int.TryParse(_regKey.GetValue("DebugNoAuthentication", 0).ToString(), out var _regFlag))
{
if (_regFlag > 0)
return Unauthorized();
}
}
catch { }
if (_id == null)
return new System.Web.Http.Results.UnauthorizedResult(new List<AuthenticationHeaderValue>() { new AuthenticationHeaderValue("NTLM"), new AuthenticationHeaderValue("Negotiate") }, this);
if (!string.IsNullOrEmpty(lang))
{
try
{
lang = CultureInfo.GetCultureInfoByIetfLanguageTag(lang).IetfLanguageTag;
}
catch { }
}
var UserInfo = await WebApiApplication.Collector.GetWinUserInfoAsync(_id, lang, false, new CancellationTokenSource(18000).Token, requestInfo, 1);
if (UserInfo == null)
{
return new System.Web.Http.Results.UnauthorizedResult(new List<AuthenticationHeaderValue>() { new AuthenticationHeaderValue("NTLM"), new AuthenticationHeaderValue("Negotiate") }, this);
}
LogEntry($"Successfull WinLogon with language: {lang}", LogLevels.Debug);
return Ok(UserInfo);
}
catch (Exception E)
{
apiError = E.HResult;
LogException(E);
}
finally
{
if (WebApiApplication.Debug_apiTiming) WebApiApplication.SaveApiTimingEntry(requestInfo.requestName, requestInfo.id, requestInfo.created, apiError);
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(0, requestInfo.requestName, requestInfo.id, requestInfo.created, requestInfo.created, ErrorCode: apiError); }
if (CM != null) LogMethodEnd(CM);
}
return NotFound();
}
[Route("api/Logon/RegisterExternalToken")]
[HttpPost]
public async Task<IHttpActionResult> RegisterExternalToken(cF4SDTokenRegistration TokenRegistration)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
var requestInfo = new cF4sdWebRequestInfo("RegisterExternalToken", TokenRegistration.UserId.ToString() + "_" + TokenRegistration.TokenType.ToString(), cAuthentication.GetUserInfo(ActionContext));
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceStart(0, requestInfo.requestName, requestInfo.id, requestInfo.created); }
var apiError = 0;
try
{
var _res = await WebApiApplication.Collector.ValidateTokenAsync(TokenRegistration, requestInfo, 1, new CancellationTokenSource().Token);
if (_res?.ValidLogonsUntil != null && _res.ValidLogonsUntil.Count > 0)
{
_res.ChangeUserInfo(requestInfo.userInfo);
var _token = WebApiApplication.Collector.GenerateJsonWebToken(requestInfo.userInfo);
_res.Token = _token;
if (cLogManager.DefaultLogger.IsDebug)
{
var _msg = Newtonsoft.Json.JsonConvert.SerializeObject(_res, Newtonsoft.Json.Formatting.Indented);
var _lstMsg = new List<string>()
{
$"RegisterExternalToken result for user {TokenRegistration.Name} and token type {TokenRegistration.TokenType.ToString()}",
_msg
};
cLogManager.DefaultLogger.LogList(LogLevels.Debug, _lstMsg);
}
return Ok(_res);
}
}
catch (Exception E)
{
apiError = E.HResult;
LogException(E);
}
finally
{
if (WebApiApplication.Debug_apiTiming) WebApiApplication.SaveApiTimingEntry(requestInfo.requestName, requestInfo.id, requestInfo.created, apiError);
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(0, requestInfo.requestName, requestInfo.id, requestInfo.created, requestInfo.created, ErrorCode: apiError); }
if (CM != null) LogMethodEnd(CM);
}
return NotFound();
}
[Route("api/Logon/GetAdditionalUserInfo")]
[HttpGet]
public async Task<IHttpActionResult> GetAdditionalUserInfo(string AccountType)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
var _ui = cAuthentication.GetUserInfo(ActionContext);
var requestInfo = new cF4sdWebRequestInfo("GetAdditionalUserInfo", AccountType + ((_ui?.Id is null) ? "" : "_" + _ui.Id.ToString()), _ui);
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceStart(0, requestInfo.requestName, requestInfo.id, requestInfo.created); }
var apiError = 0;
try
{
var _accountType = cXmlParser.GetEnumFromString(AccountType, enumAdditionalAuthentication.unknown);
if (_accountType == enumAdditionalAuthentication.unknown)
return NotFound();
var _retVal = await WebApiApplication.Collector.GetAdditionalUserInfo(_accountType, requestInfo, 1, CancellationToken.None);
if (_retVal != null)
return Ok(_retVal);
apiError = (int)HttpStatusCode.NotFound;
}
catch (Exception E)
{
apiError = E.HResult;
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(0, requestInfo.requestName, requestInfo.id, requestInfo.created, requestInfo.created, ErrorCode: apiError); }
if (WebApiApplication.Debug_apiTiming) WebApiApplication.SaveApiTimingEntry(requestInfo.requestName, requestInfo.id, requestInfo.created, apiError);
if (CM != null) LogMethodEnd(CM);
}
return NotFound();
}
}
}

View File

@@ -0,0 +1,63 @@
using C4IT.DataHistoryProvider;
using C4IT.FASD.Base;
using C4IT.Logging;
using System;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http;
using static C4IT.Logging.cLogManager;
namespace F4SDwebService.Controllers.Matrix42
{
public class Matrix42TicketFinalizationController : ApiController
{
[HttpPost]
[Route("api/Matrix42/TicketFinalization")]
public async Task<IHttpActionResult> Matrix42TicketFinalization([FromBody] cApiM42Ticket jsonRequest)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
var requestInfo = new cF4sdWebRequestInfo("Matrix42TicketFinalization", jsonRequest.Action?.ToString() + " + " + jsonRequest.Ticket?.ToString() ?? "", cAuthentication.GetUserInfo(ActionContext));
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceStart(0, requestInfo.requestName, requestInfo.id, requestInfo.created); }
var apiError = 0;
try
{
if (string.Equals(jsonRequest.StatusIdValue, "Closed", StringComparison.InvariantCultureIgnoreCase))
await WebApiApplication.Collector.M42WpmCollector.ReopenM42TicketAsync(jsonRequest, requestInfo, 1, CancellationToken.None);
switch (jsonRequest.Action)
{
case enumCloseCaseTicketStatus.Save:
if (jsonRequest.Ticket == null || jsonRequest.Ticket.HasValue && jsonRequest.Ticket.Equals(Guid.Empty))
return Ok(await WebApiApplication.Collector.M42WpmCollector.CreateM42TicketAsync(jsonRequest, requestInfo, 1, CancellationToken.None));
else
return Ok(await WebApiApplication.Collector.M42WpmCollector.UpdateM42TicketAsync(jsonRequest, requestInfo, 1, CancellationToken.None));
case enumCloseCaseTicketStatus.Close:
return Ok(await WebApiApplication.Collector.M42WpmCollector.CloseM42TicketAsync(jsonRequest, requestInfo, 1, CancellationToken.None));
case enumCloseCaseTicketStatus.OnHold:
return Ok(await WebApiApplication.Collector.M42WpmCollector.PauseM42TicketAsync(jsonRequest, requestInfo, 1, CancellationToken.None));
case enumCloseCaseTicketStatus.Forward:
return Ok(await WebApiApplication.Collector.M42WpmCollector.ForwardM42TicketAsync(jsonRequest, requestInfo, 1, CancellationToken.None));
default: break;
}
return Ok(jsonRequest);
}
catch (Exception E)
{
apiError = E.HResult;
LogException(E);
}
finally
{
if (WebApiApplication.Debug_apiTiming) WebApiApplication.SaveApiTimingEntry(requestInfo.requestName, requestInfo.id, requestInfo.created, apiError);
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(0, requestInfo.requestName, requestInfo.id, requestInfo.created, requestInfo.created, ErrorCode: apiError); }
if (CM != null) LogMethodEnd(CM);
}
return BadRequest();
}
}
}

View File

@@ -0,0 +1,93 @@
using C4IT.DataHistoryProvider;
using C4IT.FASD.Base;
using C4IT.Logging;
using System;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http;
using static C4IT.Logging.cLogManager;
namespace F4SDwebService.Controllers
{
public class QuickActionDataController : ApiController
{
[HttpPost]
[Route("api/QuickAction/Run")]
public async Task<IHttpActionResult> QuickActionRun([FromBody] cF4SDServerQuickActionParameters jsonRequest)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
var requestInfo = new cF4sdWebRequestInfo(jsonRequest.Action, jsonRequest.ParamaterType);
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceStart(0, requestInfo.requestName, requestInfo.id, requestInfo.created); }
var apiError = 0;
try
{
if (jsonRequest.Category == "Intune")
{
var result = await WebApiApplication.Collector.ActiveDirectory.QuickActionRun(jsonRequest, requestInfo, CancellationToken.None);
if (result is null)
return Ok();
return Ok(result);
}
if (jsonRequest.Category == "Citrix")
{
var result = await WebApiApplication.Collector.CitrixCollector.QuickActionRun(jsonRequest, requestInfo, CancellationToken.None);
if (result is null)
return Ok();
return Ok(result);
}
else
return Ok();
}
catch (Exception E)
{
apiError = E.HResult;
LogException(E);
return BadRequest();
}
finally
{
if (WebApiApplication.Debug_apiTiming) WebApiApplication.SaveApiTimingEntry(requestInfo.requestName, requestInfo.id, requestInfo.created, apiError);
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(0, requestInfo.requestName, requestInfo.id, requestInfo.created, requestInfo.created, ErrorCode: apiError); }
if (CM != null) LogMethodEnd(CM);
}
}
[HttpGet]
[Route("api/QuickAction/GetQuickActionList")]
public IHttpActionResult GetQuickActionList()
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
var requestInfo = new cF4sdWebRequestInfo("GetQuickActionList", null);
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceStart(0, requestInfo.requestName, requestInfo.id, requestInfo.created); }
var apiError = 0;
try
{
var _quickActions = WebApiApplication.Collector.GetQuickActionAllList();
return Ok(_quickActions.Result);
}
catch (Exception E)
{
apiError = E.HResult;
LogException(E);
return BadRequest();
}
finally
{
if (WebApiApplication.Debug_apiTiming) WebApiApplication.SaveApiTimingEntry(requestInfo.requestName, requestInfo.id, requestInfo.created, apiError);
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(0, requestInfo.requestName, requestInfo.id, requestInfo.created, requestInfo.created, ErrorCode: apiError); }
if (CM != null) LogMethodEnd(CM);
}
}
}
}

View File

@@ -0,0 +1,315 @@
using C4IT.DataHistoryProvider;
using C4IT.Logging;
using System;
using System.Collections.Generic;
using System.Net;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http;
using static C4IT.Logging.cLogManager;
namespace F4SDwebService.Controllers
{
public class SearchDefaultController : ApiController
{
public async Task<IHttpActionResult> Get(string search)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
var requestInfo = new cF4sdWebRequestInfo("SearchDefault", search);
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceStart(0, requestInfo.requestName, requestInfo.id, requestInfo.created); }
var apiError = 0;
try
{
if (WebApiApplication.Collector == null)
return null;
var output = await WebApiApplication.Collector.DefaultSearchAsync(search, CancellationToken.None, requestInfo, 1);
if (output != null)
return Ok(output);
apiError = (int)HttpStatusCode.BadRequest;
}
catch (Exception E)
{
apiError = E.HResult;
LogException(E);
}
finally
{
if (WebApiApplication.Debug_apiTiming) WebApiApplication.SaveApiTimingEntry(requestInfo.requestName, requestInfo.id, requestInfo.created, apiError);
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(0, requestInfo.requestName, requestInfo.id, requestInfo.created, requestInfo.created, ErrorCode: apiError); }
if (CM != null) LogMethodEnd(CM);
}
return BadRequest();
}
[Route("api/SearchDetailed")]
public async Task<IHttpActionResult> GetDetailed(string search)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
var requestInfo = new cF4sdWebRequestInfo("SearchDetailed", search);
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceStart(0, requestInfo.requestName, requestInfo.id, requestInfo.created); }
var apiError = 0;
try
{
if (WebApiApplication.Collector == null)
return null;
var output = await WebApiApplication.Collector.DetailedSearchAsync(search, CancellationToken.None, requestInfo, 1);
if (output != null)
return Ok(output);
apiError = (int)HttpStatusCode.BadRequest;
}
catch (Exception E)
{
apiError = E.HResult;
LogException(E);
}
finally
{
if (WebApiApplication.Debug_apiTiming) WebApiApplication.SaveApiTimingEntry(requestInfo.requestName, requestInfo.id, requestInfo.created, apiError);
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(0, requestInfo.requestName, requestInfo.id, requestInfo.created, requestInfo.created, ErrorCode: apiError); }
if (CM != null) LogMethodEnd(CM);
}
return BadRequest();
}
[Route("api/SearchDetailedStart")]
public IHttpActionResult GetDetailedStart(string search)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
var requestInfo = new cF4sdWebRequestInfo("SearchDetailedStart", search);
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceStart(0, requestInfo.requestName, requestInfo.id, requestInfo.created); }
var apiError = 0;
try
{
if (WebApiApplication.Collector == null)
return null;
var output = WebApiApplication.Collector.DetailedSearchStart(search, requestInfo, 1);
if (output != null)
return Ok(output);
apiError = (int)HttpStatusCode.BadRequest;
}
catch (Exception E)
{
apiError = E.HResult;
LogException(E);
}
finally
{
if (WebApiApplication.Debug_apiTiming) WebApiApplication.SaveApiTimingEntry(requestInfo.requestName, requestInfo.id, requestInfo.created, apiError);
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(0, requestInfo.requestName, requestInfo.id, requestInfo.created, requestInfo.created, ErrorCode: apiError); }
if (CM != null) LogMethodEnd(CM);
}
return BadRequest();
}
[Route("api/SearchDetailedResult")]
public async Task<IHttpActionResult> GetDetailedResult(Guid taskID)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
var requestInfo = new cF4sdWebRequestInfo("SearchDetailedResult", taskID.ToString());
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceStart(0, requestInfo.requestName, requestInfo.id, requestInfo.created); }
var apiError = 0;
try
{
if (WebApiApplication.Collector == null)
return null;
var output = await cDataHistoryCollectorSearchTaskCache.GetResultAsync(taskID);
if (output != null)
return Ok(output);
apiError = (int)HttpStatusCode.BadRequest;
}
catch (Exception E)
{
apiError = E.HResult;
LogException(E);
}
finally
{
if (WebApiApplication.Debug_apiTiming) WebApiApplication.SaveApiTimingEntry(requestInfo.requestName, requestInfo.id, requestInfo.created, apiError);
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(0, requestInfo.requestName, requestInfo.id, requestInfo.created, requestInfo.created, ErrorCode: apiError); }
if (CM != null) LogMethodEnd(CM);
}
return BadRequest();
}
[Route("api/SearchDetailedStop")]
public IHttpActionResult GetDetailedStop(Guid taskID)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
var requestInfo = new cF4sdWebRequestInfo("SearchDetailedStop", taskID.ToString());
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceStart(0, requestInfo.requestName, requestInfo.id, requestInfo.created); }
var apiError = 0;
try
{
if (WebApiApplication.Collector == null)
return null;
cDataHistoryCollectorSearchTaskCache.StopTask(taskID);
return Ok();
}
catch (Exception E)
{
apiError = E.HResult;
LogException(E);
}
finally
{
if (WebApiApplication.Debug_apiTiming) WebApiApplication.SaveApiTimingEntry(requestInfo.requestName, requestInfo.id, requestInfo.created, apiError);
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(0, requestInfo.requestName, requestInfo.id, requestInfo.created, requestInfo.created, ErrorCode: apiError); }
if (CM != null) LogMethodEnd(CM);
}
return BadRequest();
}
[Route("api/SearchPhone")]
public async Task<IHttpActionResult> GetPhone(string searchPhone, string searchName)
{
var requestInfo = new cF4sdWebRequestInfo("SearchPhone", searchPhone);
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceStart(0, requestInfo.requestName, requestInfo.id, requestInfo.created); }
var apiError = 0;
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
if (WebApiApplication.Collector == null)
return null;
var output = await WebApiApplication.Collector.PhoneSearchAsync(searchPhone, searchName, CancellationToken.None, requestInfo, 1);
if (output != null)
return Ok(output);
apiError = (int)HttpStatusCode.BadRequest;
}
catch (Exception E)
{
apiError = E.HResult;
LogException(E);
}
finally
{
if (WebApiApplication.Debug_apiTiming) WebApiApplication.SaveApiTimingEntry(requestInfo.requestName, requestInfo.id, requestInfo.created, apiError);
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(0, requestInfo.requestName, requestInfo.id, requestInfo.created, requestInfo.created, ErrorCode: apiError); }
if (CM != null) LogMethodEnd(CM);
}
return BadRequest();
}
[Route("api/SearchComputerByName")]
public async Task<IHttpActionResult> GetComputerByName(string Name, string Domain = null)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
var requestInfo = new cF4sdWebRequestInfo("SearchComputerByName", Name);
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceStart(0, requestInfo.requestName, requestInfo.id, requestInfo.created); }
var apiError = 0;
try
{
if (WebApiApplication.Collector == null)
return NotFound();
var output = await WebApiApplication.Collector.ComputerSearchByNameAsync(Name, Domain, CancellationToken.None, requestInfo, 1);
if (output != null)
return Ok(output);
apiError = (int)HttpStatusCode.BadRequest;
}
catch (Exception E)
{
apiError = E.HResult;
LogException(E);
}
finally
{
if (WebApiApplication.Debug_apiTiming) WebApiApplication.SaveApiTimingEntry(requestInfo.requestName, requestInfo.id, requestInfo.created, apiError);
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(0, requestInfo.requestName, requestInfo.id, requestInfo.created, requestInfo.created, ErrorCode: apiError); }
if (CM != null) LogMethodEnd(CM);
}
return BadRequest();
}
[Route("api/SearchUserByNameAndSids")]
public async Task<IHttpActionResult> GetUserByNameAndSids(string Name, string SIDs)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
var requestInfo = new cF4sdWebRequestInfo("SearchUserByNameAndSids", Name);
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceStart(0, requestInfo.requestName, requestInfo.id, requestInfo.created); }
var apiError = 0;
try
{
if (WebApiApplication.Collector == null)
return null;
var lstSids = new List<string>();
if (!string.IsNullOrWhiteSpace(SIDs))
{
var arrSids = SIDs.Split(',');
foreach (var Entry in arrSids)
lstSids.Add(Entry.Trim());
}
var output = await WebApiApplication.Collector.UserSearchByNameAndSidsAsync(Name, lstSids, CancellationToken.None, requestInfo, 1);
if (output != null)
return Ok(output);
apiError = (int)HttpStatusCode.BadRequest;
}
catch (Exception E)
{
apiError = E.HResult;
LogException(E);
}
finally
{
if (WebApiApplication.Debug_apiTiming) WebApiApplication.SaveApiTimingEntry(requestInfo.requestName, requestInfo.id, requestInfo.created, apiError);
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(0, requestInfo.requestName, requestInfo.id, requestInfo.created, requestInfo.created, ErrorCode: apiError); }
if (CM != null) LogMethodEnd(CM);
}
return BadRequest();
}
}
}

View File

@@ -0,0 +1,88 @@
using C4IT.FASD.Base;
using C4IT_DataHistoryProvider_Base.DataSources;
using C4IT_DataHistoryProvider_Base.Services;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http;
using System.Web.Http.Results;
using static C4IT.Logging.cLogManager;
namespace F4SDwebService.Controllers
{
public class StagedSearchRelationController : ApiController
{
private readonly IStagedRelationService _relationService;
public StagedSearchRelationController()
{
_relationService = WebApiApplication.Collector.GetStagedRelationService();
}
[HttpPost]
[Route("api/StagedSearchRelations")]
public IHttpActionResult StartGatheringRelatedInformationObjects([FromBody] IEnumerable<cFasdApiSearchResultEntry> relatedTo, [FromUri] int age)
{
MethodBase CM = null; if (DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
cF4sdStagedSearchResultRelationTaskId taskId = _relationService.StartGatheringRelatedObjects(relatedTo, age);
if (taskId.Id == Guid.Empty)
return BadRequest();
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Accepted, taskId);
return new ResponseMessageResult(response);
}
catch (Exception ex)
{
LogException(ex);
}
finally { LogMethodEnd(CM); }
return InternalServerError();
}
[HttpGet]
[Route("api/StagedSearchRelations/{id}")]
public async Task<IHttpActionResult> GetRelatedInformationObjects([FromUri] Guid id, CancellationToken token)
{
MethodBase CM = null; if (DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
return Ok(await _relationService.GetRelatedObjectsAsync(id, token));
}
catch (Exception ex)
{
LogException(ex);
}
finally { LogMethodEnd(CM); }
return InternalServerError();
}
[HttpPost]
[Route("api/StagedSearchRelations/{id}/stop")]
public IHttpActionResult StopGatheringRelatedInformationObjects([FromUri] Guid id)
{
MethodBase CM = null; if (DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
_relationService.StopGatheringRelatedObjects(id);
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Accepted);
return new ResponseMessageResult(response);
}
catch (Exception ex)
{
LogException(ex);
}
finally { LogMethodEnd(CM); }
return InternalServerError();
}
}
}

View File

@@ -0,0 +1,104 @@
using C4IT.DataHistoryProvider;
using C4IT.FASD.Base;
using C4IT.Logging;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http;
using static C4IT.Logging.cLogManager;
namespace F4SDwebService.Controllers
{
public class GetUsageController : ApiController
{
public async Task<IHttpActionResult> Get(enumF4sdSearchResultClass Class, Guid ClassId, int Age)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
var requestInfo = new cF4sdWebRequestInfo("GetUsage", ClassId.ToString(), cAuthentication.GetUserInfo(ActionContext));
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceStart(0, requestInfo.requestName, requestInfo.id, requestInfo.created); }
var apiError = 0;
try
{
List<cF4sdApiSearchResultRelation> RetVal = null;
var infoClass = cF4sdIdentityEntry.GetFromSearchResult(Class);
if (infoClass != enumFasdInformationClass.Unknown)
{
RetVal = await WebApiApplication.Collector.GetUsageFromAgentData(infoClass, new List<Guid>() { ClassId }, Age, CancellationToken.None, requestInfo, 1);
return Ok(RetVal);
}
apiError = 404;
return NotFound();
}
catch (Exception E)
{
apiError = E.HResult;
LogException(E);
}
finally
{
if (WebApiApplication.Debug_apiTiming) WebApiApplication.SaveApiTimingEntry(requestInfo.requestName, requestInfo.id, requestInfo.created, apiError);
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(0, requestInfo.requestName, requestInfo.id, requestInfo.created, requestInfo.created, ErrorCode: apiError); }
if (CM != null) LogMethodEnd(CM);
}
return BadRequest();
}
[Route("api/GetUsageDetailed")]
public async Task<IHttpActionResult> GetDetailed(enumF4sdSearchResultClass Class, string ClassIds, int Age)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
var requestInfo = new cF4sdWebRequestInfo("GetUsageDetailed", ClassIds.Replace(",", "_"), cAuthentication.GetUserInfo(ActionContext));
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceStart(0, requestInfo.requestName, requestInfo.id, requestInfo.created); }
var apiError = 0;
try
{
var infoClass = cF4sdIdentityEntry.GetFromSearchResult(Class);
if (infoClass == enumFasdInformationClass.Unknown)
return NotFound();
var arrIds = ClassIds.Split(',');
if (arrIds == null || arrIds.Length < 1)
return NotFound();
var lstIds = new List<Guid>();
foreach (var Entry in arrIds)
{
var strId = Entry.Trim();
if (Guid.TryParse(strId, out var Id))
lstIds.Add(Id);
}
var res = await WebApiApplication.Collector.GetUsageFromAgentData(infoClass, lstIds, Age, CancellationToken.None, requestInfo, 1);
return Ok(res);
}
catch (Exception E)
{
apiError = E.HResult;
LogException(E);
}
finally
{
if (WebApiApplication.Debug_apiTiming) WebApiApplication.SaveApiTimingEntry(requestInfo.requestName, requestInfo.id, requestInfo.created, apiError);
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(0, requestInfo.requestName, requestInfo.id, requestInfo.created, requestInfo.created, ErrorCode: apiError); }
if (CM != null) LogMethodEnd(CM);
}
return BadRequest();
}
}
}

View File

@@ -0,0 +1,47 @@
using C4IT.DataHistoryProvider;
using C4IT.FASD.Base;
using C4IT.Logging;
using System;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http;
using static C4IT.Logging.cLogManager;
namespace F4SDwebService.Controllers
{
public class WritePropertyController : ApiController
{
[HttpPost]
[Route("api/WriteProperty")]
public async Task<IHttpActionResult> Put([FromBody] cF4SDWriteParameters jsonRequest)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
var requestInfo = new cF4sdWebRequestInfo("WriteProperty", jsonRequest.id.ToString(), cAuthentication.GetUserInfo(ActionContext));
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceStart(0, requestInfo.requestName, requestInfo.id, requestInfo.created); }
var apiError = 0;
try
{
if (await WebApiApplication.Collector.WritePropertyAsync(jsonRequest, requestInfo, CancellationToken.None))
return Ok();
apiError = -1;
}
catch (Exception E)
{
apiError = E.HResult;
LogException(E);
}
finally
{
if (WebApiApplication.Debug_apiTiming) WebApiApplication.SaveApiTimingEntry(requestInfo.requestName, requestInfo.id, requestInfo.created, apiError);
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(0, requestInfo.requestName, requestInfo.id, requestInfo.created, requestInfo.created, ErrorCode: apiError); }
if (CM != null) LogMethodEnd(CM);
}
return BadRequest();
}
}
}

View File

@@ -0,0 +1,686 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TypeScript\Microsoft.TypeScript.Default.props" Condition="Exists('$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TypeScript\Microsoft.TypeScript.Default.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>{ABB7E086-1062-439F-BA05-04F9D287D550}</ProjectGuid>
<ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>F4SDwebService</RootNamespace>
<AssemblyName>F4SD-Cockpit-WebService</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<MvcBuildViews>false</MvcBuildViews>
<UseIISExpress>true</UseIISExpress>
<Use64BitIISExpress>true</Use64BitIISExpress>
<IISExpressSSLPort>44307</IISExpressSSLPort>
<IISExpressAnonymousAuthentication>enabled</IISExpressAnonymousAuthentication>
<IISExpressWindowsAuthentication>enabled</IISExpressWindowsAuthentication>
<IISExpressUseClassicPipelineMode />
<UseGlobalApplicationHostFile />
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
<TypeScriptToolsVersion>4.3</TypeScriptToolsVersion>
<SccProjectName>SAK</SccProjectName>
<SccLocalPath>SAK</SccLocalPath>
<SccAuxPath>SAK</SccAuxPath>
<SccProvider>SAK</SccProvider>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>TRACE;DEBUG</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="Azure.Core, Version=1.47.1.0, Culture=neutral, PublicKeyToken=92742159e12e44c8, processorArchitecture=MSIL">
<HintPath>..\packages\Azure.Core.1.47.1\lib\net472\Azure.Core.dll</HintPath>
</Reference>
<Reference Include="Azure.Identity, Version=1.14.2.0, Culture=neutral, PublicKeyToken=92742159e12e44c8, processorArchitecture=MSIL">
<HintPath>..\packages\Azure.Identity.1.14.2\lib\netstandard2.0\Azure.Identity.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Bcl.AsyncInterfaces, Version=9.0.0.7, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bcl.AsyncInterfaces.9.0.7\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Bcl.Cryptography, Version=9.0.0.7, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bcl.Cryptography.9.0.7\lib\net462\Microsoft.Bcl.Cryptography.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Bcl.TimeProvider, Version=9.0.0.7, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bcl.TimeProvider.9.0.7\lib\net462\Microsoft.Bcl.TimeProvider.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.4.1.0\lib\net472\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CSharp" />
<Reference Include="Microsoft.Data.SqlClient, Version=6.0.0.0, Culture=neutral, PublicKeyToken=23ec7fc2d6eaa4a5, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Data.SqlClient.6.1.0\lib\net462\Microsoft.Data.SqlClient.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Caching.Abstractions, Version=9.0.0.7, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.Caching.Abstractions.9.0.7\lib\net462\Microsoft.Extensions.Caching.Abstractions.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Caching.Memory, Version=9.0.0.7, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.Caching.Memory.9.0.7\lib\net462\Microsoft.Extensions.Caching.Memory.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.DependencyInjection.Abstractions, Version=9.0.0.7, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.9.0.7\lib\net462\Microsoft.Extensions.DependencyInjection.Abstractions.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Logging.Abstractions, Version=9.0.0.7, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.Logging.Abstractions.9.0.7\lib\net462\Microsoft.Extensions.Logging.Abstractions.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Options, Version=9.0.0.7, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.Options.9.0.7\lib\net462\Microsoft.Extensions.Options.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Primitives, Version=9.0.0.7, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.Primitives.9.0.7\lib\net462\Microsoft.Extensions.Primitives.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Identity.Client, Version=4.74.1.0, Culture=neutral, PublicKeyToken=0a613f4dd989e8ae, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Identity.Client.4.74.1\lib\net472\Microsoft.Identity.Client.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Identity.Client.Extensions.Msal, Version=4.74.1.0, Culture=neutral, PublicKeyToken=0a613f4dd989e8ae, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Identity.Client.Extensions.Msal.4.74.1\lib\netstandard2.0\Microsoft.Identity.Client.Extensions.Msal.dll</HintPath>
</Reference>
<Reference Include="Microsoft.IdentityModel.Abstractions, Version=8.13.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.IdentityModel.Abstractions.8.13.0\lib\net472\Microsoft.IdentityModel.Abstractions.dll</HintPath>
</Reference>
<Reference Include="Microsoft.IdentityModel.JsonWebTokens, Version=8.13.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.IdentityModel.JsonWebTokens.8.13.0\lib\net472\Microsoft.IdentityModel.JsonWebTokens.dll</HintPath>
</Reference>
<Reference Include="Microsoft.IdentityModel.Logging, Version=8.13.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.IdentityModel.Logging.8.13.0\lib\net472\Microsoft.IdentityModel.Logging.dll</HintPath>
</Reference>
<Reference Include="Microsoft.IdentityModel.Protocols, Version=8.13.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.IdentityModel.Protocols.8.13.0\lib\net472\Microsoft.IdentityModel.Protocols.dll</HintPath>
</Reference>
<Reference Include="Microsoft.IdentityModel.Protocols.OpenIdConnect, Version=8.13.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.IdentityModel.Protocols.OpenIdConnect.8.13.0\lib\net472\Microsoft.IdentityModel.Protocols.OpenIdConnect.dll</HintPath>
</Reference>
<Reference Include="Microsoft.IdentityModel.Tokens, Version=8.13.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.IdentityModel.Tokens.8.13.0\lib\net472\Microsoft.IdentityModel.Tokens.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Web.Infrastructure, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Web.Infrastructure.2.0.0\lib\net40\Microsoft.Web.Infrastructure.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json.Bson, Version=1.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.Bson.1.0.3\lib\net45\Newtonsoft.Json.Bson.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Buffers, Version=4.0.5.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Buffers.4.6.1\lib\net462\System.Buffers.dll</HintPath>
</Reference>
<Reference Include="System.ClientModel, Version=1.5.1.0, Culture=neutral, PublicKeyToken=92742159e12e44c8, processorArchitecture=MSIL">
<HintPath>..\packages\System.ClientModel.1.5.1\lib\netstandard2.0\System.ClientModel.dll</HintPath>
</Reference>
<Reference Include="System.Configuration.ConfigurationManager, Version=9.0.0.7, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Configuration.ConfigurationManager.9.0.7\lib\net462\System.Configuration.ConfigurationManager.dll</HintPath>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Data.Common, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Data.Common.4.3.0\lib\net451\System.Data.Common.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Data.OracleClient" />
<Reference Include="System.Diagnostics.DiagnosticSource, Version=9.0.0.7, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Diagnostics.DiagnosticSource.9.0.7\lib\net462\System.Diagnostics.DiagnosticSource.dll</HintPath>
</Reference>
<Reference Include="System.DirectoryServices" />
<Reference Include="System.Drawing" />
<Reference Include="System.Formats.Asn1, Version=9.0.0.7, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Formats.Asn1.9.0.7\lib\net462\System.Formats.Asn1.dll</HintPath>
</Reference>
<Reference Include="System.IdentityModel" />
<Reference Include="System.IdentityModel.Tokens.Jwt, Version=8.13.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\System.IdentityModel.Tokens.Jwt.8.13.0\lib\net472\System.IdentityModel.Tokens.Jwt.dll</HintPath>
</Reference>
<Reference Include="System.IO.FileSystem.AccessControl, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.IO.FileSystem.AccessControl.5.0.0\lib\net461\System.IO.FileSystem.AccessControl.dll</HintPath>
</Reference>
<Reference Include="System.IO.Pipelines, Version=9.0.0.7, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.IO.Pipelines.9.0.7\lib\net462\System.IO.Pipelines.dll</HintPath>
</Reference>
<Reference Include="System.Memory, Version=4.0.5.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Memory.4.6.3\lib\net462\System.Memory.dll</HintPath>
</Reference>
<Reference Include="System.Memory.Data, Version=9.0.0.7, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Memory.Data.9.0.7\lib\net462\System.Memory.Data.dll</HintPath>
</Reference>
<Reference Include="System.Net" />
<Reference Include="System.Net.Http.Formatting, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Client.6.0.0\lib\net45\System.Net.Http.Formatting.dll</HintPath>
</Reference>
<Reference Include="System.Numerics" />
<Reference Include="System.Numerics.Vectors, Version=4.1.6.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Numerics.Vectors.4.6.1\lib\net462\System.Numerics.Vectors.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=6.0.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.6.1.2\lib\net462\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.InteropServices.RuntimeInformation, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Security" />
<Reference Include="System.Security.AccessControl, Version=6.0.0.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Security.AccessControl.6.0.1\lib\net461\System.Security.AccessControl.dll</HintPath>
</Reference>
<Reference Include="System.Security.Cryptography.Pkcs, Version=9.0.0.7, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Security.Cryptography.Pkcs.9.0.7\lib\net462\System.Security.Cryptography.Pkcs.dll</HintPath>
</Reference>
<Reference Include="System.Security.Cryptography.ProtectedData, Version=9.0.0.7, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Security.Cryptography.ProtectedData.9.0.7\lib\net462\System.Security.Cryptography.ProtectedData.dll</HintPath>
</Reference>
<Reference Include="System.Security.Permissions, Version=9.0.0.7, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Security.Permissions.9.0.7\lib\net462\System.Security.Permissions.dll</HintPath>
</Reference>
<Reference Include="System.Security.Principal.Windows, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Security.Principal.Windows.5.0.0\lib\net461\System.Security.Principal.Windows.dll</HintPath>
</Reference>
<Reference Include="System.ServiceProcess" />
<Reference Include="System.Text.Encodings.Web, Version=9.0.0.7, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Text.Encodings.Web.9.0.7\lib\net462\System.Text.Encodings.Web.dll</HintPath>
</Reference>
<Reference Include="System.Text.Json, Version=9.0.0.7, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Text.Json.9.0.7\lib\net462\System.Text.Json.dll</HintPath>
</Reference>
<Reference Include="System.Threading.Tasks.Extensions, Version=4.2.4.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Threading.Tasks.Extensions.4.6.3\lib\net462\System.Threading.Tasks.Extensions.dll</HintPath>
</Reference>
<Reference Include="System.Transactions" />
<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.Helpers, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.3.0\lib\net45\System.Web.Helpers.dll</HintPath>
</Reference>
<Reference Include="System.Web.Http, Version=5.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Core.5.3.0\lib\net45\System.Web.Http.dll</HintPath>
</Reference>
<Reference Include="System.Web.Http.WebHost, Version=5.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.WebHost.5.3.0\lib\net45\System.Web.Http.WebHost.dll</HintPath>
</Reference>
<Reference Include="System.Web.Mvc, Version=5.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.Mvc.5.3.0\lib\net45\System.Web.Mvc.dll</HintPath>
</Reference>
<Reference Include="System.Web.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.Razor.3.3.0\lib\net45\System.Web.Razor.dll</HintPath>
</Reference>
<Reference Include="System.Web.WebPages, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.3.0\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">
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.3.0\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">
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.3.0\lib\net45\System.Web.WebPages.Razor.dll</HintPath>
</Reference>
<Reference Include="System.Windows.Forms" />
<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="System.Net.Http">
</Reference>
<Reference Include="System.Net.Http.WebRequest">
</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="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>
<Reference Include="WindowsBase" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\Common Code\Security\C4IT.Security.OneTimePw.cs">
<Link>Common\C4IT.Security.OneTimePw.cs</Link>
</Compile>
<Compile Include="..\CommonAssemblyInfo.cs">
<Link>Properties\CommonAssemblyInfo.cs</Link>
</Compile>
<Compile Include="ActionFilters\CheckCollectorFilter.cs" />
<Compile Include="ActionFilters\CheckLicenceFilter.cs" />
<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="Authentication.cs" />
<Compile Include="Controllers\GetDetailsDataController.cs" />
<Compile Include="Controllers\CheckConnectionController.cs" />
<Compile Include="Controllers\GetAgentApiConfigurationController.cs" />
<Compile Include="Controllers\GetConfigurationController.cs" />
<Compile Include="Controllers\GetRawDataController.cs" />
<Compile Include="Controllers\GetSelectionDataController.cs" />
<Compile Include="Controllers\HomeController.cs" />
<Compile Include="Controllers\QuickActionDataController.cs" />
<Compile Include="Controllers\LogonController.cs" />
<Compile Include="Controllers\Matrix42\Matrix42TicketFinalization.cs" />
<Compile Include="Controllers\SearchDefault.cs" />
<Compile Include="Controllers\F4SDAnalyticsDataController.cs" />
<Compile Include="Controllers\StagedSearchRelationController.cs" />
<Compile Include="Controllers\UsageController.cs" />
<Compile Include="Controllers\WritePropertyController.cs" />
<Compile Include="Global.asax.cs">
<DependentUpon>Global.asax</DependentUpon>
</Compile>
<Compile Include="Info.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="..\C4IT_DataHistoryProvider_Test\DataHistorySql.xml">
<Link>DataHistorySql.xml</Link>
</EmbeddedResource>
<Content Include="..\..\C4IT FASD\_Common\MediaContent\F4SD-Intro-001.mov">
<Link>MediaContent\F4SD-Intro-001.mov</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="..\C4IT_DataHistoryProvider_Test\Config\F4SD-CopyTemplate-Configuration.xml">
<Link>Config\F4SD-CopyTemplate-Configuration.xml</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="..\C4IT_DataHistoryProvider_Test\Config\F4SD-DataClusters-Configuration.xml">
<Link>Config\F4SD-DataClusters-Configuration.xml</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="..\C4IT_DataHistoryProvider_Test\Config\F4SD-Global-Configuration.xml">
<Link>Config\F4SD-Global-Configuration.xml</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="..\C4IT_DataHistoryProvider_Test\Config\F4SD-HealthCard-Configuration.xml">
<Link>Config\F4SD-HealthCard-Configuration.xml</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="..\C4IT_DataHistoryProvider_Test\Config\F4SD-Icon-Configuration.xml">
<Link>Config\F4SD-Icon-Configuration.xml</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="..\C4IT_DataHistoryProvider_Test\Config\F4SD-Infrastructure-Configuration.xml">
<Link>Config\F4SD-Infrastructure-Configuration.xml</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="..\C4IT_DataHistoryProvider_Test\Config\F4SD-MenuSection-Configuration.xml">
<Link>Config\F4SD-MenuSection-Configuration.xml</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="..\C4IT_DataHistoryProvider_Test\Config\F4SD-QuickAction-Configuration.xml">
<Link>Config\F4SD-QuickAction-Configuration.xml</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="..\C4IT_DataHistoryProvider_Test\License\F4SD_License.xml">
<Link>License\F4SD_License.xml</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Areas\HelpPage\HelpPage.css" />
<Content Include="Areas\HelpPage\logo_FASD_48x48.png" />
<Content Include="Content\bootstrap-grid.css" />
<Content Include="Content\bootstrap-grid.min.css" />
<Content Include="Content\bootstrap-reboot.css" />
<Content Include="Content\bootstrap-reboot.min.css" />
<Content Include="Content\bootstrap.css" />
<Content Include="Content\bootstrap.min.css" />
<Content Include="favicon.ico" />
<Content Include="Global.asax" />
<Content Include="Scripts\bootstrap.bundle.js" />
<Content Include="Scripts\bootstrap.bundle.min.js" />
<Content Include="Scripts\bootstrap.js" />
<Content Include="Scripts\bootstrap.min.js" />
<Content Include="Scripts\esm\popper-utils.js" />
<Content Include="Scripts\esm\popper-utils.min.js" />
<Content Include="Scripts\esm\popper.js" />
<Content Include="Scripts\esm\popper.min.js" />
<Content Include="Scripts\index.js.flow" />
<Content Include="Scripts\esm\popper.min.js.map" />
<Content Include="Scripts\esm\popper.js.map" />
<Content Include="Scripts\esm\popper-utils.min.js.map" />
<Content Include="Scripts\esm\popper-utils.js.map" />
<EmbeddedResource Include="..\..\C4IT FASD\_Common\XmlSchemas\LanguageDefinitions.xsd">
<Link>Config\LanguageDefinitions.xsd</Link>
<SubType>Designer</SubType>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="..\..\C4IT FASD\_Common\XmlSchemas\F4SD-CopyTemplate-Configuration.xsd">
<Link>Config\F4SD-CopyTemplate-Configuration.xsd</Link>
<SubType>Designer</SubType>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="..\..\C4IT FASD\_Common\XmlSchemas\F4SD-HealthCard-Configuration.xsd">
<Link>Config\F4SD-HealthCard-Configuration.xsd</Link>
<SubType>Designer</SubType>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="..\..\C4IT FASD\_Common\XmlSchemas\F4SD-Icon-Configuration.xsd">
<Link>Config\F4SD-Icon-Configuration.xsd</Link>
<SubType>Designer</SubType>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="..\..\C4IT FASD\_Common\XmlSchemas\F4SD-MenuSection-Configuration.xsd">
<Link>Config\F4SD-MenuSection-Configuration.xsd</Link>
<SubType>Designer</SubType>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="..\..\C4IT FASD\_Common\XmlSchemas\F4SD-QuickAction-Configuration.xsd">
<Link>Config\F4SD-QuickAction-Configuration.xsd</Link>
<SubType>Designer</SubType>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="..\C4IT_DataHistoryProvider_Test\Config\F4SD-DataClusters-Configuration.xsd">
<Link>Config\F4SD-DataClusters-Configuration.xsd</Link>
<SubType>Designer</SubType>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="..\C4IT_DataHistoryProvider_Test\Config\F4SD-Infrastructure-Configuration.xsd">
<Link>Config\F4SD-Infrastructure-Configuration.xsd</Link>
<SubType>Designer</SubType>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</EmbeddedResource>
<Content Include="Areas\HelpPage\Views\Help\Index.cshtml" />
<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\DisplayTemplates\TextSample.cshtml" />
<Content Include="Areas\HelpPage\Views\Help\DisplayTemplates\SimpleTypeModelDescription.cshtml" />
<Content Include="Areas\HelpPage\Views\Help\DisplayTemplates\Samples.cshtml" />
<Content Include="Areas\HelpPage\Views\Help\DisplayTemplates\Parameters.cshtml" />
<Content Include="Areas\HelpPage\Views\Help\DisplayTemplates\ModelDescriptionLink.cshtml" />
<Content Include="Areas\HelpPage\Views\Help\DisplayTemplates\KeyValuePairModelDescription.cshtml" />
<Content Include="Areas\HelpPage\Views\Help\DisplayTemplates\InvalidSample.cshtml" />
<Content Include="Areas\HelpPage\Views\Help\DisplayTemplates\ImageSample.cshtml" />
<Content Include="Areas\HelpPage\Views\Help\DisplayTemplates\HelpPageApiModel.cshtml" />
<Content Include="Areas\HelpPage\Views\Help\DisplayTemplates\EnumTypeModelDescription.cshtml" />
<Content Include="Areas\HelpPage\Views\Help\DisplayTemplates\DictionaryModelDescription.cshtml" />
<Content Include="Areas\HelpPage\Views\Help\DisplayTemplates\ComplexTypeModelDescription.cshtml" />
<Content Include="Areas\HelpPage\Views\Help\DisplayTemplates\CollectionModelDescription.cshtml" />
<Content Include="Areas\HelpPage\Views\Help\DisplayTemplates\ApiGroup.cshtml" />
<Content Include="Areas\HelpPage\Views\Help\Api.cshtml" />
<Content Include="Scripts\bootstrap.min.js.map" />
<Content Include="Scripts\bootstrap.js.map" />
<Content Include="Scripts\bootstrap.bundle.min.js.map" />
<Content Include="Scripts\bootstrap.bundle.js.map" />
<Content Include="Content\bootstrap.min.css.map" />
<Content Include="Content\bootstrap.css.map" />
<Content Include="Content\bootstrap-reboot.min.css.map" />
<Content Include="Content\bootstrap-reboot.css.map" />
<Content Include="Content\bootstrap-grid.min.css.map" />
<Content Include="Content\bootstrap-grid.css.map" />
<EmbeddedResource Include="..\C4IT_DataHistoryProvider_Test\Config\F4SD-Global-Configuration.xsd">
<Link>Config\F4SD-Global-Configuration.xsd</Link>
<SubType>Designer</SubType>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</EmbeddedResource>
<None Include="Scripts\jquery-3.7.1.intellisense.js" />
<Content Include="Scripts\jquery-3.7.1.js" />
<Content Include="Scripts\jquery-3.7.1.min.js" />
<Content Include="Scripts\jquery-3.7.1.slim.js" />
<Content Include="Scripts\jquery-3.7.1.slim.min.js" />
<Content Include="Scripts\modernizr-2.8.3.js" />
<Content Include="Scripts\popper-utils.js" />
<Content Include="Scripts\popper-utils.min.js" />
<Content Include="Scripts\popper.js" />
<Content Include="Scripts\popper.min.js" />
<Content Include="Scripts\src\index.js" />
<Content Include="Scripts\src\methods\defaults.js" />
<Content Include="Scripts\src\methods\destroy.js" />
<Content Include="Scripts\src\methods\disableEventListeners.js" />
<Content Include="Scripts\src\methods\enableEventListeners.js" />
<Content Include="Scripts\src\methods\placements.js" />
<Content Include="Scripts\src\methods\update.js" />
<Content Include="Scripts\src\modifiers\applyStyle.js" />
<Content Include="Scripts\src\modifiers\arrow.js" />
<Content Include="Scripts\src\modifiers\computeStyle.js" />
<Content Include="Scripts\src\modifiers\flip.js" />
<Content Include="Scripts\src\modifiers\hide.js" />
<Content Include="Scripts\src\modifiers\index.js" />
<Content Include="Scripts\src\modifiers\inner.js" />
<Content Include="Scripts\src\modifiers\keepTogether.js" />
<Content Include="Scripts\src\modifiers\offset.js" />
<Content Include="Scripts\src\modifiers\preventOverflow.js" />
<Content Include="Scripts\src\modifiers\shift.js" />
<Content Include="Scripts\src\utils\clockwise.js" />
<Content Include="Scripts\src\utils\computeAutoPlacement.js" />
<Content Include="Scripts\src\utils\debounce.js" />
<Content Include="Scripts\src\utils\find.js" />
<Content Include="Scripts\src\utils\findCommonOffsetParent.js" />
<Content Include="Scripts\src\utils\findIndex.js" />
<Content Include="Scripts\src\utils\getBordersSize.js" />
<Content Include="Scripts\src\utils\getBoundaries.js" />
<Content Include="Scripts\src\utils\getBoundingClientRect.js" />
<Content Include="Scripts\src\utils\getClientRect.js" />
<Content Include="Scripts\src\utils\getFixedPositionOffsetParent.js" />
<Content Include="Scripts\src\utils\getOffsetParent.js" />
<Content Include="Scripts\src\utils\getOffsetRect.js" />
<Content Include="Scripts\src\utils\getOffsetRectRelativeToArbitraryNode.js" />
<Content Include="Scripts\src\utils\getOppositePlacement.js" />
<Content Include="Scripts\src\utils\getOppositeVariation.js" />
<Content Include="Scripts\src\utils\getOuterSizes.js" />
<Content Include="Scripts\src\utils\getParentNode.js" />
<Content Include="Scripts\src\utils\getPopperOffsets.js" />
<Content Include="Scripts\src\utils\getReferenceNode.js" />
<Content Include="Scripts\src\utils\getReferenceOffsets.js" />
<Content Include="Scripts\src\utils\getRoot.js" />
<Content Include="Scripts\src\utils\getRoundedOffsets.js" />
<Content Include="Scripts\src\utils\getScroll.js" />
<Content Include="Scripts\src\utils\getScrollParent.js" />
<Content Include="Scripts\src\utils\getStyleComputedProperty.js" />
<Content Include="Scripts\src\utils\getSupportedPropertyName.js" />
<Content Include="Scripts\src\utils\getViewportOffsetRectRelativeToArtbitraryNode.js" />
<Content Include="Scripts\src\utils\getWindow.js" />
<Content Include="Scripts\src\utils\getWindowSizes.js" />
<Content Include="Scripts\src\utils\includeScroll.js" />
<Content Include="Scripts\src\utils\index.js" />
<Content Include="Scripts\src\utils\isBrowser.js" />
<Content Include="Scripts\src\utils\isFixed.js" />
<Content Include="Scripts\src\utils\isFunction.js" />
<Content Include="Scripts\src\utils\isIE.js" />
<Content Include="Scripts\src\utils\isModifierEnabled.js" />
<Content Include="Scripts\src\utils\isModifierRequired.js" />
<Content Include="Scripts\src\utils\isNumeric.js" />
<Content Include="Scripts\src\utils\isOffsetContainer.js" />
<Content Include="Scripts\src\utils\removeEventListeners.js" />
<Content Include="Scripts\src\utils\runModifiers.js" />
<Content Include="Scripts\src\utils\setAttributes.js" />
<Content Include="Scripts\src\utils\setStyles.js" />
<Content Include="Scripts\src\utils\setupEventListeners.js" />
<Content Include="Scripts\umd\popper-utils.js" />
<Content Include="Scripts\umd\popper-utils.min.js" />
<Content Include="Scripts\umd\popper.js" />
<Content Include="Scripts\umd\popper.min.js" />
<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="Scripts\umd\popper.min.js.map" />
<Content Include="Scripts\umd\popper.js.map" />
<Content Include="Scripts\umd\popper.js.flow" />
<Content Include="Scripts\umd\popper-utils.min.js.map" />
<Content Include="Scripts\umd\popper-utils.js.map" />
<Content Include="Scripts\README.md" />
<Content Include="Scripts\popper.min.js.map" />
<Content Include="Scripts\popper.js.map" />
<Content Include="Scripts\popper-utils.min.js.map" />
<Content Include="Scripts\popper-utils.js.map" />
<Content Include="Web.config" />
<None Include="Web.Debug-Demo.config">
<DependentUpon>Web.config</DependentUpon>
</None>
<None Include="Web.Debug.config">
<DependentUpon>Web.config</DependentUpon>
</None>
<None Include="Web.Release-Demo.config">
<DependentUpon>Web.config</DependentUpon>
</None>
<None Include="Web.Release.config">
<DependentUpon>Web.config</DependentUpon>
</None>
</ItemGroup>
<ItemGroup>
<Folder Include="App_Data\" />
<Folder Include="Models\" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
<Content Include="Scripts\jquery-3.7.1.slim.min.map" />
<Content Include="Scripts\jquery-3.7.1.min.map" />
</ItemGroup>
<ItemGroup>
<TypeScriptCompile Include="Scripts\index.d.ts" />
</ItemGroup>
<ItemGroup>
<Service Include="{4A0DDDB5-7A95-4FBF-97CC-616D07737A77}" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\C4IT_DataHistoryProvider_Base\F4SD-Cockpit-Server.csproj">
<Project>{49452fc2-05ce-4077-8b40-8adf5eca212e}</Project>
<Name>F4SD-Cockpit-Server</Name>
</ProjectReference>
</ItemGroup>
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<PropertyGroup>
<RoslynToolsDestinationFolder>$(OutputPath)\roslyn</RoslynToolsDestinationFolder>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release-Demo|AnyCPU'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\</OutputPath>
<DefineConstants>TRACE;DEMOLICENSE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug-Demo|AnyCPU'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\</OutputPath>
<DefineConstants>TRACE;DEBUG;DEMOLICENSE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TypeScript\Microsoft.TypeScript.targets" Condition="Exists('$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TypeScript\Microsoft.TypeScript.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>61309</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>https://localhost:44307</IISUrl>
<NTLMAuthentication>False</NTLMAuthentication>
<UseCustomServer>False</UseCustomServer>
<CustomServerUrl>
</CustomServerUrl>
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
</WebProjectProperties>
</FlavorProperties>
</VisualStudio>
</ProjectExtensions>
<Import Project="packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.3.6.0\build\net472\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.targets" Condition="Exists('packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.3.6.0\build\net472\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.targets')" />
<Target Name="AfterBuild">
<Message Text="Start to publish website" Importance="high" />
<RemoveDir Directories=".\Publish\bin" ContinueOnError="true" />
<MSBuild Projects=".\$(ProjectFileName)" Targets="ResolveReferences;_CopyWebApplication" Properties="OutDir=.\Publish;WebProjectOutputDir=.\Publish;Configuration=$(Configuration);Platform=$(Platform)" />
<Exec Command="cmd.exe /C md &quot;$(ProjectDir)\Publish\bin\roslyn&quot;" ContinueOnError="false" WorkingDirectory="." />
<Exec Command="xcopy.exe /S &quot;$(RoslynToolsDestinationFolder)\*&quot; &quot;$(ProjectDir)\Publish\bin\roslyn&quot;" ContinueOnError="false" WorkingDirectory="." />
<Exec Command="xcopy.exe /Y /S &quot;$(ProjectDir)..\C4IT_DataHistoryProvider_Test\bin\$(Configuration)\config\F4SD*.xsd&quot; &quot;$(ProjectDir)\Publish\config&quot;" ContinueOnError="false" WorkingDirectory="." />
<Exec Command="xcopy.exe /Y /S &quot;$(ProjectDir)..\C4IT_DataHistoryProvider_Test\bin\$(Configuration)\*.exe&quot; &quot;$(ProjectDir)\Publish\bin&quot;" ContinueOnError="false" WorkingDirectory="." />
<Exec Command="xcopy.exe /Y /S &quot;$(ProjectDir)..\C4IT_DataHistoryProvider_Test\bin\$(Configuration)\*.exe.config&quot; &quot;$(ProjectDir)\Publish\bin&quot;" ContinueOnError="false" WorkingDirectory="." />
<Exec Command="xcopy.exe /Y /S &quot;$(ProjectDir)..\C4IT_DataHistoryProvider_Test\bin\$(Configuration)\*.dll&quot; &quot;$(ProjectDir)\Publish\bin&quot;" ContinueOnError="false" WorkingDirectory="." />
</Target>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.3.6.0\build\net472\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.3.6.0\build\net472\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.targets'))" />
<Error Condition="!Exists('..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.4.1.0\build\net472\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.4.1.0\build\net472\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.targets'))" />
<Error Condition="!Exists('..\packages\Microsoft.Data.SqlClient.SNI.6.0.2\build\net462\Microsoft.Data.SqlClient.SNI.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Data.SqlClient.SNI.6.0.2\build\net462\Microsoft.Data.SqlClient.SNI.targets'))" />
<Error Condition="!Exists('..\packages\System.ValueTuple.4.6.1\build\net471\System.ValueTuple.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\System.ValueTuple.4.6.1\build\net471\System.ValueTuple.targets'))" />
</Target>
<PropertyGroup>
<PreBuildEvent>
copy "$(ProjectDir)..\..\C4IT FASD\_Common\XmlSchemas\*" "$(ProjectDir)Config"
copy "$(ProjectDir)..\C4IT_DataHistoryProvider_Test\Config\*.xml" "$(ProjectDir)Config"
copy "$(ProjectDir)..\C4IT_DataHistoryProvider_Test\License\*" "$(ProjectDir)License"
</PreBuildEvent>
<!--<PreBuildEvent>copy "$(ProjectDir)..\C4IT_DataHistoryProvider_Test\Config\*" "$(ProjectDir)Config"</PreBuildEvent>-->
</PropertyGroup>
<Import Project="..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.4.1.0\build\net472\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.targets" Condition="Exists('..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.4.1.0\build\net472\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.targets')" />
<Import Project="..\packages\Microsoft.Data.SqlClient.SNI.6.0.2\build\net462\Microsoft.Data.SqlClient.SNI.targets" Condition="Exists('..\packages\Microsoft.Data.SqlClient.SNI.6.0.2\build\net462\Microsoft.Data.SqlClient.SNI.targets')" />
<Import Project="..\packages\System.ValueTuple.4.6.1\build\net471\System.ValueTuple.targets" Condition="Exists('..\packages\System.ValueTuple.4.6.1\build\net471\System.ValueTuple.targets')" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target> -->
</Project>

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