Merge branch 'UnbrokenSQLiteImplementation' into 'master'

merge work for version 0.1

See merge request !2
This commit is contained in:
Chris Watts 2017-02-20 14:12:31 +00:00
commit 8f24fca75a
132 changed files with 21424 additions and 157 deletions

3
.gitignore vendored
View File

@ -3,3 +3,6 @@
**/packages/*
**/.vs/*
**/.localhistory/*
**/node_modules/*
**csproj.DotSettings
**.csproj.user

View File

@ -13,7 +13,6 @@ using Newtonsoft.Json;
using Windows.Foundation;
using Devkoes.Restup.WebServer.File;
using Microsoft.Practices.Unity;
using Interfaces;
namespace WebSocketService
{

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
<appSettings>
<add key="DataCenterServiceEndpoint" value="http://localhost:1234"/>
</appSettings>
</configuration>

View File

@ -0,0 +1,37 @@
namespace CardReaderService
{
partial class CardReaderService
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
this.ServiceName = "Service1";
}
#endregion
}
}

View File

@ -0,0 +1,173 @@
using PCSC;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading;
using Interfaces;
namespace CardReaderService
{
public partial class CardReaderService : ServiceBase
{
private Thread _mainWorkThread;
private bool _stopMainWorkerThread;
private string _readerName = "";
private SCardMonitor _cardMonitor;
private ILogger _logger;
public CardReaderService()
{
InitializeComponent();
}
public void Start()
{
OnStart(new string[] {});
}
protected override void OnStart(string[] args)
{
_logger = NinjectHelper.GetInstance().Get<ILogger>();
_logger.Trace("Starting Service.. Getting available readers");
var ctxFactory = ContextFactory.Instance;
using(var context = ctxFactory.Establish(SCardScope.System))
{
var readerNames = context.GetReaders();
if (NoReaderAvailable(readerNames))
{
_logger.Trace("No Card Reader is available, Exiting..");
throw new ApplicationException("A card reader must be provided in order to operate.");
}
foreach (var reader in readerNames)
{
_logger.Trace("Found reader: {0}", reader);
}
var readerNameConfig = ConfigurationManager.AppSettings["ReaderName"];
if (string.IsNullOrEmpty(readerNameConfig))
{
if (!readerNames.Contains(readerNameConfig))
{
_logger.Warn("No reader found with the name: {0}, defaulting to first available reader {1}",
readerNameConfig, readerNames.First());
readerNameConfig=readerNames.First();
}
}
_logger.Trace("Choosing reader: {0}", readerNameConfig);
_readerName = readerNameConfig;
_cardMonitor = new SCardMonitor(ctxFactory, SCardScope.System);
_cardMonitor.CardInserted += _cardMonitor_CardInserted;
_cardMonitor.Start(_readerName);
StartWorkerThread();
}
}
public void StopService()
{
OnStop();
}
protected override void OnStop()
{
_stopMainWorkerThread = true;
if (_mainWorkThread!= null && _mainWorkThread.IsAlive)
{
_mainWorkThread.Join(3000);
if (_mainWorkThread.IsAlive)
{
_mainWorkThread.Interrupt();
}
}
if (_cardMonitor == null) return;
_cardMonitor.Cancel();
_cardMonitor.Dispose();
_cardMonitor = null;
}
private void StartWorkerThread()
{
_stopMainWorkerThread = false;
_mainWorkThread = new Thread(MainWorkerThread)
{
Name = "CardServiceMainThread",
IsBackground = false
};
_mainWorkThread.Start();
}
private void _cardMonitor_CardInserted(object sender, CardStatusEventArgs e)
{
var ctxFac = ContextFactory.Instance;
using (var ctx = ctxFac.Establish(SCardScope.System))
{
var reader = new SCardReader(ctx);
var pioSendPci = new IntPtr();
var rcvBuffer = new byte[256];
if (_readerName == string.Empty)
{
_logger.Fatal("Reader name is somehow empty...exiting");
_stopMainWorkerThread = true;
return;
}
var err = reader.Connect(_readerName, SCardShareMode.Shared, SCardProtocol.T0 | SCardProtocol.T1);
if (err == SCardError.Success)
{
var uIdcmd = new byte[] { 0xFF, 0xCA, 0x00, 0x00, 0x00 };
err = reader.Transmit(pioSendPci, uIdcmd, ref rcvBuffer);
if (err != SCardError.Success) return;
var uid = ConvertByteUIDToString(rcvBuffer);
var atrString = ConvertByteUIDToString(e.Atr);
_logger.Trace("Card Inserted, ATR: " + atrString + ", and UID is: " + uid);
var postObj = new CardDataPost {CardUId = uid};
DataCenterHelper.PostAsync(postObj, "/api/swipedata");
_logger.Trace("Posted to Server");
}
else
{
_logger.Trace("Reader failed to connect, error: " + Enum.GetName(typeof(SCardError), err));
}
}
}
private void MainWorkerThread()
{
while (!_stopMainWorkerThread)
{
//dont actually need to do anything.. but cannot exit right away?
Thread.Sleep(3000);
}
}
private string ConvertByteUIDToString(byte[] uid)
{
var sb = new StringBuilder();
foreach(var b in uid)
{
sb.AppendFormat("{0:X2}", b);
}
return sb.ToString();
}
private bool NoReaderAvailable(ICollection<string> readerNames)
{
return readerNames == null || readerNames.Count < 1;
}
}
}

View File

@ -0,0 +1,97 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{5F30E8E4-5107-4C99-ADFF-38D735DC113D}</ProjectGuid>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>CardReaderService</RootNamespace>
<AssemblyName>CardReaderService</AssemblyName>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Ninject, Version=3.2.0.0, Culture=neutral, PublicKeyToken=c7192dc5380945e7, processorArchitecture=MSIL">
<HintPath>..\packages\Ninject.3.2.2.0\lib\net45-full\Ninject.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="pcsc-sharp, Version=3.6.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\PCSC.3.6.0\lib\net40\pcsc-sharp.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.ServiceProcess" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Configuration.cs" />
<Compile Include="ConfigureService.cs" />
<Compile Include="DataCenterHelper.cs" />
<Compile Include="DefaultComponents\DefaultLogger.cs" />
<Compile Include="NinjectHelper.cs" />
<Compile Include="CardReaderService.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="CardReaderService.Designer.cs">
<DependentUpon>CardReaderService.cs</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Interfaces\Interfaces.csproj">
<Project>{B7347B72-E208-423A-9D99-723B558EA3D7}</Project>
<Name>Interfaces</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Content Include="NinjectConfig.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -0,0 +1,35 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using CardReaderService.DefaultComponents;
using Interfaces;
using Ninject;
namespace CardReaderService
{
public static class Configuration
{
public static StandardKernel ConfigureNinject()
{
var kernel = new StandardKernel();
var ninjectConfigPath =
new Uri(Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().CodeBase), "NinjectConfig.xml"))
.LocalPath;
if (File.Exists(ninjectConfigPath))
{
kernel.Load(ninjectConfigPath);
}
var logger = kernel.TryGet<ILogger>();
if (logger == null)
{
kernel.Bind<ILogger>().To<DefaultLogger>();
logger = kernel.Get<ILogger>();
}
logger.Fatal("test message - ninject stuff loaded.");
return kernel;
}
}
}

View File

@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CardReaderService
{
internal static class ConfigureService
{
internal static void Configure()
{
//try
//{
// HostFactory.Run(configure =>
// {
// configure.Service<Service1>(service =>
// {
// service.ConstructUsing(s => new Service1());
// service.WhenStarted(s => s.Start());
// service.WhenStopped(s => s.Stop());
// });
// //Setup Account that window service use to run.
// configure.RunAsLocalSystem();
// configure.SetServiceName("MyWindowServiceWithTopshelf");
// configure.SetDisplayName("MyWindowServiceWithTopshelf");
// configure.SetDescription("My .Net windows service with Topshelf");
// });
//}
//catch (Exception ex)
//{
// throw;
//}
}
}
}

View File

@ -0,0 +1,48 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace CardReaderService
{
static class DataCenterHelper
{
public static void Post(CardDataPost postObject, string url)
{
var endpointConfig = ConfigurationManager.AppSettings["DataCenterServiceEndpoint"] ??
"http://localhost:8800";
using (var client = new HttpClient())
{
var jsonObject = JsonConvert.SerializeObject(postObject);
var content = new StringContent(jsonObject, Encoding.UTF8, "application/json");
try
{
Console.WriteLine("Writing");
var fullUrl = endpointConfig + url;
var response = client.PostAsync(fullUrl, content).Result;
Console.WriteLine("Written");
}
catch (Exception)
{
Console.WriteLine("exceptioning");
//ignore
}
}
}
public static Task PostAsync(CardDataPost postObject, string url)
{
return Task.Run(() => Post(postObject, url));
}
}
public class CardDataPost
{
public string CardUId { get; set; }
}
}

View File

@ -0,0 +1,151 @@
using System;
using System.Diagnostics;
using Interfaces;
namespace CardReaderService.DefaultComponents
{
public class DefaultLogger : ILogger
{
private string _eventLogSource = "CardReaderDefaultLogger";
private string _logName = "CardReaderService";
private EventLog _eventLog;
public DefaultLogger()
{
if (!EventLog.SourceExists(_eventLogSource))
{
EventLog.CreateEventSource(_eventLogSource, _logName);
}
}
public bool IsDebugEnabled { get { return true; } }
public bool IsErrorEnabled { get { return true; } }
public bool IsFatalEnabled { get { return true; } }
public bool IsInfoEnabled { get { return true; } }
public bool IsTraceEnabled { get { return true; } }
public bool IsWarnEnabled { get { return true; } }
public void Debug(Exception exception)
{
CheckEventLog();
_eventLog.WriteEntry(exception.ToString(), EventLogEntryType.Information);
}
public void Debug(string format, params object[] args)
{
CheckEventLog();
_eventLog.WriteEntry(string.Format(format, args), EventLogEntryType.Information);
}
public void Debug(Exception exception, string format, params object[] args)
{
CheckEventLog();
_eventLog.WriteEntry(string.Format(exception + ", " + format, args),
EventLogEntryType.Information);
}
public void Error(Exception exception)
{
CheckEventLog();
_eventLog.WriteEntry(exception.ToString(), EventLogEntryType.Error);
}
public void Error(string format, params object[] args)
{
CheckEventLog();
_eventLog.WriteEntry(string.Format(format, args), EventLogEntryType.Error);
}
public void Error(Exception exception, string format, params object[] args)
{
CheckEventLog();
_eventLog.WriteEntry(string.Format(exception + ", " + format, args),
EventLogEntryType.Error);
}
public void Fatal(Exception exception)
{
CheckEventLog();
_eventLog.WriteEntry(exception.ToString(), EventLogEntryType.Error);
}
public void Fatal(string format, params object[] args)
{
CheckEventLog();
_eventLog.WriteEntry(string.Format(format, args), EventLogEntryType.Error);
}
public void Fatal(Exception exception, string format, params object[] args)
{
CheckEventLog();
_eventLog.WriteEntry(string.Format(exception + ", " + format, args),
EventLogEntryType.Error);
}
public void Info(Exception exception)
{
CheckEventLog();
_eventLog.WriteEntry(exception.ToString(), EventLogEntryType.Information);
}
public void Info(string format, params object[] args)
{
CheckEventLog();
_eventLog.WriteEntry(string.Format(format, args), EventLogEntryType.Information);
}
public void Info(Exception exception, string format, params object[] args)
{
CheckEventLog();
_eventLog.WriteEntry(string.Format(exception + ", " + format, args),
EventLogEntryType.Information);
}
public void Trace(Exception exception)
{
CheckEventLog();
_eventLog.WriteEntry(exception.ToString(), EventLogEntryType.Information);
}
public void Trace(string format, params object[] args)
{
CheckEventLog();
_eventLog.WriteEntry(string.Format(format, args), EventLogEntryType.Information);
}
public void Trace(Exception exception, string format, params object[] args)
{
CheckEventLog();
_eventLog.WriteEntry(string.Format(exception + ", " + format, args),
EventLogEntryType.Information);
}
public void Warn(Exception exception)
{
CheckEventLog();
_eventLog.WriteEntry(exception.ToString(), EventLogEntryType.Warning);
}
public void Warn(string format, params object[] args)
{
CheckEventLog();
_eventLog.WriteEntry(string.Format(format, args), EventLogEntryType.Warning);
}
public void Warn(Exception exception, string format, params object[] args)
{
CheckEventLog();
_eventLog.WriteEntry(string.Format(exception + ", " + format, args),
EventLogEntryType.Warning);
}
private void CheckEventLog()
{
if (_eventLog == null)
{
_eventLog = new EventLog();
_eventLog.Source = _eventLogSource;
_eventLog.Log = _logName;
}
}
}
}

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8" ?>
<module name="NinjectAssemblies">
<bind service="Interfaces.ILogger, Interfaces"
to="NLogLogger.NLogger, NLogLogger" scope="singleton" />
</module>

View File

@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Ninject;
namespace CardReaderService
{
public class NinjectHelper
{
private static NinjectHelper _instance;
private static readonly object LockObject = new object();
public StandardKernel Kernel { get; private set; }
public static NinjectHelper GetInstance()
{
if (_instance != null)
return _instance;
lock (LockObject)
{
_instance = new NinjectHelper();
return _instance;
}
}
private NinjectHelper()
{
Kernel = Configuration.ConfigureNinject();
}
public T Get<T>()
{
return Kernel.Get<T>();
}
public IEnumerable<T> GetAll<T>()
{
return Kernel.GetAll<T>();
}
}
}

View File

@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Xsl;
namespace CardReaderService
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new CardReaderService()
};
ServiceBase.Run(ServicesToRun);
}
}
}

View File

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

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net452" />
<package id="Ninject" version="3.2.2.0" targetFramework="net452" />
<package id="PCSC" version="3.6.0" targetFramework="net452" />
</packages>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
</configuration>

View File

@ -0,0 +1,72 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{6E48913F-9D8C-4132-93A7-C7B1C6DD5264}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>CardReaderServiceHost</RootNamespace>
<AssemblyName>CardReaderServiceHost</AssemblyName>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\CardReaderService\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.ServiceProcess" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\CardReaderService\CardReaderService.csproj">
<Project>{5f30e8e4-5107-4c99-adff-38d735dc113d}</Project>
<Name>CardReaderService</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -0,0 +1,17 @@
using System;
using CardReaderService;
namespace CardReaderServiceHost
{
class Program
{
static void Main(string[] args)
{
CardReaderService.CardReaderService service1 = new CardReaderService.CardReaderService();
service1.Start();
Console.WriteLine("Service Running...");
Console.ReadLine();
service1.StopService();
}
}
}

View File

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

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net452" />
</packages>

View File

@ -0,0 +1,97 @@
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<Fragment>
<PropertyRef Id="STARTSERVICEONINSTALL"/>
<Component Id="CardReaderServiceStarter" Directory="INSTALLFOLDER"
Guid="{E37EA846-FF70-4D2C-95CF-EFD06850BBF3}" KeyPath="yes">
<ServiceControl Id="CardReaderServiceStarter"
Start="install"
Stop="uninstall"
Remove="uninstall"
Name="FlexitimeCardReaderService"
Wait="yes" />
<Condition><![CDATA[STARTSERVICEONINSTALL <> "false"]]></Condition>
</Component>
<Component Id="CardReaderEventLog" Directory="INSTALLFOLDER"
Guid="{A97DF87D-257C-4321-9ECA-0551FA9301C3}" KeyPath="yes">
<util:EventSource Log="CardReaderService"
EventMessageFile="[WindowsFolder]Microsoft.NET\Framework\v4.0.30319\EventLogMessages.dll"
Name="CardReaderDefaultLogger"/>
</Component>
<ComponentGroup Id="CardReaderServiceComponents" Directory="INSTALLFOLDER">
<ComponentRef Id="CardReaderServiceStarter" />
<ComponentRef Id="CardReaderEventLog" />
<!-- Start the Smart Card Service which is a dependency of the PCSC library. -->
<Component Id="SmartCardServiceConfig" Guid="{73D2E31D-F256-457C-AFD5-EC456CDAD7E8}" KeyPath="yes">
<ServiceControl Id="SmartCardServiceStarter"
Start="install"
Name="SCardSvr"
Wait="yes" />
</Component>
<Component Id="CardReaderServiceExe" Guid="{24C9D834-21E2-476D-8302-EF35730D0BA8}">
<File Id="CardReaderService.exe"
Checksum="yes"
KeyPath="yes"
Source="$(var.CardReaderService.TargetDir)CardReaderService.exe" />
<ServiceInstall Id="CardReaderService"
Start="auto"
ErrorControl="ignore"
Type="ownProcess"
Vital="yes"
Name="FlexitimeCardReaderService"
DisplayName="FlexitimeCardReaderService"
Description="Flexitime Card Reader Service"
Account="LocalSystem">
<util:PermissionEx User="Everyone"
ServicePauseContinue="yes"
ServiceQueryStatus="yes"
ServiceStart="yes"
ServiceStop="yes"
ServiceUserDefinedControl="yes" />
<ServiceConfig Id="CardReaderServiceConfig"
OnInstall="yes"
DelayedAutoStart="0" />
<util:ServiceConfig FirstFailureActionType="restart"
SecondFailureActionType="restart"
ThirdFailureActionType="restart"
ResetPeriodInDays="1"
RestartServiceDelayInSeconds="10" />
</ServiceInstall>
</Component>
<Component Id="CardReaderServiceExeConfig" Guid="{E20D23BC-C8E7-49F8-962C-DE856A84258E}">
<File Id="CardReaderService.exe.config"
Checksum="yes"
KeyPath="yes"
Source="$(var.CardReaderService.TargetDir)CardReaderService.exe.config" />
</Component>
<Component Id="NewtonsoftJson" Guid="{98006F04-1335-40D5-8D2F-A394C8176A1A}">
<File Id="Newtonsoft.Json.dll"
Checksum="yes"
KeyPath="yes"
Source="$(var.CardReaderService.TargetDir)Newtonsoft.Json.dll" />
</Component>
<Component Id="Ninject" Guid="{A5C71803-AD3C-45CB-9973-FB5B6C7579D2}">
<File Id="Ninject.dll"
Checksum="yes"
KeyPath="yes"
Source="$(var.CardReaderService.TargetDir)Ninject.dll" />
</Component>
<Component Id="NinjectConfig" Guid="{C7106002-A5E5-4223-AC34-75704C71D2F4}">
<File Id="NinjectConfig.xml"
Checksum="yes"
KeyPath="yes"
Source="$(var.CardReaderService.TargetDir)NinjectConfig.xml" />
</Component>
<Component Id="PCSC" Guid="{9DD367D4-3760-46DA-8A4A-6E801ED754D5}">
<File Id="pcsc_sharp.dll"
Checksum="yes"
KeyPath="yes"
Source="$(var.CardReaderService.TargetDir)pcsc-sharp.dll" />
</Component>
</ComponentGroup>
</Fragment>
</Wix>

View File

@ -0,0 +1,84 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProductVersion>3.10</ProductVersion>
<ProjectGuid>119216de-fc7f-408a-9c2c-105874449e42</ProjectGuid>
<SchemaVersion>2.0</SchemaVersion>
<OutputName>CardReaderServiceInstaller</OutputName>
<OutputType>Package</OutputType>
<WixTargetsPath Condition=" '$(WixTargetsPath)' == '' AND '$(MSBuildExtensionsPath32)' != '' ">$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
<WixTargetsPath Condition=" '$(WixTargetsPath)' == '' ">$(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<OutputPath>bin\$(Configuration)\</OutputPath>
<IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
<DefineConstants>Debug</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<OutputPath>bin\$(Configuration)\</OutputPath>
<IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
</PropertyGroup>
<ItemGroup>
<Compile Include="CardReaderServiceComponents.wxs" />
<Compile Include="Common.wxs" />
<Compile Include="DirectoryStructure.wxs" />
<Compile Include="LoggerComponents.wxs" />
<Compile Include="Product.wxs" />
<Compile Include="Properties.wxs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\CardReaderService\CardReaderService.csproj">
<Name>CardReaderService</Name>
<Project>{5f30e8e4-5107-4c99-adff-38d735dc113d}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\Interfaces\Interfaces.csproj">
<Name>Interfaces</Name>
<Project>{b7347b72-e208-423a-9d99-723b558ea3d7}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\NLogLogger\NLogLogger.csproj">
<Name>NLogLogger</Name>
<Project>{1c5220d6-9166-4f47-b57d-beb4d09d2a3f}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<WixExtension Include="WixUtilExtension">
<HintPath>$(WixExtDir)\WixUtilExtension.dll</HintPath>
<Name>WixUtilExtension</Name>
</WixExtension>
<WixExtension Include="WixUIExtension">
<HintPath>$(WixExtDir)\WixUIExtension.dll</HintPath>
<Name>WixUIExtension</Name>
</WixExtension>
<WixExtension Include="WixHttpExtension">
<HintPath>$(WixExtDir)\WixHttpExtension.dll</HintPath>
<Name>WixHttpExtension</Name>
</WixExtension>
<WixExtension Include="WixFirewallExtension">
<HintPath>$(WixExtDir)\WixFirewallExtension.dll</HintPath>
<Name>WixFirewallExtension</Name>
</WixExtension>
</ItemGroup>
<Import Project="$(WixTargetsPath)" />
<!--
To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Wix.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<ComponentGroup Id="CommonComponents" Directory="INSTALLFOLDER">
<Component Id="Interfaces" Guid="{B13D293D-FCA6-49C3-878A-0ECDCE724672}">
<File Id="Interfaces.dll"
Checksum="yes"
KeyPath="yes"
Source="$(var.Interfaces.TargetDir)Interfaces.dll" />
</Component>
</ComponentGroup>
</Fragment>
</Wix>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="CardReaderServiceInstaller" >
<Directory Id="CONFIGSFOLDER" Name="Configs" />
</Directory>
</Directory>
</Directory>
</Fragment>
</Wix>

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<ComponentGroup Id="LoggerComponents">
<ComponentGroupRef Id="LoggerConfigComponents"/>
<ComponentGroupRef Id="LoggerBinaryComponents"/>
</ComponentGroup>
<ComponentGroup Id="LoggerBinaryComponents" Directory="INSTALLFOLDER">
<Component Id="NLog" Guid="{3CF61D98-23E5-4042-9325-B1CB25752B6E}">
<File Id="NLog.dll"
Checksum="yes"
KeyPath="yes"
Source="$(var.NLogLogger.TargetDir)NLog.dll" />
</Component>
<Component Id="NLogLogger" Guid="{37C18A51-7934-469E-8DA3-8214754798A6}">
<File Id="NLogLogger.dll"
Checksum="yes"
KeyPath="yes"
Source="$(var.NLogLogger.TargetDir)NLogLogger.dll" />
</Component>
</ComponentGroup>
<ComponentGroup Id="LoggerConfigComponents" Directory="CONFIGSFOLDER">
<Component Id="NLogConfig" Guid="{B4252427-AE6A-4AC5-AA7C-B87C37AF3EB4}">
<File Id="NLogConfig.xml"
Checksum="yes"
KeyPath="yes"
Source="$(var.NLogLogger.TargetDir)NLogConfig.xml" />
</Component>
</ComponentGroup>
</Fragment>
</Wix>

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="{DA4797C8-E60E-499F-95A3-B7BD9D19D6DA}"
Name="CardReaderServiceInstaller"
Language="1033"
Version="1.0.0.0"
Manufacturer="ChrisWatts"
UpgradeCode="3b61e4ae-d717-4c95-9ce5-a53a1c180bf6">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate EmbedCab="yes"/>
<Feature Id="ProductFeature" Title="CardReaderServiceInstaller" Level="1">
<ComponentGroupRef Id="ProductComponents" />
</Feature>
<UIRef Id="WixUI_Mondo" />
<UIRef Id="WixUI_ErrorProgressText" />
</Product>
<Fragment>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<ComponentGroupRef Id="CommonComponents"/>
<ComponentGroupRef Id="LoggerComponents"/>
<ComponentGroupRef Id="CardReaderServiceComponents"/>
</ComponentGroup>
</Fragment>
</Wix>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<Property Id="STARTSERVICEONINSTALL" Value="false" />
</Fragment>
</Wix>

View File

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
namespace Interfaces
{
public class DailyLogs
{
public DailyLogs()
{
Logs = new List<TimeLog>();
}
public DayOfWeek Day { get; set; }
public string DayOfWeek { get; set; }
public int LogCount { get { return Logs.Count; } }
public double DailyTotal { get; set; }
public List<TimeLog> Logs { get; set; }
}
}

View File

@ -0,0 +1,33 @@
using System;
namespace Interfaces
{
public interface ILogger
{
bool IsDebugEnabled { get; }
bool IsErrorEnabled { get; }
bool IsFatalEnabled { get; }
bool IsInfoEnabled { get; }
bool IsTraceEnabled { get; }
bool IsWarnEnabled { get; }
void Debug(Exception exception);
void Debug(string format, params object[] args);
void Debug(Exception exception, string format, params object[] args);
void Error(Exception exception);
void Error(string format, params object[] args);
void Error(Exception exception, string format, params object[] args);
void Fatal(Exception exception);
void Fatal(string format, params object[] args);
void Fatal(Exception exception, string format, params object[] args);
void Info(Exception exception);
void Info(string format, params object[] args);
void Info(Exception exception, string format, params object[] args);
void Trace(Exception exception);
void Trace(string format, params object[] args);
void Trace(Exception exception, string format, params object[] args);
void Warn(Exception exception);
void Warn(string format, params object[] args);
void Warn(Exception exception, string format, params object[] args);
}
}

View File

@ -0,0 +1,109 @@
using System;
namespace Interfaces
{
public interface IRepository
{
/// <summary>
/// Get a list of Users
/// </summary>
/// <returns>
/// Returns <see cref="UserList"/> with full list of users,
/// plus a total user count. Pagination options are supported.
/// </returns>
UserList GetUsers(int pageNumber=-1, int pageSize=-1);
///// <summary>
///// Get a paginated list of users
///// </summary>
///// <param name="pageNumber">The number of the page to retrieve</param>
///// <param name="pageSize">The size of the pages</param>
///// <returns>
///// Returns <see cref="UserList"/> with full list of users,
///// plus a total user count. Pagination options are supported.
///// </returns>
//UserList GetUsers(int pageNumber, int pageSize);
/// <summary>
/// Search the user list for the following string
/// </summary>
/// <param name="searchParam">string to search the user store for.</param>
/// <returns>
/// Returns <see cref="UserList"/> with full list of users,
/// plus a total user count. Pagination options are supported.
/// </returns>
UserList Search(string searchParam);
/// <summary>
/// Get details about a single user in the system base on their Id
/// </summary>
/// <param name="id">
/// integer data type, the Id of the User to get details about.</param>
/// <returns>
/// <see cref="User"/> object with full details,
/// including full <see cref="Identifier"/>
/// </returns>
User GetUser(int id);
/// <summary>
/// Get a list of the timelogs available for the specified user
/// for the current Calendar Week
/// </summary>
/// <param name="userId">
/// integer data type, the Id of the user to get time logs for
/// </param>
/// <returns>
/// <see cref="TimeLogList"/> with nested <see cref="TimeLog"/> objects
/// for the current calendar week
/// </returns>
TimeLogList GetTimeLogs(int userId);
/// <summary>
/// Get a list of the timelogs available for the specified user
/// for the specified calendar week
/// </summary>
/// <param name="userId">
/// integer data type, the Id of the user to get time logs for
/// </param>
/// <param name="selectedDate">
/// datetime data type, the date to receive time logs for (will scope out to calendar week).
/// </param>
/// <returns>
/// <see cref="TimeLogList"/> with nested <see cref="TimeLog"/> objects
/// for the current calendar week
/// </returns>
TimeLogList GetTimeLogs(int userId, DateTime selectedDate);
/// <summary>
/// Get a full list of Identifiers which are not associated to a user.
/// </summary>
/// <returns>
/// <see cref="IdentifierList"/> with nested <see cref="Identifier"/> list
/// </returns>
IdentifierList GetUnassignedIdentifierList();
/// <summary>
/// Update a user in the system with the new values.
/// </summary>
/// <remarks>
/// If the user object passed does not exist, it will be created.
/// </remarks>
/// <param name="user">
/// <see cref="User"/> object detailing the new properties to assign to the user.
/// The Id Field should not be changed, or should be -1 for new users.
/// </param>
/// <param name="userId">
/// int - ref param, value will be the UserId of the inserted or updated user
/// </param>
/// <returns>
/// <see cref="OperationResponse"/> to indicate procedure status.
/// </returns>
OperationResponse UpdateUser(User user, out int userId);
/// <summary>
/// Create a new TimeLog Event in the repository.
/// </summary>
/// <param name="identifier">
/// <see cref="Identifier"/> object with the Unique Id triggering the event
/// </param>
/// <param name="logId">The resultant Id of the inserted TimeLog</param>
/// <returns>
/// <see cref="OperationResponse"/> to indicate procedure status.
/// </returns>
OperationResponse LogEventTime(Identifier identifier, out int logId);
}
}

View File

@ -0,0 +1,24 @@
namespace Interfaces
{
public class Identifier
{
public int Id { get; set; }
public string UniqueId { get; set; }
public bool IsAssociatedToUser { get; set; }
public override bool Equals(object obj)
{
var identObj = obj as Identifier;
if (identObj == null) return false;
return identObj.Id == Id
&& identObj.IsAssociatedToUser == IsAssociatedToUser
&& identObj.UniqueId == UniqueId;
}
public override int GetHashCode()
{
return Id.GetHashCode() ^ UniqueId.GetHashCode() ^ IsAssociatedToUser.GetHashCode();
}
}
}

View File

@ -0,0 +1,13 @@
using System.Collections.Generic;
namespace Interfaces
{
public class IdentifierList
{
public IdentifierList()
{
data = new List<Identifier>();
}
public List<Identifier> data { get; set; }
}
}

View File

@ -0,0 +1,64 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{B7347B72-E208-423A-9D99-723B558EA3D7}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Interfaces</RootNamespace>
<AssemblyName>Interfaces</AssemblyName>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="DailyLogs.cs" />
<Compile Include="ILogger.cs" />
<Compile Include="IRepository.cs" />
<Compile Include="Identifier.cs" />
<Compile Include="IdentifierList.cs" />
<Compile Include="ManualLog.cs" />
<Compile Include="OperationResponse.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="TimeLog.cs" />
<Compile Include="TimeLogList.cs" />
<Compile Include="User.cs" />
<Compile Include="UserList.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Interfaces
{
public class ManualLog
{
public int UserId { get; set; }
public DateTime LogDateTime { get; set; }
}
}

View File

@ -0,0 +1,12 @@
namespace Interfaces
{
public enum OperationResponse
{
NONE = 0,
SUCCESS = 1,
UPDATED = 2,
CREATED = 3,
DELETED = 4,
FAILED = 5
}
}

View File

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

View File

@ -0,0 +1,22 @@
using System;
namespace Interfaces
{
public class TimeLog
{
public int Id { get; set; }
public int UserId { get; set; }
public int IdentifierId { get; set; }
public LogDirection Direction { get; set; }
public DateTimeOffset EventTime { get; set; }
public int CalendarWeek { get; set; }
public int Year { get; set; }
}
public enum LogDirection
{
UNKNOWN = 0,
IN = 1,
OUT = 2
}
}

View File

@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace Interfaces
{
public class TimeLogList
{
public TimeLogList()
{
TimeLogs = new List<DailyLogs>();
}
public DateTime SelectedDate { get; set; }
public int CalendarWeek { get; set; }
public int TimeLogCount { get { return TimeLogs.Sum(x => x.LogCount); } }
public List<DailyLogs> TimeLogs { get; set; }
public int MaxDailyLogCount { get { return TimeLogs.Max(x => x.LogCount); } }
public double WeeklyTotal {
get { return Math.Round(TimeLogs.Sum(x => x.DailyTotal), 2); }
}
public float HoursPerWeekMinutes { get; set; }
}
}

View File

@ -0,0 +1,25 @@
using System.Collections.Generic;
namespace Interfaces
{
public class User
{
public User()
{
AssociatedIdentifiers = new List<Identifier>();
FirstName = "";
LastName = "";
}
public int UserId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public float HoursPerWeek { get; set; }
public bool IsContractor { get; set; }
public int AssociatedIdentifierCount
{
get { return AssociatedIdentifiers.Count; }
}
public List<Identifier> AssociatedIdentifiers { get; set; }
}
}

View File

@ -0,0 +1,30 @@
using System.Collections.Generic;
namespace Interfaces
{
public class UserList
{
public UserList()
{
Users = new List<User>();
PageSize = 10;
}
public string Query { get; set; }
public int UserCount { get { return Users.Count; } }
public int TotalUserCount { get; set; }
public List<User> Users { get; set; }
public int PageCount
{
get
{
if (TotalUserCount < PageSize)
return 1;
return (TotalUserCount / PageSize);
}
}
public int PageSize { get; set; }
public int PageNumber { get; set; }
}
}

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="NLogConfigFilePath" value="Configs/NLogConfig.xml"/>
</appSettings>
</configuration>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true">
<targets>
<target name="viewer" xsi:type="Chainsaw" address="udp://127.0.0.1:4000" />
</targets>
<rules>
<logger name="*" minlevel="Trace" writeTo="viewer" />
</rules>
</nlog>

View File

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{1C5220D6-9166-4F47-B57D-BEB4D09D2A3F}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>NLogLogger</RootNamespace>
<AssemblyName>NLogLogger</AssemblyName>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.4.4.2\lib\net45\NLog.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="NLogger.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Interfaces\Interfaces.csproj">
<Project>{B7347B72-E208-423A-9D99-723B558EA3D7}</Project>
<Name>Interfaces</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Content Include="NLogConfig.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -0,0 +1,123 @@
using System;
using System.Configuration;
using System.IO;
using System.Reflection;
using NLog;
using NLog.Config;
using ILogger = Interfaces.ILogger;
namespace NLogLogger
{
public class NLogger:ILogger
{
private NLog.Logger _logger;
public NLogger()
{
var nlogConfigPathOption = ConfigurationManager.AppSettings["NLogConfigFilePath"];
if (nlogConfigPathOption == null)
{
throw new ArgumentNullException("nlogConfigPath");
}
var nlogConfigPath = new Uri(Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().CodeBase), nlogConfigPathOption)).LocalPath;
LogManager.Configuration = new XmlLoggingConfiguration(nlogConfigPath);
_logger = LogManager.GetLogger("");
}
public bool IsDebugEnabled { get { return _logger.IsDebugEnabled; } }
public bool IsErrorEnabled { get { return _logger.IsErrorEnabled; } }
public bool IsFatalEnabled { get { return _logger.IsFatalEnabled; } }
public bool IsInfoEnabled { get { return _logger.IsInfoEnabled; } }
public bool IsTraceEnabled { get { return _logger.IsTraceEnabled; } }
public bool IsWarnEnabled { get { return _logger.IsWarnEnabled; } }
public void Debug(Exception exception)
{
_logger.Debug(exception);
}
public void Debug(string format, params object[] args)
{
_logger.Debug(format, args);
}
public void Debug(Exception exception, string format, params object[] args)
{
_logger.Debug(exception, format, args);
}
public void Error(Exception exception)
{
_logger.Error(exception);
}
public void Error(string format, params object[] args)
{
_logger.Error(format, args);
}
public void Error(Exception exception, string format, params object[] args)
{
_logger.Error(exception, format, args);
}
public void Fatal(Exception exception)
{
_logger.Fatal(exception);
}
public void Fatal(string format, params object[] args)
{
_logger.Fatal(format, args);
}
public void Fatal(Exception exception, string format, params object[] args)
{
_logger.Fatal(exception, format, args);
}
public void Info(Exception exception)
{
_logger.Info(exception);
}
public void Info(string format, params object[] args)
{
_logger.Info(format, args);
}
public void Info(Exception exception, string format, params object[] args)
{
_logger.Info(exception, format, args);
}
public void Trace(Exception exception)
{
_logger.Trace(exception);
}
public void Trace(string format, params object[] args)
{
_logger.Trace(format, args);
}
public void Trace(Exception exception, string format, params object[] args)
{
_logger.Trace(exception, format, args);
}
public void Warn(Exception exception)
{
_logger.Warn(exception);
}
public void Warn(string format, params object[] args)
{
_logger.Warn(format, args);
}
public void Warn(Exception exception, string format, params object[] args)
{
_logger.Warn(exception, format, args);
}
}
}

View File

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

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="NLog" version="4.4.2" targetFramework="net452" />
</packages>

View File

@ -0,0 +1,12 @@
using SQLite.Net.Attributes;
namespace SQLiteRepository
{
public sealed class CardUniqueId
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public int UserId_FK { get; set; }
public string CardUId { get; set; }
}
}

View File

@ -0,0 +1,7 @@
namespace SQLiteRepository
{
internal class Constants
{
public const int UNASSIGNED_CARD_USER_ID = -1;
}
}

View File

@ -0,0 +1,9 @@
namespace SQLiteRepository
{
public enum LogDirectionDb
{
UNKNOWN = 0,
IN = 1,
OUT = 2
}
}

View File

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

View File

@ -0,0 +1,28 @@
namespace SQLiteRepository
{
internal static class SQLiteProcedures
{
public const string GET_TIMELOGS = "select * from "+nameof(TimeLogDb)+ " where (" + nameof(TimeLogDb.UserId_FK) + "=? AND " + nameof(TimeLogDb.CalendarWeek) + "=? and " + nameof(TimeLogDb.Year) + "=?)";
public const string GET_ALL_USERS = "select * from " + nameof(UserIdentity);
public const string GET_USER_BY_ID = "select * from " + nameof(UserIdentity) + " where " + nameof(UserIdentity.Id) + "=?";
public const string GET_CARDS_BY_USER_ID = "select * from " + nameof(CardUniqueId) + " where " + nameof(CardUniqueId.UserId_FK) + "=?";
public const string GET_CARDS_BY_UNIQUE_ID = "select * from " + nameof(CardUniqueId) + " where " + nameof(CardUniqueId.CardUId) + "=?";
public const string GET_UNASSIGNED_CARD_LIST = "select * from " + nameof(CardUniqueId) + " where " + nameof(CardUniqueId.UserId_FK) + "=?";
public const string GET_USER_BY_FIRST_AND_LAST =
"select * from " + nameof(UserIdentity) + " where " + nameof(UserIdentity.FirstName) + " = ? AND " + nameof(UserIdentity.LastName) + " = ?";
public const string UPDATE_CARD_USER_ID = "update " + nameof(CardUniqueId) + " set " + nameof(CardUniqueId.UserId_FK) + "=? where " + nameof(CardUniqueId.Id) + "=?";
public const string SEARCH_USER_LIST = "SELECT * FROM " + nameof(UserIdentity) + " where(" + nameof(UserIdentity.FirstName) + " Like ? OR " + nameof(UserIdentity.LastName) + " Like ?)";
public const string GET_LAST_TIMELOG_DIRECTION = "SELECT * FROM " + nameof(TimeLogDb) + " where " + nameof(TimeLogDb.UserId_FK) + " = ? order by " + nameof(TimeLogDb.SwipeEventDateTime) + " desc LIMIT 1";
public const string GET_ALL_USERS_PAGINATE = "select * from "+ nameof(UserIdentity)+" limit ? offset ?";
public const string GET_TOTAL_USER_COUNT = "select Max("+nameof(UserIdentity.Id)+") from " + nameof(UserIdentity);
public const string GET_USER_CONTRACTED_HOURS = "select "+nameof(UserIdentity.HoursPerWeek)+ " From UserIdentity where " + nameof(UserIdentity.Id) + "=?";
}
}

View File

@ -0,0 +1,540 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Security.Cryptography.X509Certificates;
using Interfaces;
using SQLite.Net;
using SQLite.Net.Platform.Win32;
namespace SQLiteRepository
{
public class SQLiteRepository : IRepository
{
private readonly SQLiteConnection _connection;
private readonly ILogger _logger;
private string _path = "flexitimedb.db";
public SQLiteRepository(ILogger logger)
{
_path =
new Uri(Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().CodeBase), "flexitimedb.db"))
.LocalPath;
if (logger == null) throw new ArgumentNullException(nameof(logger));
_logger = logger;
_connection = new SQLiteConnection(new SQLitePlatformWin32(), _path);
_connection.CreateTable<CardUniqueId>();
_connection.CreateTable<UserIdentity>();
_connection.CreateTable<TimeLogDb>();
_logger.Trace("Initialised SQLite Repository");
}
public UserList GetUsers(int pageNumber = -1, int pageSize = -1)
{
var ret = new UserList();
List<UserIdentity> users;
int userCount;
if (pageNumber == -1 && pageSize == -1)
{
users = _connection.Query<UserIdentity>(SQLiteProcedures.GET_ALL_USERS);
userCount = users.Count;
}
else
{
users = _connection.Query<UserIdentity>(SQLiteProcedures.GET_ALL_USERS_PAGINATE,
pageSize, (pageNumber - 1) * pageSize);
userCount = _connection.ExecuteScalar<int>(SQLiteProcedures.GET_TOTAL_USER_COUNT);
}
if (!users.Any())
{
if (pageNumber == -1 && pageSize == -1)
{
ret.PageNumber = 1;
ret.PageSize = 20;
}
else
{
ret.PageNumber = pageNumber;
ret.PageSize = pageSize;
}
return ret;
}
foreach (var user in users)
{
var userObj = ChangeToUserObject(user);
var cards = _connection.Query<CardUniqueId>(
SQLiteProcedures.GET_CARDS_BY_USER_ID,
user.Id);
foreach (var card in cards)
{
userObj.AssociatedIdentifiers.Add(new Identifier()
{
UniqueId = card.CardUId,
IsAssociatedToUser = true,
Id = card.Id
});
}
ret.Users.Add(userObj);
}
if (pageNumber == -1 && pageSize == -1)
{
ret.PageSize = 1; //TODO: switch to ret.UserCount
ret.PageNumber = 1;
}
else
{
ret.PageSize = pageSize;
ret.PageNumber = pageNumber;
}
ret.TotalUserCount = userCount;
return ret;
}
public UserList Search(string searchParam)
{
_logger.Trace("Searching SQLite database for the term: {0}", searchParam);
var ret = new UserList();
searchParam = string.Format("%{0}%", searchParam);
var users = _connection.Query<UserIdentity>(
SQLiteProcedures.SEARCH_USER_LIST,
searchParam, searchParam);
_logger.Trace("Got {0} results for term: {1}", users.Count, searchParam);
if (!users.Any())
{
ret.PageNumber = 1;
ret.PageSize = 20;
return ret;
}
foreach (var user in users)
{
var userObj = ChangeToUserObject(user);
var cards = _connection.Query<CardUniqueId>(
SQLiteProcedures.GET_CARDS_BY_USER_ID,
user.Id);
foreach (var card in cards)
{
userObj.AssociatedIdentifiers.Add(new Identifier()
{
UniqueId = card.CardUId,
IsAssociatedToUser = true,
Id = card.Id
});
}
ret.Users.Add(userObj);
}
//TODO: figure out paging here. - should there be any?
ret.PageSize = 20;
ret.PageNumber = 1;
return ret;
}
public User GetUser(int id)
{
var ret = new User();
try
{
var users = _connection.Query<UserIdentity>(
SQLiteProcedures.GET_USER_BY_ID,
id);
if (!users.Any()) return ret;
var user = users.First();
ret = ChangeToUserObject(user);
var cards = _connection.Query<CardUniqueId>(
SQLiteProcedures.GET_CARDS_BY_USER_ID,
user.Id);
foreach (var card in cards)
{
ret.AssociatedIdentifiers.Add(new Identifier { UniqueId = card.CardUId, IsAssociatedToUser = true, Id = card.Id });
}
}
catch (Exception ex)
{
_logger.Error(ex, "Error in GetUser with Id: {0}", id);
ret.UserId = id;
ret.FirstName = ret.LastName = string.Empty;
ret.HoursPerWeek = -1.0f;
ret.IsContractor = false;
ret.AssociatedIdentifiers.Clear();
}
return ret;
}
//TODO: refac this as it duplicates a lot of code.
public TimeLogList GetTimeLogs(int userId)
{
return GetTimeLogs(userId, DateTime.UtcNow);
}
public TimeLogList GetTimeLogs(int userId, DateTime selectedDate)
{
var ret = new TimeLogList { SelectedDate = selectedDate.Date };
var calendarWeek = GetIso8601CalendarWeek(selectedDate);
ret.CalendarWeek = calendarWeek;
try
{
ret.TimeLogs = GetTimeLogList(userId, calendarWeek, selectedDate.Year);
}
catch (Exception ex)
{
_logger.Error(ex, "Error in GetTimeLogs with Id: {0} and selected date: {1}, Exception: {2}", userId, selectedDate, ex);
}
try
{
ret.HoursPerWeekMinutes = GetUserContractedHours(userId) * 60.0f;
}
catch (Exception ex)
{
_logger.Error(ex, "Error in GetUserContracterHours with Id: {0} and selected date: {1}, Exception: {2}", userId, selectedDate, ex);
}
return ret;
}
private float GetUserContractedHours(int userId)
{
var hoursQuery = _connection.Query<UserIdentity>(SQLiteProcedures.GET_USER_CONTRACTED_HOURS, userId);
if (hoursQuery.Any())
{
return hoursQuery.First().HoursPerWeek;
}
return -1.0f;
}
public IdentifierList GetUnassignedIdentifierList()
{
var ret = new IdentifierList();
var cardQuery = _connection.Query<CardUniqueId>(
SQLiteProcedures.GET_UNASSIGNED_CARD_LIST,
Constants.UNASSIGNED_CARD_USER_ID);
foreach (var card in cardQuery)
{
ret.data.Add(new Identifier
{
Id = card.Id,
IsAssociatedToUser = card.UserId_FK != Constants.UNASSIGNED_CARD_USER_ID,
UniqueId = card.CardUId
});
}
return ret;
}
//TODO: Check time logs table on update to ensure associated cards/unique identifiers are removed/added as appropriate.
public OperationResponse UpdateUser(User user, out int userIdResult)
{
//if(user.UserId <=0) return OperationResponse.FAILED;
var ret = OperationResponse.NONE;
var cardIds = new List<int>();
//Get a list of current associated identifiers, convert into a list of Identifier Objects..
var currentCards =
_connection.Query<CardUniqueId>(SQLiteProcedures.GET_CARDS_BY_USER_ID, user.UserId)
.Select(x => new Identifier { Id = x.Id, IsAssociatedToUser = true, UniqueId = x.CardUId });
var cardsToRemove = currentCards.Except(user.AssociatedIdentifiers).Select(x => x.Id).ToList();
#region GetUnique Identifiers
foreach (var card in user.AssociatedIdentifiers)
{
var existingCard = _connection.Query<CardUniqueId>(
SQLiteProcedures.GET_CARDS_BY_UNIQUE_ID, card.UniqueId);
if (!existingCard.Any())
{
var cardInsert = new CardUniqueId { CardUId = card.UniqueId, UserId_FK = -1 };
_connection.Insert(cardInsert);
cardIds.Add(cardInsert.Id);
if (ret < OperationResponse.CREATED)
ret = OperationResponse.CREATED; //only change it if my status supercedes.
}
else
{
cardIds.Add(existingCard.First().Id);
if (ret < OperationResponse.UPDATED)
ret = OperationResponse.UPDATED;
}
}
#endregion
#region Update/Create User
int userId;
if (user.UserId != -1)
{
//edit..
_connection.Query<UserIdentity>(
"update UserIdentity set FirstName=?, LastName=?, HoursPerWeek=?,IsContractor=? where Id=?",
user.FirstName,
user.LastName,
user.HoursPerWeek,
user.IsContractor,
user.UserId
);
userId = user.UserId;
}
else
{
var userInsert = new UserIdentity
{
FirstName = user.FirstName,
LastName = user.LastName,
HoursPerWeek = user.HoursPerWeek,
IsContractor = user.IsContractor
};
_connection.Insert(userInsert);
userId = userInsert.Id;
if (ret < OperationResponse.CREATED)
ret = OperationResponse.CREATED;
}
#endregion
#region Update Card/Unique Id entries.
foreach (var cardId in cardIds)
{
_connection.Query<CardUniqueId>(
SQLiteProcedures.UPDATE_CARD_USER_ID,
userId, cardId);
}
foreach (var card in cardsToRemove)
{
_connection.Query<CardUniqueId>(
SQLiteProcedures.UPDATE_CARD_USER_ID,
-1, card);
}
#endregion
userIdResult = userId;
return ret;
}
public OperationResponse LogEventTime(Identifier identifier, out int logId)
{
var cardIdQuery = _connection.Query<CardUniqueId>(
SQLiteProcedures.GET_CARDS_BY_UNIQUE_ID,
identifier.UniqueId);
#region Get/Insert the PK Id Identifier to associate the time log to.
var ident = new CardUniqueId();
if (!cardIdQuery.Any())
{
//new card, create it!
ident.UserId_FK = -1;
ident.CardUId = identifier.UniqueId;
_connection.Insert(ident);
}
else
{
//TODO: log when more than one comes back. should NEVER happen but....
ident = cardIdQuery.First();
}
#endregion
// Get The User Direction (are they going in or out)?
var logDirection = GetLogDirection(ident.UserId_FK);
#region Get the current time (for swiping). and calendar week/year to help recall the data.
var logTime = DateTime.UtcNow;
var calendarWeek = GetIso8601CalendarWeek(logTime);
var year = logTime.Year;
#endregion
//TODO: Handle When the identifier is assigned to a user (identifier has -1)
//when identifier not assigned to user, just store it anyway and carry on, can update later.
var timeLog = new TimeLogDb
{
SwipeEventDateTime = DateTime.UtcNow,
UserId_FK = ident.UserId_FK,
IdentifierId = ident.Id,
Direction = logDirection,
Year = year,
CalendarWeek = calendarWeek
};
_connection.Insert(timeLog);
logId = timeLog.Id;
return OperationResponse.SUCCESS;
}
private List<DailyLogs> GetTimeLogList(int userId, int calendarWeek, int year)
{
var timeLogList = _connection.Query<TimeLogDb>(
SQLiteProcedures.GET_TIMELOGS,
userId, calendarWeek, year);
var timeLogs = timeLogList.Select(x => new TimeLog
{
Id = x.Id,
CalendarWeek = x.CalendarWeek,
Direction = (LogDirection)x.Direction,
IdentifierId = x.IdentifierId,
EventTime = x.SwipeEventDateTime,
UserId = x.UserId_FK,
Year = x.Year
}).ToList();
var dict = new Dictionary<DayOfWeek, DailyLogs>();
var logList = new List<DailyLogs>();
//make sure each day of the week is accounted for in the dictionary.
foreach (DayOfWeek day in Enum.GetValues(typeof(DayOfWeek)))
{
dict.Add(day, new DailyLogs());
}
//add the logs to the respective day of the week.
foreach (var log in timeLogs)
{
dict[log.EventTime.DayOfWeek].Logs.Add(log);
}
var logGroups = timeLogs.GroupBy(x => x.EventTime.DayOfWeek);
foreach (var group in logGroups)
{
var groupLogs = group.ToList();
var dailyLog = new DailyLogs
{
Logs = groupLogs,
Day = group.Key,
DayOfWeek = group.Key.ToString()
};
dailyLog.DailyTotal = CalculateDailyTotal(dailyLog);
logList.Add(dailyLog);
}
foreach (DayOfWeek day in Enum.GetValues(typeof(DayOfWeek)))
{
if (logList.Any(x => x.Day == day)) continue;
var dailyLog = new DailyLogs {Day = day, DayOfWeek = day.ToString()};
logList.Add(dailyLog);
}
foreach (var dailyCollection in dict)
{
dailyCollection.Value.DailyTotal = CalculateDailyTotal(dailyCollection.Value);
}
return logList.OrderBy(x => ((int) x.Day + 6)%7).ToList();
}
private double CalculateDailyTotal(DailyLogs dailyLogs)
{
var totalInTime = TimeSpan.FromSeconds(0);
var logs = dailyLogs.Logs.OrderBy(x => x.Id).ToArray();
var totalCalcMax = IsOdd(logs.Length) ? logs.Length - 1 : logs.Length;
for (int i = 0; i < totalCalcMax; i += 2)
{
totalInTime += (logs[i + 1].EventTime - logs[i].EventTime);
}
return Math.Round(totalInTime.TotalMinutes, 2);
}
/// <summary>
/// determines if the number is an odd or even value
/// </summary>
/// <param name="value">number to determine is odd or even</param>
/// <returns>true - number is odd</returns>
private bool IsOdd(int value)
{
return value % 2 != 0;
}
/// <summary>
/// Get the new direction for the user based on previous entry logs in the system.
/// </summary>
/// <remarks>
/// If the user has not logged in today, the direction will be In.
/// If the user has logged in already today, the direction will be the opposite of the last
/// recorded log direction. ("out" if "in", "in" if "out")
/// </remarks>
/// <param name="userId">Id of the user to get the log direction of.</param>
/// <returns><see cref="LogDirectionDb"/> indicating what direction the new log is.</returns>
private LogDirectionDb GetLogDirection(int userId)
{
var logDirection = LogDirectionDb.UNKNOWN;
if (userId != -1)
{
var lastEntry = _connection.Query<TimeLogDb>(
SQLiteProcedures.GET_LAST_TIMELOG_DIRECTION,
userId);
if (lastEntry.Any())
{
var lastLog = lastEntry.First();
// See if the datetime retrieved is yesterday. If yesterday, logDirection = true (in)
if (IsLogDateTimeYesterdayOrOlder(lastLog.SwipeEventDateTime.DateTime))
{
logDirection = LogDirectionDb.IN;
}
else
{
// we have a time log from today already, so just do the opposite of what we last did!
if (lastLog.Direction == LogDirectionDb.IN)
logDirection = LogDirectionDb.OUT;
else if (lastLog.Direction == LogDirectionDb.OUT)
logDirection = LogDirectionDb.IN;
}
}
else
{
//assume its the first then!
logDirection = LogDirectionDb.IN;
}
}
return logDirection;
}
/// <summary>
/// Get the calendar week of the year according to the ISO8601 standard (starts monday).
/// </summary>
/// <param name="date">the date to get the calendar week of.</param>
/// <returns>the calendar week of the year in integer form (1-52)</returns>
private int GetIso8601CalendarWeek(DateTime date)
{
var day = CultureInfo.InvariantCulture.Calendar.GetDayOfWeek(date);
if (day >= DayOfWeek.Monday && day <= DayOfWeek.Wednesday)
{
date = date.AddDays(3);
}
return CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(date, CalendarWeekRule.FirstFourDayWeek,
DayOfWeek.Monday);
}
/// <summary>
/// Check whether the specified DateTime is from yesterday or older.
/// </summary>
/// <param name="dt">the DateTime object to check is yesterday or older</param>
/// <returns>true - is yesterday or older.</returns>
private bool IsLogDateTimeYesterdayOrOlder(DateTime dt)
{
return dt.Date.CompareTo(DateTime.Today.Date) < 0;
}
private User ChangeToUserObject(UserIdentity user)
{
return new User
{
UserId = user.Id,
FirstName = user.FirstName,
LastName = user.LastName,
HoursPerWeek = user.HoursPerWeek,
IsContractor = user.IsContractor
};
}
}
}

View File

@ -0,0 +1,94 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{B3510C81-F069-48A2-B826-EBE0CE7AB0B2}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>SQLiteRepository</RootNamespace>
<AssemblyName>SQLiteRepository</AssemblyName>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="SQLite.Net, Version=3.1.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\SQLite.Net.Core-PCL.3.1.1\lib\portable-win8+net45+wp8+wpa81+MonoAndroid1+MonoTouch1\SQLite.Net.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="SQLite.Net.Platform.Generic, Version=3.1.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\SQLite.Net-PCL.3.1.1\lib\net40\SQLite.Net.Platform.Generic.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="SQLite.Net.Platform.Win32, Version=3.1.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\SQLite.Net-PCL.3.1.1\lib\net4\SQLite.Net.Platform.Win32.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Data.SQLite, Version=1.0.104.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL">
<HintPath>..\packages\System.Data.SQLite.Core.1.0.104.0\lib\net451\System.Data.SQLite.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="CardUniqueId.cs" />
<Compile Include="SQLiteRepository.cs" />
<Compile Include="Constants.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SQLiteProcedures.cs" />
<Compile Include="LogDirectionDb.cs" />
<Compile Include="TimeLogDb.cs" />
<Compile Include="UserIdentity.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Interfaces\Interfaces.csproj">
<Project>{B7347B72-E208-423A-9D99-723B558EA3D7}</Project>
<Name>Interfaces</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\System.Data.SQLite.Core.1.0.104.0\build\net451\System.Data.SQLite.Core.targets" Condition="Exists('..\packages\System.Data.SQLite.Core.1.0.104.0\build\net451\System.Data.SQLite.Core.targets')" />
<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\System.Data.SQLite.Core.1.0.104.0\build\net451\System.Data.SQLite.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\System.Data.SQLite.Core.1.0.104.0\build\net451\System.Data.SQLite.Core.targets'))" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -0,0 +1,17 @@
using System;
using SQLite.Net.Attributes;
namespace SQLiteRepository
{
public sealed class TimeLogDb
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public int UserId_FK { get; set; }
public int IdentifierId { get; set; }
public LogDirectionDb Direction { get; set; }
public DateTimeOffset SwipeEventDateTime { get; set; }
public int CalendarWeek { get; set; }
public int Year { get; set; }
}
}

View File

@ -0,0 +1,14 @@
using SQLite.Net.Attributes;
namespace SQLiteRepository
{
public sealed class UserIdentity
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public float HoursPerWeek { get; set; }
public bool IsContractor { get; set; }
}
}

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="SQLite.Net.Core-PCL" version="3.1.1" targetFramework="net452" />
<package id="SQLite.Net-PCL" version="3.1.1" targetFramework="net452" />
<package id="System.Data.SQLite.Core" version="1.0.104.0" targetFramework="net452" />
</packages>

Binary file not shown.

View File

@ -0,0 +1,219 @@
EXPORTS
sqlite3_aggregate_context
sqlite3_aggregate_count
sqlite3_auto_extension
sqlite3_backup_finish
sqlite3_backup_init
sqlite3_backup_pagecount
sqlite3_backup_remaining
sqlite3_backup_step
sqlite3_bind_blob
sqlite3_bind_blob64
sqlite3_bind_double
sqlite3_bind_int
sqlite3_bind_int64
sqlite3_bind_null
sqlite3_bind_parameter_count
sqlite3_bind_parameter_index
sqlite3_bind_parameter_name
sqlite3_bind_text
sqlite3_bind_text16
sqlite3_bind_text64
sqlite3_bind_value
sqlite3_bind_zeroblob
sqlite3_blob_bytes
sqlite3_blob_close
sqlite3_blob_open
sqlite3_blob_read
sqlite3_blob_reopen
sqlite3_blob_write
sqlite3_busy_handler
sqlite3_busy_timeout
sqlite3_cancel_auto_extension
sqlite3_changes
sqlite3_clear_bindings
sqlite3_close
sqlite3_close_v2
sqlite3_collation_needed
sqlite3_collation_needed16
sqlite3_column_blob
sqlite3_column_bytes
sqlite3_column_bytes16
sqlite3_column_count
sqlite3_column_database_name
sqlite3_column_database_name16
sqlite3_column_decltype
sqlite3_column_decltype16
sqlite3_column_double
sqlite3_column_int
sqlite3_column_int64
sqlite3_column_name
sqlite3_column_name16
sqlite3_column_origin_name
sqlite3_column_origin_name16
sqlite3_column_table_name
sqlite3_column_table_name16
sqlite3_column_text
sqlite3_column_text16
sqlite3_column_type
sqlite3_column_value
sqlite3_commit_hook
sqlite3_compileoption_get
sqlite3_compileoption_used
sqlite3_complete
sqlite3_complete16
sqlite3_config
sqlite3_context_db_handle
sqlite3_create_collation
sqlite3_create_collation16
sqlite3_create_collation_v2
sqlite3_create_function
sqlite3_create_function16
sqlite3_create_function_v2
sqlite3_create_module
sqlite3_create_module_v2
sqlite3_data_count
sqlite3_db_config
sqlite3_db_filename
sqlite3_db_handle
sqlite3_db_mutex
sqlite3_db_readonly
sqlite3_db_release_memory
sqlite3_db_status
sqlite3_declare_vtab
sqlite3_enable_load_extension
sqlite3_enable_shared_cache
sqlite3_errcode
sqlite3_errmsg
sqlite3_errmsg16
sqlite3_errstr
sqlite3_exec
sqlite3_expired
sqlite3_extended_errcode
sqlite3_extended_result_codes
sqlite3_file_control
sqlite3_finalize
sqlite3_free
sqlite3_free_table
sqlite3_get_autocommit
sqlite3_get_auxdata
sqlite3_get_table
sqlite3_global_recover
sqlite3_initialize
sqlite3_interrupt
sqlite3_last_insert_rowid
sqlite3_libversion
sqlite3_libversion_number
sqlite3_limit
sqlite3_load_extension
sqlite3_log
sqlite3_malloc
sqlite3_malloc64
sqlite3_memory_alarm
sqlite3_memory_highwater
sqlite3_memory_used
sqlite3_mprintf
sqlite3_msize
sqlite3_mutex_alloc
sqlite3_mutex_enter
sqlite3_mutex_free
sqlite3_mutex_leave
sqlite3_mutex_try
sqlite3_next_stmt
sqlite3_open
sqlite3_open16
sqlite3_open_v2
sqlite3_os_end
sqlite3_os_init
sqlite3_overload_function
sqlite3_prepare
sqlite3_prepare16
sqlite3_prepare16_v2
sqlite3_prepare_v2
sqlite3_profile
sqlite3_progress_handler
sqlite3_randomness
sqlite3_realloc
sqlite3_realloc64
sqlite3_release_memory
sqlite3_reset
sqlite3_reset_auto_extension
sqlite3_result_blob
sqlite3_result_blob64
sqlite3_result_double
sqlite3_result_error
sqlite3_result_error16
sqlite3_result_error_code
sqlite3_result_error_nomem
sqlite3_result_error_toobig
sqlite3_result_int
sqlite3_result_int64
sqlite3_result_null
sqlite3_result_text
sqlite3_result_text16
sqlite3_result_text16be
sqlite3_result_text16le
sqlite3_result_text64
sqlite3_result_value
sqlite3_result_zeroblob
sqlite3_rollback_hook
sqlite3_rtree_geometry_callback
sqlite3_rtree_query_callback
sqlite3_set_authorizer
sqlite3_set_auxdata
sqlite3_shutdown
sqlite3_sleep
sqlite3_snprintf
sqlite3_soft_heap_limit
sqlite3_soft_heap_limit64
sqlite3_sourceid
sqlite3_sql
sqlite3_status
sqlite3_step
sqlite3_stmt_busy
sqlite3_stmt_readonly
sqlite3_stmt_status
sqlite3_strglob
sqlite3_stricmp
sqlite3_strnicmp
sqlite3_table_column_metadata
sqlite3_test_control
sqlite3_thread_cleanup
sqlite3_threadsafe
sqlite3_total_changes
sqlite3_trace
sqlite3_transfer_bindings
sqlite3_update_hook
sqlite3_uri_boolean
sqlite3_uri_int64
sqlite3_uri_parameter
sqlite3_user_data
sqlite3_value_blob
sqlite3_value_bytes
sqlite3_value_bytes16
sqlite3_value_double
sqlite3_value_int
sqlite3_value_int64
sqlite3_value_numeric_type
sqlite3_value_text
sqlite3_value_text16
sqlite3_value_text16be
sqlite3_value_text16le
sqlite3_value_type
sqlite3_vfs_find
sqlite3_vfs_register
sqlite3_vfs_unregister
sqlite3_vmprintf
sqlite3_vsnprintf
sqlite3_vtab_config
sqlite3_vtab_on_conflict
sqlite3_wal_autocheckpoint
sqlite3_wal_checkpoint
sqlite3_wal_checkpoint_v2
sqlite3_wal_hook
sqlite3_win32_is_nt
sqlite3_win32_mbcs_to_utf8
sqlite3_win32_set_directory
sqlite3_win32_sleep
sqlite3_win32_utf8_to_mbcs
sqlite3_win32_write_debug

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<ComponentGroup Id="CoreComponents">
<ComponentGroupRef Id="InterfacesGroup"/>
</ComponentGroup>
<ComponentGroup Id="InterfacesGroup" Directory="INSTALLFOLDER">
<Component Id="interfaces.dll" Guid="{FF7287A9-2583-413B-921A-A7E399AD82B9}">
<File Id="InterfacesDll"
Source="$(var.Interfaces.TargetDir)\Interfaces.dll"
KeyPath="yes"
Checksum="yes"/>
</Component>
</ComponentGroup>
</Fragment>
</Wix>

View File

@ -0,0 +1,76 @@
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<DirectoryRef Id="INSTALLFOLDER">
<Directory Id="DALSOFTHELPPAGESROOT" Name="Help">
<Directory Id="DALSOFTHELPPAGESVIEWS" Name="DalSoft.WebApi.HelpPage.Views" >
<Directory Id="DALSOFTHELPTEMPLATES" Name="DisplayTemplates"/>
</Directory>
</Directory>
</DirectoryRef>
<ComponentGroup Id="DalSoftWebApiHelpComponents" >
<ComponentGroupRef Id="DalSoftWebApiHelpDlls"/>
<ComponentGroupRef Id="DalSoftWebApiHelpPages"/>
<ComponentGroupRef Id="DalSoftWebApiHelpTemplates" />
</ComponentGroup>
<ComponentGroup Id="DalSoftWebApiHelpDlls" Directory="INSTALLFOLDER">
<Component Id="DalSoftWebApiHelpPageDll" Guid="{14336777-D4B4-4F13-86E5-40CC99EC2EF0}">
<File Id="DalSoftWebApiHelpPage.dll"
Source="$(var.WindowsDataCenter.TargetDir)\DalSoft.WebApi.HelpPage.dll"
KeyPath="yes"
Checksum="yes"/>
</Component>
</ComponentGroup>
<ComponentGroup Id="DalSoftWebApiHelpPages" Directory="DALSOFTHELPPAGESVIEWS">
<Component Id="apiCshtml" Guid="{EC37A9F3-9162-4977-94C8-0A3A7BF738BA}">
<File Id="api.cshtml"
Source="$(var.WindowsDataCenter.TargetDir)\Help\DalSoft.WebApi.HelpPage.Views\api.cshtml"
KeyPath="yes"
Checksum="yes"/>
</Component>
<Component Id="HelpPageCss" Guid="{B2D885B6-3C13-4756-9F65-46EE33E504EB}">
<File Id="HelpPage.css"
Source="$(var.WindowsDataCenter.TargetDir)\Help\DalSoft.WebApi.HelpPage.Views\HelpPage.css"
KeyPath="yes"
Checksum="yes"/>
</Component>
<Component Id="IndexCshtml" Guid="{33DDE962-66CC-4938-B0C5-1F554A58F1C7}">
<File Id="Index.cshtml"
Source="$(var.WindowsDataCenter.TargetDir)\Help\DalSoft.WebApi.HelpPage.Views\index.cshtml"
KeyPath="yes"
Checksum="yes"/>
</Component>
</ComponentGroup>
<ComponentGroup Id="DalSoftWebApiHelpTemplates" Directory="DALSOFTHELPTEMPLATES" >
<Component Id="ApiGroupCshtml" Guid="{E204BCE6-40DB-4563-8B72-7CDCB425ECA9}">
<File Id="ApiGroup.cshtml"
Source="$(var.WindowsDataCenter.TargetDir)\Help\DalSoft.WebApi.HelpPage.Views\DisplayTemplates\ApiGroup.cshtml"
KeyPath="yes"
Checksum="yes"/>
</Component>
<Component Id="HelpPageApiModelCshtml" Guid="{D4825C1A-C4F9-4EEA-AFA5-BD29B69A9E7D}">
<File Id="HelpPageApiModel.cshtml"
Source="$(var.WindowsDataCenter.TargetDir)\Help\DalSoft.WebApi.HelpPage.Views\DisplayTemplates\HelpPageApiModel.cshtml"
KeyPath="yes"
Checksum="yes"/>
</Component>
<Component Id="ParametersCshtml" Guid="{9FDF06CE-5A92-42E5-AD5E-534D00EDD1AC}">
<File Id="Parameters.cshtml"
Source="$(var.WindowsDataCenter.TargetDir)\Help\DalSoft.WebApi.HelpPage.Views\DisplayTemplates\Parameters.cshtml"
KeyPath="yes"
Checksum="yes"/>
</Component>
<Component Id="SamplesCshtml" Guid="{4FFCCC5C-D449-4461-9705-CA2269B1BE47}">
<File Id="Samples.cshtml"
Source="$(var.WindowsDataCenter.TargetDir)\Help\DalSoft.WebApi.HelpPage.Views\DisplayTemplates\Samples.cshtml"
KeyPath="yes"
Checksum="yes"/>
</Component>
</ComponentGroup>
</Fragment>
</Wix>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:fire="http://schemas.microsoft.com/wix/FirewallExtension">
<Fragment>
<Component Id="DataCenterFirewallConfig" Directory="INSTALLFOLDER" KeyPath="yes" Guid="{7B874DAA-E2D6-493C-8EA8-2F6F3175E010}">
<fire:FirewallException Id="FwallEx"
Port="8800"
Description="Flexitime DataCenter API/Website Port"
Name="Flexitime Data Center"
Protocol="tcp"
Scope="any" IgnoreFailure="yes"/>
</Component>
</Fragment>
</Wix>

View File

@ -0,0 +1,98 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProductVersion>3.10</ProductVersion>
<ProjectGuid>c5a4cdc3-849c-4166-bdc3-56bdb307126d</ProjectGuid>
<SchemaVersion>2.0</SchemaVersion>
<OutputName>WebApiServerHostInstaller</OutputName>
<OutputType>Package</OutputType>
<WixTargetsPath Condition=" '$(WixTargetsPath)' == '' AND '$(MSBuildExtensionsPath32)' != '' ">$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
<WixTargetsPath Condition=" '$(WixTargetsPath)' == '' ">$(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
<Name>DataCenterHostInstaller</Name>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<OutputPath>bin\$(Configuration)\</OutputPath>
<IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
<DefineConstants>Debug</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<OutputPath>bin\$(Configuration)\</OutputPath>
<IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
</PropertyGroup>
<ItemGroup>
<Compile Include="DataCenterURLACLConfiguration.wxs" />
<Compile Include="CoreComponents.wxs" />
<Compile Include="DalsoftWebApiHelp.wxs" />
<Compile Include="DataCenterFirewallConfiguration.wxs" />
<Compile Include="DataCenterServiceComponents.wxs" />
<Compile Include="DirectoryStructure.wxs" />
<Compile Include="NLog.wxs" />
<Compile Include="Product.wxs" />
<Compile Include="Properties.wxs" />
<Compile Include="SQLiteRepository.wxs" />
<Compile Include="WebPages.wxs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Interfaces\Interfaces.csproj">
<Name>Interfaces</Name>
<Project>{b7347b72-e208-423a-9d99-723b558ea3d7}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\NLogLogger\NLogLogger.csproj">
<Name>NLogLogger</Name>
<Project>{1c5220d6-9166-4f47-b57d-beb4d09d2a3f}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\SQLiteRepository\SQLiteRepository.csproj">
<Name>SQLiteRepository</Name>
<Project>{b3510c81-f069-48a2-b826-ebe0ce7ab0b2}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\WindowsDataCenter\WindowsDataCenter.csproj">
<Name>WindowsDataCenter</Name>
<Project>{a5fee048-17a6-4966-9b6b-bf073592a470}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<WixExtension Include="WixFirewallExtension">
<HintPath>$(WixExtDir)\WixFirewallExtension.dll</HintPath>
<Name>WixFirewallExtension</Name>
</WixExtension>
<WixExtension Include="WixHttpExtension">
<HintPath>$(WixExtDir)\WixHttpExtension.dll</HintPath>
<Name>WixHttpExtension</Name>
</WixExtension>
<WixExtension Include="WixUIExtension">
<HintPath>$(WixExtDir)\WixUIExtension.dll</HintPath>
<Name>WixUIExtension</Name>
</WixExtension>
<WixExtension Include="WixUtilExtension">
<HintPath>$(WixExtDir)\WixUtilExtension.dll</HintPath>
<Name>WixUtilExtension</Name>
</WixExtension>
</ItemGroup>
<Import Project="$(WixTargetsPath)" />
<!--
To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Wix.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -0,0 +1,206 @@
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<Fragment>
<PropertyRef Id="STARTSERVICEONINSTALL"/>
<ComponentGroup Id="DataCenterComponents">
<ComponentRef Id="URLReservation"/>
<ComponentRef Id="DataCenterFirewallConfig"/>
<ComponentGroupRef Id="DataCenterFileGroup"/>
</ComponentGroup>
<ComponentGroup Id="DataCenterFileGroup" Directory="INSTALLFOLDER">
<Component Id="MicrosoftOwin" Guid="{45563976-8620-4447-9DFE-216DEF263D5A}">
<File Id="Microsoft.Owin.dll"
Source="$(var.WindowsDataCenter.TargetDir)\Microsoft.Owin.dll"
KeyPath="yes"
Checksum="yes"/>
</Component>
<Component Id="MicrosoftOwinFileSystems" Guid="{45B6E4C5-FDD3-4B59-84A3-C58C8626BF61}">
<File Id="Microsoft.Owin.FileSystems.dll"
Source="$(var.WindowsDataCenter.TargetDir)Microsoft.Owin.FileSystems.dll"
KeyPath="yes"
Checksum="yes"/>
</Component>
<Component Id="MicrosoftOwinHostHttpListener" Guid="{5C9206E7-8C1B-4713-BE3B-8E754172ABE5}">
<File Id="Microsoft.Owin.Host.HttpListener.dll"
Source="$(var.WindowsDataCenter.TargetDir)Microsoft.Owin.Host.HttpListener.dll"
KeyPath="yes"
Checksum="yes"/>
</Component>
<Component Id="MicrosoftOwinHosting" Guid="{1A250453-173F-4FC6-BD72-5E3B3A67569B}">
<File Id="Microsoft.Owin.Hosting.dll"
Source="$(var.WindowsDataCenter.TargetDir)Microsoft.Owin.Hosting.dll"
KeyPath="yes"
Checksum="yes"/>
</Component>
<Component Id="MicrosoftOwinStaticFiles" Guid="{8F6B1D17-8D7C-4320-8BF6-26D6B3C5115E}">
<File Id="Microsoft.Owin.StaticFiles.dll"
Source="$(var.WindowsDataCenter.TargetDir)Microsoft.Owin.StaticFiles.dll"
KeyPath="yes"
Checksum="yes"/>
</Component>
<Component Id="MicrosoftWebInsfrastructure" Guid="{BCBEE2B7-3E75-4744-8B95-5928E69A8807}">
<File Id="Microsoft.Web.Infrastructure.dll"
Source="$(var.WindowsDataCenter.TargetDir)Microsoft.Web.Infrastructure.dll"
KeyPath="yes"
Checksum="yes"/>
</Component>
<Component Id="NewtonsoftJson" Guid="{972634F3-DEC1-41D9-B48E-3836D6C1FD1D}">
<File Id="Newtonsoft.Json.dll"
Source="$(var.WindowsDataCenter.TargetDir)Newtonsoft.Json.dll"
KeyPath="yes"
Checksum="yes"/>
</Component>
<Component Id="Ninject" Guid="{31D0E89E-F1F7-4B7D-84E9-229D5C7042B5}">
<File Id="Ninject.dll"
Source="$(var.WindowsDataCenter.TargetDir)Ninject.dll"
KeyPath="yes"
Checksum="yes"/>
</Component>
<Component Id="NinjectExtensionsContextPreservationDll" Guid="{580EAE73-1DBF-4F79-9153-8D5055C3A31F}">
<File Id="Ninject.Extensions.ContextPreservation.dll"
Source="$(var.WindowsDataCenter.TargetDir)Ninject.Extensions.ContextPreservation.dll"
KeyPath="yes"
Checksum="yes"/>
</Component>
<Component Id="NinjectExtensionsNamedScopeDll" Guid="{76602BE7-8A83-4BC2-AAA3-2A06F82353F0}">
<File Id="Ninject.Extensions.NamedScope.dll"
Source="$(var.WindowsDataCenter.TargetDir)Ninject.Extensions.NamedScope.dll"
KeyPath="yes"
Checksum="yes"/>
</Component>
<Component Id="NinjectExtensionsXmlDll" Guid="{3809511F-9C51-4C05-AFE5-F59160EDCB71}">
<File Id="Ninject.Extensions.Xml.dll"
Source="$(var.WindowsDataCenter.TargetDir)Ninject.Extensions.Xml.dll"
KeyPath="yes"
Checksum="yes"/>
</Component>
<Component Id="NinjectWebCommon" Guid="{A4D175A1-D68C-4E20-9E52-A0A8052B9E1D}">
<File Id="Ninject.Web.Common.dll"
Source="$(var.WindowsDataCenter.TargetDir)Ninject.Web.Common.dll"
KeyPath="yes"
Checksum="yes"/>
</Component>
<Component Id="NinjectWebCommonOwinHost" Guid="{156FF6D0-00DA-46BC-80C9-816F2CA8975E}">
<File Id="Ninject.Web.Common.OwinHost.dll"
Source="$(var.WindowsDataCenter.TargetDir)Ninject.Web.Common.OwinHost.dll"
KeyPath="yes"
Checksum="yes"/>
</Component>
<Component Id="NinjectWebWebApi" Guid="{20D06854-C822-4780-8EDC-D1601A835626}">
<File Id="Ninject.Web.WebApi.dll"
Source="$(var.WindowsDataCenter.TargetDir)Ninject.Web.WebApi.dll"
KeyPath="yes"
Checksum="yes"/>
</Component>
<Component Id="NinjectWebWebApiOwinHost" Guid="{024E48A9-CFAA-4AE1-9B55-399AC27E93B0}">
<File Id="Ninject.Web.WebApi.OwinHost.dll"
Source="$(var.WindowsDataCenter.TargetDir)Ninject.Web.WebApi.OwinHost.dll"
KeyPath="yes"
Checksum="yes"/>
</Component>
<Component Id="NinjectConfig" Guid="{85F6271F-7251-4E88-B44D-8EBDA4CBD29D}">
<File Id="NinjectConfig.xml"
Source="$(var.WindowsDataCenter.TargetDir)NinjectConfig.xml"
KeyPath="yes"
Checksum="yes"/>
</Component>
<Component Id="Owin" Guid="{B4A90231-65AB-40F1-BEEC-EE02B9DBD4EC}">
<File Id="Owin.dll"
Source="$(var.WindowsDataCenter.TargetDir)Owin.dll"
KeyPath="yes"
Checksum="yes"/>
</Component>
<Component Id="RazorEngine" Guid="{494124DC-1BD1-42C2-A249-53757289AAA4}">
<File Id="RazorEngine.dll"
Source="$(var.WindowsDataCenter.TargetDir)RazorEngine.dll"
KeyPath="yes"
Checksum="yes"/>
</Component>
<Component Id="SystemNetHttpFormatting" Guid="{53AB40B1-7A74-4B6B-9F0E-B1A74EE27467}">
<File Id="System.Net.Http.Formatting.dll"
Source="$(var.WindowsDataCenter.TargetDir)System.Net.Http.Formatting.dll"
KeyPath="yes"
Checksum="yes"/>
</Component>
<Component Id="SystemWebHttp" Guid="{B94609B3-B65E-4FB5-B226-B831D8597A9B}">
<File Id="System.Web.Http.dll"
Source="$(var.WindowsDataCenter.TargetDir)System.Web.Http.dll"
KeyPath="yes"
Checksum="yes"/>
</Component>
<Component Id="SystemWebHttpOwin" Guid="{99FF5381-765A-4B03-8668-1083ED498CAB}">
<File Id="System.Web.Http.Owin.dll"
Source="$(var.WindowsDataCenter.TargetDir)System.Web.Http.Owin.dll"
KeyPath="yes"
Checksum="yes"/>
</Component>
<Component Id="SystemWebHttpWebHost" Guid="{29E7462F-32C3-46E2-8295-FBF561D37E40}">
<File Id="System.Web.Http.WebHost.dll"
Source="$(var.WindowsDataCenter.TargetDir)System.Web.Http.WebHost.dll"
KeyPath="yes"
Checksum="yes"/>
</Component>
<Component Id="WebActivatorEx" Guid="{7AD6A619-5946-4E94-AAD3-1AEEB88272C0}">
<File Id="WebActivatorEx.dll"
Source="$(var.WindowsDataCenter.TargetDir)WebActivatorEx.dll"
KeyPath="yes"
Checksum="yes"/>
</Component>
<Component Id="WindowsDataCenter" Guid="{CD36814E-8C1B-4AC1-BDC7-D1595D2A4728}">
<File Id="WindowsDataCenter.exe"
Source="$(var.WindowsDataCenter.TargetDir)WindowsDataCenter.exe"
KeyPath="yes"/>
<ServiceInstall Id="DataCenterService"
Start="auto"
ErrorControl="normal"
Type="ownProcess"
Vital="yes"
Name="FlexitimeDataCenterService"
DisplayName="FlexitimeDataCenterService"
Description="Flexitime API Database and Website"
Account="LocalSystem">
<util:PermissionEx User="Everyone"
ServicePauseContinue="yes"
ServiceQueryStatus="yes"
ServiceStart="yes"
ServiceStop="yes"
ServiceUserDefinedControl="yes" />
<ServiceConfig Id="FlexiTimeServiceConfig"
OnInstall="yes"
DelayedAutoStart="0" />
<util:ServiceConfig FirstFailureActionType="restart"
SecondFailureActionType="restart"
ThirdFailureActionType="restart"
ResetPeriodInDays="1"
RestartServiceDelayInSeconds="10" />
</ServiceInstall>
</Component>
<Component Id="StartDataCenterServiceOnInsall"
Guid="{884828DC-A47E-4CEF-AEEB-E46FFDFFBED3}"
KeyPath="yes">
<ServiceControl Id="FlexitimeDataCenterStarter"
Start="install"
Stop="uninstall"
Remove="uninstall"
Name="FlexitimeDataCenterService"
Wait="yes"/>
<Condition><![CDATA[STARTSERVICEONINSTALL <> "false"]]></Condition>
</Component>
<Component Id="WindowsDataCenterExeConfig" Guid="{CBFA53EB-0663-4A79-9990-451FC1105A12}">
<File Id="WindowsDataCenter.exe.config"
Source="$(var.WindowsDataCenter.TargetDir)WindowsDataCenter.exe.config"
KeyPath="yes"
Checksum="yes"/>
</Component>
<Component Id="WindowsDataCenterXml" Guid="{35A62230-0052-4EBE-9775-DE0266BADB4E}">
<File Id="WindowsDataCenter.xml"
Source="$(var.WindowsDataCenter.TargetDir)WindowsDataCenter.XML"
KeyPath="yes"
Checksum="yes"/>
</Component>
</ComponentGroup>
</Fragment>
</Wix>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:http="http://schemas.microsoft.com/wix/HttpExtension">
<Fragment>
<Component Id="URLReservation" Guid="{35F39190-88CA-4D1D-B066-9F9CAB328F4D}" Directory="INSTALLFOLDER" KeyPath="yes">
<http:UrlReservation Id="EndpointUrlAcl" Url="http://*:8800/" HandleExisting="ignore">
<http:UrlAce SecurityPrincipal="Everyone" Rights="all"/>
</http:UrlReservation>
</Component>
</Fragment>
</Wix>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="WebApiServerHostInstaller" >
<Directory Id="CONFIGFILES" Name="Configs" />
</Directory>
</Directory>
</Directory>
</Fragment>
</Wix>

View File

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<ComponentGroup Id="NLogComponents">
<ComponentGroupRef Id="NLoggerGroup"/>
<ComponentGroupRef Id="NLogConfigFiles"/>
</ComponentGroup>
<ComponentGroup Id="NLoggerGroup" Directory="INSTALLFOLDER">
<Component Id="NLoggerDll" Guid="{48765F51-86CA-4AD8-A34E-E4705353E101}">
<File Id="NLogLoggerDll"
Source="$(var.NLogLogger.TargetDir)\NLogLogger.dll"
KeyPath="yes"
Checksum="yes"/>
</Component>
<Component Id="NLogDll" Guid="{D9D15A6F-9602-4B6B-BB76-AD0768D14780}">
<File Id="NLog.dll"
Source="$(var.NLogLogger.TargetDir)\NLog.dll"
KeyPath="yes"
Checksum="yes"/>
</Component>
<Component Id="NLogLoggerDllConfig" Guid="{E3808BFF-5156-4123-B108-BECD0A5A99BC}">
<File Id="NLogLoggerDllConfig"
Source="$(var.NLogLogger.TargetDir)\NLogLogger.dll.config"
KeyPath="yes" />
</Component>
</ComponentGroup>
<ComponentGroup Id="NLogConfigFiles" Directory="CONFIGFILES">
<Component Id="NLogConfigFile" Guid="{DE1F65F2-C286-4495-984C-9BF5861A0567}">
<File Id="NLogConfigXml"
Source="$(var.NLogLogger.TargetDir)\NLogConfig.xml"
KeyPath="yes" />
</Component>
</ComponentGroup>
</Fragment>
</Wix>

View File

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="{52F7296E-1C7E-497E-9B25-4FE715D7AD1C}"
Name="DataCentreHostInstaller"
Language="1033"
Version="0.0.1.0"
Manufacturer="ChrisWatts"
UpgradeCode="7282166b-691e-4caa-9a80-f348b8e5ffef">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate EmbedCab="yes"/>
<Feature Id="Complete"
Title="FlexitimeDataCenter"
Description="Flexitime Data Center Website and Data Center"
Level="1"
AllowAdvertise="yes">
<ComponentGroupRef Id="ProductComponents" />
</Feature>
<UIRef Id="WixUI_Mondo" />
<UIRef Id="WixUI_ErrorProgressText" />
</Product>
<Fragment>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<ComponentGroupRef Id="CoreComponents"/>
<ComponentGroupRef Id="DalSoftWebApiHelpComponents" />
<ComponentGroupRef Id="DataCenterComponents"/>
<ComponentGroupRef Id="NLogComponents" />
<ComponentGroupRef Id="SQLiteRepositoryComponents" />
<ComponentGroupRef Id="WebSiteComponents" />
</ComponentGroup>
</Fragment>
</Wix>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<Property Id="STARTSERVICEONINSTALL" Value="false" />
</Fragment>
</Wix>

View File

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<DirectoryRef Id="INSTALLFOLDER">
<Directory Id="SQLITEX86" Name="x86" />
<Directory Id="SQLITEX64" Name="x64" />
</DirectoryRef>
<ComponentGroup Id="SQLiteRepositoryComponents" >
<ComponentGroupRef Id="SQLiteRepository" />
<ComponentGroupRef Id="SQLiteInterop" />
</ComponentGroup>
<ComponentGroup Id="SQLiteRepository" Directory="INSTALLFOLDER">
<Component Id="SQLiteNet" Guid="{65D7D3DB-AB4A-41DE-956E-ACBC1EC1E5B7}">
<File Id="SQLiteNet.dll"
Source="$(var.SQLiteRepository.TargetDir)\SQLite.Net.dll"
KeyPath="yes"
Checksum="yes" />
</Component>
<Component Id="SQLiteNetPlatformGeneric" Guid="{6E540212-B40B-41EB-BD81-1D8625F330D3}">
<File Id="SQLiteNetPlatformGenericDll"
Source="$(var.SQLiteRepository.TargetDir)\SQLite.Net.Platform.Generic.dll"
KeyPath="yes"
Checksum="yes"/>
</Component>
<Component Id="SQLiteNetPlatformWin32" Guid="{41E99987-0901-44D8-A2E8-2BCE18660298}">
<File Id="SQLiteNetPlatformWin32.dll"
Source="$(var.SQLiteRepository.TargetDir)\SQLite.Net.Platform.Win32.dll"
KeyPath="yes"
Checksum="yes"/>
</Component>
<Component Id="SQLiteRepository" Guid="{B109C5DD-FD21-4078-9534-6065753F2900}">
<File Id="SQLiteRepository.dll"
Source="$(var.SQLiteRepository.TargetDir)\SQLiteRepository.dll"
KeyPath="yes"
Checksum="yes"/>
</Component>
</ComponentGroup>
<ComponentGroup Id="SQLiteInterop">
<Component Id="SQLiteInteropx86" Guid="{7D4C1BF5-A6B5-4379-B040-4AD6BABBB526}" Directory="SQLITEX86">
<File Id="SQLite.Interop.dllx86"
Source="$(var.WindowsDataCenter.TargetDir)x86\SQLite.Interop.dll"
KeyPath="yes"
Checksum="yes"/>
</Component>
<Component Id="SQLiteInteropx64" Guid="{3591D185-ECBA-4382-BE75-FF6A271CEE3B}" Directory="SQLITEX64">
<File Id="SQLite.Interop.dllx64"
Source="$(var.WindowsDataCenter.TargetDir)x64\SQLite.Interop.dll"
KeyPath="yes"
Checksum="yes"/>
</Component>
</ComponentGroup>
</Fragment>
</Wix>

View File

@ -0,0 +1,130 @@
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<DirectoryRef Id="INSTALLFOLDER">
<Directory Id="STATICWWW" Name="www" >
<Directory Id="STATICWWWCSS" Name="css"/>
<Directory Id="STATICWWWJS" Name="js" />
</Directory>
</DirectoryRef>
<ComponentGroup Id="WebSiteComponents">
<ComponentGroupRef Id="WWWStaticFiles"/>
<ComponentGroupRef Id="WWWStaticJs"/>
<ComponentGroupRef Id="WWWStaticCss"/>
</ComponentGroup>
<ComponentGroup Id="WWWStaticFiles" Directory="STATICWWW">
<Component Id="IndexHtml" Guid="{418BCB07-AB9B-4A67-AB31-E9378B806A2E}">
<File Id="index.html"
Source="$(var.WindowsDataCenter.TargetDir)\www\index.html"
KeyPath="yes"
Checksum="yes"/>
</Component>
<Component Id="SpaCss" Guid="{A5998F36-2CD9-4EB3-A008-12AE1018F153}">
<File Id="spa.css"
Source="$(var.WindowsDataCenter.TargetDir)\www\spa.css"
KeyPath="yes"
Checksum="yes"/>
</Component>
<Component Id="SpaJs" Guid="{0A669ADE-9804-4C2A-9970-BF7EFE52F003}">
<File Id="spa.js"
Source="$(var.WindowsDataCenter.TargetDir)\www\spa.js"
KeyPath="yes"
Checksum="yes"/>
</Component>
</ComponentGroup>
<ComponentGroup Id="WWWStaticJs" Directory="STATICWWWJS">
<Component Id="BootstrapJs" Guid="{DF7034BA-B315-4AB5-983A-6470D773DF27}">
<File Id="Bootstrap.js"
Source="$(var.WindowsDataCenter.TargetDir)www\js\bootstrap.js"
KeyPath="yes"
Checksum="yes"/>
</Component>
<Component Id="BootstrapMinJs" Guid="{48C14202-7096-4FCA-91BA-7BB24F0D5C22}">
<File Id="Bootstrap.min.js"
Source="$(var.WindowsDataCenter.TargetDir)www\js\bootstrap.min.js"
KeyPath="yes"
Checksum="yes"/>
</Component>
</ComponentGroup>
<ComponentGroup Id="WWWStaticCss" Directory="STATICWWWCSS">
<Component Id="BootstrapCss" Guid="{EBB792CD-23B2-4806-B92B-CA4CD3293148}">
<File Id="bootstrap.css"
Source="$(var.WindowsDataCenter.TargetDir)www\css\bootstrap.css"
KeyPath="yes"
Checksum="yes"/>
</Component>
<Component Id="BootstrapCssMap" Guid="{6E7BEFA7-61F3-4740-96A2-9036F6ABF273}">
<File Id="bootstrap.css.map"
Source="$(var.WindowsDataCenter.TargetDir)www\css\bootstrap.css.map"
KeyPath="yes"
Checksum="yes"/>
</Component>
<Component Id="BootstrapMinCss" Guid="{10BBCC84-63EB-4B4A-816B-460888896A79}">
<File Id="bootstrap.min.css"
Source="$(var.WindowsDataCenter.TargetDir)www\css\bootstrap.min.css"
KeyPath="yes"
Checksum="yes"/>
</Component>
<Component Id="BootstrapMinCssMap" Guid="{909F1752-1472-48DD-99DA-116D391FB12B}">
<File Id="bootstrap.min.css.map"
Source="$(var.WindowsDataCenter.TargetDir)www\css\bootstrap.min.css.map"
KeyPath="yes"
Checksum="yes"/>
</Component>
<Component Id="BootstrapGridCss" Guid="{0EA9E1E9-F077-4B75-A829-6CC93AF55684}">
<File Id="bootstrap_grid.css"
Source="$(var.WindowsDataCenter.TargetDir)www\css\bootstrap-grid.css"
KeyPath="yes"
Checksum="yes"/>
</Component>
<Component Id="BootstrapGridCssMap" Guid="{5732BF4E-5963-49BD-B466-D9D3CF0B137A}">
<File Id="bootstrap_grid.css.map"
Source="$(var.WindowsDataCenter.TargetDir)www\css\bootstrap-grid.css.map"
KeyPath="yes"
Checksum="yes"/>
</Component>
<Component Id="BootstrapGridMinCss" Guid="{1281A9F1-28E0-4748-B9B4-8C8C68EDD9E5}">
<File Id="bootstrap_grid.min.css"
Source="$(var.WindowsDataCenter.TargetDir)www\css\bootstrap-grid.min.css"
KeyPath="yes"
Checksum="yes"/>
</Component>
<Component Id="BootstrapGridMinCssMap" Guid="{F054150C-0E9A-4EB8-8EB2-B5BD81D004CE}">
<File Id="bootstrap_grid.min.css.map"
Source="$(var.WindowsDataCenter.TargetDir)www\css\bootstrap-grid.min.css.map"
KeyPath="yes"
Checksum="yes"/>
</Component>
<Component Id="BootstrapRebootCss" Guid="{9A116F79-1714-4B01-B664-218287EB97BA}">
<File Id="bootstrap_reboot.css"
Source="$(var.WindowsDataCenter.TargetDir)www\css\bootstrap-reboot.css"
KeyPath="yes"
Checksum="yes"/>
</Component>
<Component Id="BootstrapRebootCssMap" Guid="{C7B42AD0-294B-40C0-9755-78839F0310AC}">
<File Id="bootstrap_reboot.css.map"
Source="$(var.WindowsDataCenter.TargetDir)www\css\bootstrap-reboot.css.map"
KeyPath="yes"
Checksum="yes"/>
</Component>
<Component Id="BootstrapRebootMinCss" Guid="{18EB9B47-06F6-42B8-8DEA-C6EC50FB4979}">
<File Id="bootstrap_reboot.min.css"
Source="$(var.WindowsDataCenter.TargetDir)www\css\bootstrap-reboot.min.css"
KeyPath="yes"
Checksum="yes"/>
</Component>
<Component Id="BootstrapRebootMinCssMap" Guid="{40200643-0ECE-4F03-BBB6-98BD877CF43F}">
<File Id="bootstrap_reboot.min.css.map"
Source="$(var.WindowsDataCenter.TargetDir)www\css\bootstrap-reboot.min.css.map"
KeyPath="yes"
Checksum="yes"/>
</Component>
</ComponentGroup>
</Fragment>
</Wix>

View File

@ -4,25 +4,112 @@ Microsoft Visual Studio Solution File, Format Version 12.00
VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WindowsDataCenter", "WindowsDataCenter\WindowsDataCenter.csproj", "{A5FEE048-17A6-4966-9B6B-BF073592A470}"
ProjectSection(ProjectDependencies) = postProject
{6E48913F-9D8C-4132-93A7-C7B1C6DD5264} = {6E48913F-9D8C-4132-93A7-C7B1C6DD5264}
{1C5220D6-9166-4F47-B57D-BEB4D09D2A3F} = {1C5220D6-9166-4F47-B57D-BEB4D09D2A3F}
{5F30E8E4-5107-4C99-ADFF-38D735DC113D} = {5F30E8E4-5107-4C99-ADFF-38D735DC113D}
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WindowsDataServiceHost", "WindowsDataServiceHost\WindowsDataServiceHost.csproj", "{5A4E2CF2-FA51-413E-82C7-14A19A50766D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Interfaces", "Interfaces\Interfaces.csproj", "{B7347B72-E208-423A-9D99-723B558EA3D7}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SQLiteRepository", "SQLiteRepository\SQLiteRepository.csproj", "{B3510C81-F069-48A2-B826-EBE0CE7AB0B2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NLogLogger", "NLogLogger\NLogLogger.csproj", "{1C5220D6-9166-4F47-B57D-BEB4D09D2A3F}"
EndProject
Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "DataCenterHostInstaller", "WebApiServerHostInstaller\DataCenterHostInstaller.wixproj", "{C5A4CDC3-849C-4166-BDC3-56BDB307126D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CardReaderService", "CardReaderService\CardReaderService.csproj", "{5F30E8E4-5107-4C99-ADFF-38D735DC113D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CardReaderServiceHost", "CardReaderServiceHost\CardReaderServiceHost.csproj", "{6E48913F-9D8C-4132-93A7-C7B1C6DD5264}"
EndProject
Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "CardReaderServiceInstaller", "CardReaderServiceInstaller\CardReaderServiceInstaller.wixproj", "{119216DE-FC7F-408A-9C2C-105874449E42}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Installers", "Installers", "{10A7E78C-0D11-40DD-AEC3-27C2C507A926}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A5FEE048-17A6-4966-9B6B-BF073592A470}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A5FEE048-17A6-4966-9B6B-BF073592A470}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A5FEE048-17A6-4966-9B6B-BF073592A470}.Debug|x86.ActiveCfg = Debug|Any CPU
{A5FEE048-17A6-4966-9B6B-BF073592A470}.Debug|x86.Build.0 = Debug|Any CPU
{A5FEE048-17A6-4966-9B6B-BF073592A470}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A5FEE048-17A6-4966-9B6B-BF073592A470}.Release|Any CPU.Build.0 = Release|Any CPU
{A5FEE048-17A6-4966-9B6B-BF073592A470}.Release|x86.ActiveCfg = Release|Any CPU
{A5FEE048-17A6-4966-9B6B-BF073592A470}.Release|x86.Build.0 = Release|Any CPU
{5A4E2CF2-FA51-413E-82C7-14A19A50766D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5A4E2CF2-FA51-413E-82C7-14A19A50766D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5A4E2CF2-FA51-413E-82C7-14A19A50766D}.Debug|x86.ActiveCfg = Debug|Any CPU
{5A4E2CF2-FA51-413E-82C7-14A19A50766D}.Debug|x86.Build.0 = Debug|Any CPU
{5A4E2CF2-FA51-413E-82C7-14A19A50766D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5A4E2CF2-FA51-413E-82C7-14A19A50766D}.Release|Any CPU.Build.0 = Release|Any CPU
{5A4E2CF2-FA51-413E-82C7-14A19A50766D}.Release|x86.ActiveCfg = Release|Any CPU
{5A4E2CF2-FA51-413E-82C7-14A19A50766D}.Release|x86.Build.0 = Release|Any CPU
{B7347B72-E208-423A-9D99-723B558EA3D7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B7347B72-E208-423A-9D99-723B558EA3D7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B7347B72-E208-423A-9D99-723B558EA3D7}.Debug|x86.ActiveCfg = Debug|Any CPU
{B7347B72-E208-423A-9D99-723B558EA3D7}.Debug|x86.Build.0 = Debug|Any CPU
{B7347B72-E208-423A-9D99-723B558EA3D7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B7347B72-E208-423A-9D99-723B558EA3D7}.Release|Any CPU.Build.0 = Release|Any CPU
{B7347B72-E208-423A-9D99-723B558EA3D7}.Release|x86.ActiveCfg = Release|Any CPU
{B7347B72-E208-423A-9D99-723B558EA3D7}.Release|x86.Build.0 = Release|Any CPU
{B3510C81-F069-48A2-B826-EBE0CE7AB0B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B3510C81-F069-48A2-B826-EBE0CE7AB0B2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B3510C81-F069-48A2-B826-EBE0CE7AB0B2}.Debug|x86.ActiveCfg = Debug|Any CPU
{B3510C81-F069-48A2-B826-EBE0CE7AB0B2}.Debug|x86.Build.0 = Debug|Any CPU
{B3510C81-F069-48A2-B826-EBE0CE7AB0B2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B3510C81-F069-48A2-B826-EBE0CE7AB0B2}.Release|Any CPU.Build.0 = Release|Any CPU
{B3510C81-F069-48A2-B826-EBE0CE7AB0B2}.Release|x86.ActiveCfg = Release|Any CPU
{B3510C81-F069-48A2-B826-EBE0CE7AB0B2}.Release|x86.Build.0 = Release|Any CPU
{1C5220D6-9166-4F47-B57D-BEB4D09D2A3F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1C5220D6-9166-4F47-B57D-BEB4D09D2A3F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1C5220D6-9166-4F47-B57D-BEB4D09D2A3F}.Debug|x86.ActiveCfg = Debug|Any CPU
{1C5220D6-9166-4F47-B57D-BEB4D09D2A3F}.Debug|x86.Build.0 = Debug|Any CPU
{1C5220D6-9166-4F47-B57D-BEB4D09D2A3F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1C5220D6-9166-4F47-B57D-BEB4D09D2A3F}.Release|Any CPU.Build.0 = Release|Any CPU
{1C5220D6-9166-4F47-B57D-BEB4D09D2A3F}.Release|x86.ActiveCfg = Release|Any CPU
{1C5220D6-9166-4F47-B57D-BEB4D09D2A3F}.Release|x86.Build.0 = Release|Any CPU
{C5A4CDC3-849C-4166-BDC3-56BDB307126D}.Debug|Any CPU.ActiveCfg = Debug|x86
{C5A4CDC3-849C-4166-BDC3-56BDB307126D}.Debug|x86.ActiveCfg = Debug|x86
{C5A4CDC3-849C-4166-BDC3-56BDB307126D}.Debug|x86.Build.0 = Debug|x86
{C5A4CDC3-849C-4166-BDC3-56BDB307126D}.Release|Any CPU.ActiveCfg = Release|x86
{C5A4CDC3-849C-4166-BDC3-56BDB307126D}.Release|x86.ActiveCfg = Release|x86
{C5A4CDC3-849C-4166-BDC3-56BDB307126D}.Release|x86.Build.0 = Release|x86
{5F30E8E4-5107-4C99-ADFF-38D735DC113D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5F30E8E4-5107-4C99-ADFF-38D735DC113D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5F30E8E4-5107-4C99-ADFF-38D735DC113D}.Debug|x86.ActiveCfg = Debug|Any CPU
{5F30E8E4-5107-4C99-ADFF-38D735DC113D}.Debug|x86.Build.0 = Debug|Any CPU
{5F30E8E4-5107-4C99-ADFF-38D735DC113D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5F30E8E4-5107-4C99-ADFF-38D735DC113D}.Release|Any CPU.Build.0 = Release|Any CPU
{5F30E8E4-5107-4C99-ADFF-38D735DC113D}.Release|x86.ActiveCfg = Release|Any CPU
{5F30E8E4-5107-4C99-ADFF-38D735DC113D}.Release|x86.Build.0 = Release|Any CPU
{6E48913F-9D8C-4132-93A7-C7B1C6DD5264}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6E48913F-9D8C-4132-93A7-C7B1C6DD5264}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6E48913F-9D8C-4132-93A7-C7B1C6DD5264}.Debug|x86.ActiveCfg = Debug|Any CPU
{6E48913F-9D8C-4132-93A7-C7B1C6DD5264}.Debug|x86.Build.0 = Debug|Any CPU
{6E48913F-9D8C-4132-93A7-C7B1C6DD5264}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6E48913F-9D8C-4132-93A7-C7B1C6DD5264}.Release|Any CPU.Build.0 = Release|Any CPU
{6E48913F-9D8C-4132-93A7-C7B1C6DD5264}.Release|x86.ActiveCfg = Release|Any CPU
{6E48913F-9D8C-4132-93A7-C7B1C6DD5264}.Release|x86.Build.0 = Release|Any CPU
{119216DE-FC7F-408A-9C2C-105874449E42}.Debug|Any CPU.ActiveCfg = Debug|x86
{119216DE-FC7F-408A-9C2C-105874449E42}.Debug|x86.ActiveCfg = Debug|x86
{119216DE-FC7F-408A-9C2C-105874449E42}.Debug|x86.Build.0 = Debug|x86
{119216DE-FC7F-408A-9C2C-105874449E42}.Release|Any CPU.ActiveCfg = Release|x86
{119216DE-FC7F-408A-9C2C-105874449E42}.Release|x86.ActiveCfg = Release|x86
{119216DE-FC7F-408A-9C2C-105874449E42}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{C5A4CDC3-849C-4166-BDC3-56BDB307126D} = {10A7E78C-0D11-40DD-AEC3-27C2C507A926}
{119216DE-FC7F-408A-9C2C-105874449E42} = {10A7E78C-0D11-40DD-AEC3-27C2C507A926}
EndGlobalSection
EndGlobal

View File

@ -1,6 +1,37 @@
<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
<appSettings>
<add key="NLogConfigFilePath" value="Configs/NLogConfig.xml" />
</appSettings>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="RazorEngine" publicKeyToken="9ee697374c7e744a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.7.2.0" newVersion="3.7.2.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Http.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View File

@ -0,0 +1,7 @@
namespace WindowsDataCenter
{
public class CardData
{
public string CardUId { get; set; }
}
}

View File

@ -0,0 +1,48 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Web;
using Interfaces;
using Ninject;
using Ninject.Web.Common;
namespace WindowsDataCenter
{
public static class Configuration
{
public static StandardKernel ConfigureNinject()
{
var kernel = new StandardKernel();
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
var ninjectConfigPath =
new Uri(Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().CodeBase), "NinjectConfig.xml"))
.LocalPath;
if (File.Exists(ninjectConfigPath))
{
kernel.Load(ninjectConfigPath);
}
var logger = kernel.TryGet<ILogger>();
if (logger == null)
{
kernel.Bind<ILogger>().To<DefaultComponents.DefaultLogger>();
logger = kernel.Get<ILogger>();
}
logger.Fatal("test message - ninject stuff loaded.");
var repo = kernel.TryGet<IRepository>();
if (repo == null)
{
Debug.WriteLine(File.ReadAllText(ninjectConfigPath));
logger.Fatal("A type of IRepository must be installed. Exiting.");
throw new ArgumentNullException("IRepository");
}
logger.Trace("Got Repo: {0}", repo.GetType());
return kernel;
}
}
}

View File

@ -0,0 +1,31 @@
using System;
using System.Web.Http;
using WindowsDataCenter.Helpers;
using Interfaces;
namespace WindowsDataCenter
{
[RoutePrefix("api/cards")]
public class CardsController : ApiController
{
private readonly IRepository _repo;
private readonly ILogger _logger;
public CardsController(IRepository repo, ILogger logger)
{
if(repo == null) throw new ArgumentNullException(nameof(repo));
_repo = repo;
if(logger == null) throw new ArgumentNullException(nameof(logger));
_logger = logger;
}
[HttpGet]
[Route("unassigned")]
[CacheControl(MaxAge = 0)]
public IHttpActionResult GetUnassignedCards()
{
var unassignedCards = _repo.GetUnassignedIdentifierList();
_logger.Trace("Call to GetUnassignedCards, returning {0} items", unassignedCards.data.Count);
return Ok(unassignedCards);
}
}
}

View File

@ -0,0 +1,57 @@
using System;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using Interfaces;
namespace WindowsDataCenter
{
/// <summary>
///
/// </summary>
[RoutePrefix("api/swipedata")]
public class SwipeDataController : ApiController
{
private readonly IRepository _repo;
private readonly ILogger _logger;
/// <summary>
///
/// </summary>
/// <param name="repo"></param>
public SwipeDataController(IRepository repo, ILogger logger)
{
if(repo == null) throw new ArgumentNullException(nameof(repo));
_repo = repo;
if(logger == null) throw new ArgumentNullException(nameof(logger));
_logger = logger;
}
/// <summary>
///
/// </summary>
/// <param name="cData"></param>
/// <returns></returns>
[HttpPost]
[Route("")]
public IHttpActionResult PostData([FromBody] CardData cData)
{
int logId;
_repo.LogEventTime(new Identifier {UniqueId = cData.CardUId}, out logId);
_logger.Trace("Received new \"Swipe Event\" for UId: {0} at {1}", cData.CardUId, DateTime.UtcNow);
return
ResponseMessage(new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StringContent(logId.ToString())
});
}
/// <summary>
///
/// </summary>
/// <param name="log"></param>
/// <returns></returns>
public IHttpActionResult ManuallyPostData([FromBody] ManualLog log)
{
throw new NotImplementedException();
}
}
}

View File

@ -0,0 +1,50 @@
using System;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Web.Http;
using WindowsDataCenter.Helpers;
using Interfaces;
using Newtonsoft.Json;
namespace WindowsDataCenter
{
[RoutePrefix("api/timelogs")]
public class TimelogController: ApiController
{
private readonly IRepository _repo;
private readonly ILogger _logger;
public TimelogController(IRepository repo, ILogger logger)
{
if (repo == null)
{
throw new ArgumentNullException(nameof(repo));
}
_repo = repo;
if(logger == null) throw new ArgumentNullException(nameof(logger));
_logger = logger;
}
[Route("")]
[CacheControl(MaxAge = 0)]
public IHttpActionResult GetTimeLogs([FromUri]int userId, [FromUri] DateTime? selectedDate = null)
{
_logger.Trace("Getting Time Logs for user with id: {0}, for the calendar week that the date {1} belongs to.", userId, selectedDate ?? DateTime.UtcNow.Date);
TimeLogList logList;
if (selectedDate == null)
logList = _repo.GetTimeLogs(userId);
else
logList = _repo.GetTimeLogs(userId, selectedDate.Value);
_logger.Trace("Got Time logs for the user: {0}, returned {1} records", userId, logList.TimeLogCount);
var msg = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StringContent(JsonConvert.SerializeObject(logList), Encoding.UTF8, "application/json")
};
return ResponseMessage(msg);
}
}
}

View File

@ -0,0 +1,92 @@
using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Web.Http;
using WindowsDataCenter.Helpers;
using Interfaces;
namespace WindowsDataCenter
{
[RoutePrefix("api/users")]
public class UsersController : ApiController
{
private readonly IRepository _repo;
private readonly ILogger _logger;
public UsersController(IRepository repo, ILogger logger)
{
if(logger == null) { throw new ArgumentNullException(nameof(logger));}
_logger = logger;
_logger.Trace("Loading Repository..");
if(repo == null) { throw new ArgumentNullException(nameof(repo));}
_repo = repo;
_logger.Trace("Loaded Repository..");
}
[HttpGet]
[Route("")]
[CacheControl(MaxAge = 0)]
public IHttpActionResult GetUsers([FromUri] string query = "",[FromUri] int pageSize = -1, [FromUri] int pageNumber =-1)
{
_logger.Trace("GetUsers called with arguments >> query: {0}, pageSize: {1}, pageNumber: {2}", query, pageSize, pageNumber);
pageNumber = pageNumber == -1 ? 1 : pageNumber;
pageSize = pageSize == -1 ? 1 : pageSize;
var userList = query == string.Empty ? _repo.GetUsers(pageNumber, pageSize) : _repo.Search(query);
_logger.Trace("Got UserList from Repository, UserCount: {0}", userList.UserCount);
if (query != string.Empty)
{
userList.Query = query;
userList.PageNumber = 1;
userList.PageSize = userList.UserCount;
}
else
userList.Query = null;
userList.PageNumber = pageNumber;
userList.PageSize = pageSize;
_logger.Trace("Returning UserList from GetUsers.");
var msg = Request.CreateResponse(HttpStatusCode.OK, userList);
return ResponseMessage(msg);
}
[HttpGet]
[Route("{id:int}")]
[CacheControl(MaxAge = 0)]
public IHttpActionResult GetUserDetails(int id)
{
_logger.Trace("Getting details for user id: {0}", id);
var ret = _repo.GetUser(id);
_logger.Trace("Got details for user id: {0}, name: {1}", id, ret.FirstName);
var resp = Request.CreateResponse(HttpStatusCode.OK, ret);
return ResponseMessage(resp);
}
[HttpPost]
[Route("create")]
[CacheControl(MaxAge = 0)]
public IHttpActionResult CreateUser([FromBody] User user)
{
int userId;
_repo.UpdateUser(user, out userId);
//TODO return ID.
return ResponseMessage(new HttpResponseMessage(HttpStatusCode.OK) {Content = new StringContent("unknownIdTODO")});
}
[HttpPost]
[Route("edit")]
[CacheControl(MaxAge = 0)]
public IHttpActionResult EditUser([FromBody] User user)
{
_logger.Trace("Editing user, id: {0}", user.UserId);
int userId;
_repo.UpdateUser(user, out userId);
_logger.Trace("Edited details for user id: {0}", user.UserId);
var resp = Request.CreateResponse(HttpStatusCode.OK, userId);
return ResponseMessage(resp);
}
}
}

View File

@ -0,0 +1,13 @@
using System.Collections.Generic;
using System.Web.Http;
namespace WindowsDataCenter
{
public class ValuesController : ApiController
{
public IEnumerable<string> Get()
{
return new List<string> { "ASP.NET", "Docker", "Windows Containers" };
}
}
}

View File

@ -1,6 +1,6 @@
namespace WindowsDataCenter
{
partial class Service1
partial class DataCenterService
{
/// <summary>
/// Required designer variable.

View File

@ -0,0 +1,74 @@
using System;
using System.Diagnostics;
using System.ServiceProcess;
using System.Threading;
using Microsoft.Owin.Hosting;
namespace WindowsDataCenter
{
public partial class DataCenterService: ServiceBase
{
public DataCenterService()
{
InitializeComponent();
}
private IDisposable _webApp;
private bool _stopMainWorkerThread;
private Thread _mainWorkerThread;
public void Start()
{
OnStart(new string[] {});
}
public void Stop()
{
OnStop();
}
protected override void OnStart(string[] args)
{
//Initialise the Ninject system.
var ninjectInstance = NinjectHelper.GetInstance();
_mainWorkerThread = new Thread(MainWorkerThread)
{
IsBackground = false,
Name = "OWIN SELF HOST MAIN THREAD"
};
//TODO: use app.config for endpoint config.
try
{
_webApp = WebApp.Start<StartOwin>("http://*:8800");
}
catch (Exception ex)
{
Debug.WriteLine(ex);
throw;
}
}
protected override void OnStop()
{
_webApp.Dispose();
_stopMainWorkerThread = true;
if (_mainWorkerThread != null && _mainWorkerThread.IsAlive)
{
_mainWorkerThread.Join(2000);
if (_mainWorkerThread.IsAlive)
{
_mainWorkerThread.Interrupt();
}
}
}
private void MainWorkerThread()
{
while (!_stopMainWorkerThread)
{
Thread.Sleep(2000);
}
}
}
}

View File

@ -0,0 +1,110 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Interfaces;
namespace WindowsDataCenter.DefaultComponents
{
public class DefaultLogger : ILogger
{
public bool IsDebugEnabled { get { return true; } }
public bool IsErrorEnabled { get { return true; } }
public bool IsFatalEnabled { get { return true; } }
public bool IsInfoEnabled { get { return true; } }
public bool IsTraceEnabled { get { return true; } }
public bool IsWarnEnabled { get { return true; } }
public void Debug(Exception exception)
{
System.Diagnostics.Debug.WriteLine(exception);
}
public void Debug(string format, params object[] args)
{
System.Diagnostics.Debug.WriteLine(string.Format(format, args));
}
public void Debug(Exception exception, string format, params object[] args)
{
System.Diagnostics.Debug.WriteLine(string.Format(exception + ", " + format, args));
}
public void Error(Exception exception)
{
System.Diagnostics.Debug.WriteLine(exception);
}
public void Error(string format, params object[] args)
{
System.Diagnostics.Debug.WriteLine(string.Format(format, args));
}
public void Error(Exception exception, string format, params object[] args)
{
System.Diagnostics.Debug.WriteLine(string.Format(exception + ", " + format, args));
}
public void Fatal(Exception exception)
{
System.Diagnostics.Debug.WriteLine(exception);
}
public void Fatal(string format, params object[] args)
{
System.Diagnostics.Debug.WriteLine(string.Format(format, args));
}
public void Fatal(Exception exception, string format, params object[] args)
{
System.Diagnostics.Debug.WriteLine(string.Format(exception + ", " + format, args));
}
public void Info(Exception exception)
{
System.Diagnostics.Debug.WriteLine(exception);
}
public void Info(string format, params object[] args)
{
System.Diagnostics.Debug.WriteLine(string.Format(format, args));
}
public void Info(Exception exception, string format, params object[] args)
{
System.Diagnostics.Debug.WriteLine(string.Format(exception + ", " + format, args));
}
public void Trace(Exception exception)
{
System.Diagnostics.Debug.WriteLine(exception);
}
public void Trace(string format, params object[] args)
{
System.Diagnostics.Debug.WriteLine(string.Format(format, args));
}
public void Trace(Exception exception, string format, params object[] args)
{
System.Diagnostics.Debug.WriteLine(string.Format(exception + ", " + format, args));
}
public void Warn(Exception exception)
{
System.Diagnostics.Debug.WriteLine(exception);
}
public void Warn(string format, params object[] args)
{
System.Diagnostics.Debug.WriteLine(string.Format(format, args));
}
public void Warn(Exception exception, string format, params object[] args)
{
System.Diagnostics.Debug.WriteLine(string.Format(exception + ", " + format, args));
}
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.Web.Http.Filters;
namespace WindowsDataCenter.Helpers
{
public class CacheControlAttribute : System.Web.Http.Filters.ActionFilterAttribute
{
public int MaxAge { get; set; }
public CacheControlAttribute()
{
MaxAge = 3600;
}
public override void OnActionExecuted(HttpActionExecutedContext context)
{
if (context.Response != null)
context.Response.Headers.CacheControl = new CacheControlHeaderValue()
{
Public = true,
MaxAge = TimeSpan.FromSeconds(MaxAge)
};
base.OnActionExecuted(context);
}
}
}

View File

@ -0,0 +1,171 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using Newtonsoft.Json.Converters;
namespace WindowsDataCenter
{
/// <summary>
/// Handles JsonP requests when requests are fired with text/javascript
/// </summary>
public class JsonpFormatter : JsonMediaTypeFormatter
{
public JsonpFormatter()
{
SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/javascript"));
JsonpParameterName = "callback";
}
/// <summary>
/// Name of the query string parameter to look for
/// the jsonp function name
/// </summary>
public string JsonpParameterName { get; set; }
/// <summary>
/// Captured name of the Jsonp function that the JSON call
/// is wrapped in. Set in GetPerRequestFormatter Instance
/// </summary>
private string JsonpCallbackFunction;
public override bool CanWriteType(Type type)
{
return true;
}
/// <summary>
/// Override this method to capture the Request object
/// </summary>
/// <param name="type"></param>
/// <param name="request"></param>
/// <param name="mediaType"></param>
/// <returns></returns>
public override MediaTypeFormatter GetPerRequestFormatterInstance(Type type, System.Net.Http.HttpRequestMessage request, MediaTypeHeaderValue mediaType)
{
var formatter = new JsonpFormatter()
{
JsonpCallbackFunction = GetJsonCallbackFunction(request)
};
// this doesn't work unfortunately
//formatter.SerializerSettings = GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings;
// You have to reapply any JSON.NET default serializer Customizations here
formatter.SerializerSettings.Converters.Add(new StringEnumConverter());
formatter.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented;
return formatter;
}
public override Task WriteToStreamAsync(
Type type,
object value,
Stream stream,
HttpContent content,
TransportContext transportContext
)
{
if (string.IsNullOrEmpty(JsonpCallbackFunction))
{
return base.WriteToStreamAsync(type, value, stream, content, transportContext);
}
// write the JSONP pre-amble
var preamble = Encoding.ASCII.GetBytes(JsonpCallbackFunction + "(");
stream.Write(preamble, 0, preamble.Length);
return base.WriteToStreamAsync(type, value, stream, content, transportContext).ContinueWith((innerTask, state) =>
{
if (innerTask.Status == TaskStatus.RanToCompletion)
{
// write the JSONP suffix
var responseStream = (Stream)state;
var suffix = Encoding.ASCII.GetBytes(")");
responseStream.Write(suffix, 0, suffix.Length);
}
}, stream, TaskContinuationOptions.ExecuteSynchronously);
}
//public override Task WriteToStreamAsync(
// Type type,
// object value,
// Stream stream,
// HttpContent content,
// TransportContext transportContext)
//{
// if (string.IsNullOrEmpty(JsonpCallbackFunction))
// return base.WriteToStreamAsync(type, value, stream, content, transportContext);
// StreamWriter writer = null;
// // write the pre-amble
// try
// {
// writer = new StreamWriter(stream);
// writer.Write(JsonpCallbackFunction + "(");
// writer.Flush();
// }
// catch (Exception ex)
// {
// try
// {
// if (writer != null)
// writer.Dispose();
// }
// catch { }
// var tcs = new TaskCompletionSource<object>();
// tcs.SetException(ex);
// return tcs.Task;
// }
// return base.WriteToStreamAsync(type, value, stream, content, transportContext)
// .ContinueWith(innerTask =>
// {
// if (innerTask.Status == TaskStatus.RanToCompletion)
// {
// writer.Write(")");
// writer.Flush();
// }
// }, TaskContinuationOptions.ExecuteSynchronously)
// .ContinueWith(innerTask =>
// {
// writer.Dispose();
// return innerTask;
// }, TaskContinuationOptions.ExecuteSynchronously)
// .Unwrap();
//}
/// <summary>
/// Retrieves the Jsonp Callback function
/// from the query string
/// </summary>
/// <returns></returns>
private string GetJsonCallbackFunction(HttpRequestMessage request)
{
if (request.Method != HttpMethod.Get)
return null;
var query = HttpUtility.ParseQueryString(request.RequestUri.Query);
var queryVal = query[this.JsonpParameterName];
if (string.IsNullOrEmpty(queryVal))
return null;
return queryVal;
}
}
}

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8" ?>
<module name="NinjectAssemblies">
<bind service="Interfaces.ILogger, Interfaces"
to="NLogLogger.NLogger, NLogLogger" scope="singleton" />
<bind service="Interfaces.IRepository, Interfaces"
to="SQLiteRepository.SQLiteRepository, SQLiteRepository" />
</module>

View File

@ -0,0 +1,20 @@
using System.Web.Http.Dependencies;
using Ninject;
namespace WindowsDataCenter
{
public class NinjectDependencyResolver : NinjectDependencyScope, IDependencyResolver
{
readonly IKernel _kernel;
public NinjectDependencyResolver(IKernel kernel) : base(kernel)
{
_kernel = kernel;
}
public IDependencyScope BeginScope()
{
return new NinjectDependencyScope(_kernel.BeginBlock());
}
}
}

View File

@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Web.Http.Dependencies;
using Ninject;
using Ninject.Syntax;
namespace WindowsDataCenter
{
// Provides a Ninject implementation of IDependencyScope
// which resolves services using the Ninject container.
public class NinjectDependencyScope : IDependencyScope
{
IResolutionRoot _resolver;
public NinjectDependencyScope(IResolutionRoot resolver)
{
_resolver = resolver;
}
public object GetService(Type serviceType)
{
if (_resolver == null)
throw new ObjectDisposedException("this", "This scope has been disposed");
return _resolver.TryGet(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
if (_resolver == null)
throw new ObjectDisposedException("this", "This scope has been disposed");
return _resolver.GetAll(serviceType);
}
public void Dispose()
{
IDisposable disposable = _resolver as IDisposable;
disposable?.Dispose();
_resolver = null;
}
}
}

View File

@ -0,0 +1,39 @@
using System.Collections.Generic;
using Ninject;
namespace WindowsDataCenter
{
public class NinjectHelper
{
private static NinjectHelper _instance;
private static readonly object LockObject = new object();
public StandardKernel Kernel { get; private set; }
public static NinjectHelper GetInstance()
{
if (_instance != null)
return _instance;
lock (LockObject)
{
_instance = new NinjectHelper();
return _instance;
}
}
private NinjectHelper()
{
Kernel = Configuration.ConfigureNinject();
}
public T Get<T>()
{
return Kernel.Get<T>();
}
public IEnumerable<T> GetAll<T>()
{
return Kernel.GetAll<T>();
}
}
}

View File

@ -17,7 +17,7 @@ namespace WindowsDataCenter
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new Service1()
new DataCenterService()
};
ServiceBase.Run(ServicesToRun);
}

View File

@ -1,118 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.ServiceProcess;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http;
using Microsoft.Owin.Hosting;
using Owin;
namespace WindowsDataCenter
{
public partial class Service1: ServiceBase
{
public Service1()
{
InitializeComponent();
}
private IDisposable _webApp;
private bool _stopMainWorkerThread;
private Thread _mainWorkerThread;
public void Start()
{
OnStart(new string[] {});
}
public void Stop()
{
OnStop();
}
protected override void OnStart(string[] args)
{
_mainWorkerThread = new Thread(MainWorkerThread)
{
IsBackground = false,
Name = "OWIN SELF HOST MAIN THREAD"
};
_webApp = WebApp.Start<StartOwin>("http://localhost:8800");
}
protected override void OnStop()
{
_webApp.Dispose();
_stopMainWorkerThread = true;
if (_mainWorkerThread != null && _mainWorkerThread.IsAlive)
{
_mainWorkerThread.Join(2000);
if (_mainWorkerThread.IsAlive)
{
_mainWorkerThread.Interrupt();
}
}
}
private void MainWorkerThread()
{
while (!_stopMainWorkerThread)
{
Thread.Sleep(2000);
}
}
}
public class StartOwin
{
public void Configuration(IAppBuilder appBuilder)
{
var config = new HttpConfiguration();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
appBuilder.UseWebApi(config);
}
}
public class SwipeDataController : ApiController
{
[HttpPost]
//[Route("postSwipeData")]
public IHttpActionResult PostData([FromBody] CardData cData)
{
Console.WriteLine(cData.CardUId);
var respMsg = new HttpResponseMessage(HttpStatusCode.OK);
return ResponseMessage(respMsg);
}
}
public class ValuesController : ApiController
{
public IEnumerable<string> Get()
{
return new List<string> { "ASP.NET", "Docker", "Windows Containers" };
}
}
public class UsersController : ApiController
{
public IHttpActionResult GetUsers()
{
throw new NotImplementedException();
}
}
public class CardData
{
public string CardUId { get; set; }
}
}

View File

@ -0,0 +1,53 @@
using System;
using System.IO;
using System.Reflection;
using System.Web.Http;
using DalSoft.WebApi.HelpPage;
using Microsoft.Owin.FileSystems;
using Microsoft.Owin.StaticFiles;
using Ninject.Web.Common.OwinHost;
using Ninject.Web.WebApi.OwinHost;
using Owin;
namespace WindowsDataCenter
{
public class StartOwin
{
public void Configuration(IAppBuilder appBuilder)
{
var config = new HttpConfiguration();
config.MapHttpAttributeRoutes();
config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
//ninject resolver for ApiController DI.
config.DependencyResolver = new NinjectDependencyResolver(NinjectHelper.GetInstance().Kernel);
//JSONP formatter for cross-domain requests.
config.Formatters.Insert(0, new JsonpFormatter());
var staticFilePaths = new Uri(Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().CodeBase), "www"))
.LocalPath;
var fileSystem = new PhysicalFileSystem(staticFilePaths);
var options = new FileServerOptions
{
EnableDefaultFiles = true,
FileSystem = fileSystem
};
options.StaticFileOptions.FileSystem = fileSystem;
options.StaticFileOptions.ServeUnknownFileTypes = true;
options.DefaultFilesOptions.DefaultFileNames = new[]
{
"index.html"
};
config.EnsureInitialized();
appBuilder.UseNinjectMiddleware(()=>NinjectHelper.GetInstance().Kernel).UseNinjectWebApi(config);
//appBuilder.UseWebApi(config);
#if DEBUG
//Add the help-pages extension only in Debug mode.
appBuilder.UseWebApiHelpPage(config, "help-pages");
#endif
appBuilder.UseFileServer(options);
}
}
}

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