mirror of
https://github.com/aljazceru/btcpayserver.git
synced 2025-12-18 06:24:24 +01:00
Upgrade to .NET Core 2.1
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||||
|
|
||||||
<IsPackable>false</IsPackable>
|
<IsPackable>false</IsPackable>
|
||||||
<NoWarn>NU1701,CA1816,CA1308,CA1810,CA2208</NoWarn>
|
<NoWarn>NU1701,CA1816,CA1308,CA1810,CA2208</NoWarn>
|
||||||
|
|||||||
@@ -252,7 +252,7 @@ namespace BTCPayServer.Tests
|
|||||||
|
|
||||||
entity.PaymentTolerance = 100;
|
entity.PaymentTolerance = 100;
|
||||||
accounting = paymentMethod.Calculate();
|
accounting = paymentMethod.Calculate();
|
||||||
Assert.Equal(Money.Coins(0), accounting.MinimumTotalDue);
|
Assert.Equal(Money.Satoshis(1), accounting.MinimumTotalDue);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ services:
|
|||||||
- lightning-charged
|
- lightning-charged
|
||||||
|
|
||||||
nbxplorer:
|
nbxplorer:
|
||||||
image: nicolasdorier/nbxplorer:1.0.2.3
|
image: nicolasdorier/nbxplorer:1.0.2.6
|
||||||
ports:
|
ports:
|
||||||
- "32838:32838"
|
- "32838:32838"
|
||||||
expose:
|
expose:
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||||
<Version>1.0.2.11</Version>
|
<Version>1.0.2.12</Version>
|
||||||
<NoWarn>NU1701,CA1816,CA1308,CA1810,CA2208</NoWarn>
|
<NoWarn>NU1701,CA1816,CA1308,CA1810,CA2208</NoWarn>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -30,38 +30,37 @@
|
|||||||
<EmbeddedResource Include="Currencies.txt" />
|
<EmbeddedResource Include="Currencies.txt" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="BuildBundlerMinifier" Version="2.6.375" />
|
<PackageReference Include="BuildBundlerMinifier" Version="2.7.385" />
|
||||||
<PackageReference Include="DigitalRuby.ExchangeSharp" Version="0.4.1" />
|
<PackageReference Include="DigitalRuby.ExchangeSharp" Version="0.4.1" />
|
||||||
<PackageReference Include="Hangfire" Version="1.6.19" />
|
<PackageReference Include="Hangfire" Version="1.6.19" />
|
||||||
<PackageReference Include="Hangfire.MemoryStorage" Version="1.5.2" />
|
<PackageReference Include="Hangfire.MemoryStorage" Version="1.5.2" />
|
||||||
<PackageReference Include="Hangfire.PostgreSql" Version="1.4.8.1" />
|
<PackageReference Include="Hangfire.PostgreSql" Version="1.4.8.2" />
|
||||||
<PackageReference Include="LedgerWallet" Version="1.0.1.36" />
|
<PackageReference Include="LedgerWallet" Version="1.0.1.36" />
|
||||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="2.6.1" />
|
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="2.8.0" />
|
||||||
<PackageReference Include="Meziantou.AspNetCore.BundleTagHelpers" Version="1.0.1" />
|
<PackageReference Include="Meziantou.AspNetCore.BundleTagHelpers" Version="2.0.0" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.0.3" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Filter" Version="1.1.2" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Filter" Version="1.1.2" />
|
||||||
<PackageReference Include="Microsoft.NetCore.Analyzers" Version="2.6.0" />
|
<PackageReference Include="Microsoft.NetCore.Analyzers" Version="2.6.0" />
|
||||||
<PackageReference Include="NBitcoin" Version="4.1.1.6" />
|
<PackageReference Include="NBitcoin" Version="4.1.1.7" />
|
||||||
<PackageReference Include="NBitpayClient" Version="1.0.0.18" />
|
<PackageReference Include="NBitpayClient" Version="1.0.0.18" />
|
||||||
<PackageReference Include="DBreeze" Version="1.87.0" />
|
<PackageReference Include="DBreeze" Version="1.87.0" />
|
||||||
<PackageReference Include="NBXplorer.Client" Version="1.0.2.6" />
|
<PackageReference Include="NBXplorer.Client" Version="1.0.2.7" />
|
||||||
<PackageReference Include="NicolasDorier.CommandLine" Version="1.0.0.1" />
|
<PackageReference Include="NicolasDorier.CommandLine" Version="1.0.0.1" />
|
||||||
<PackageReference Include="NicolasDorier.CommandLine.Configuration" Version="1.0.0.2" />
|
<PackageReference Include="NicolasDorier.CommandLine.Configuration" Version="1.0.0.2" />
|
||||||
<PackageReference Include="NicolasDorier.StandardConfiguration" Version="1.0.0.13" />
|
<PackageReference Include="NicolasDorier.StandardConfiguration" Version="1.0.0.13" />
|
||||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="2.0.2" />
|
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="2.0.2" />
|
||||||
<PackageReference Include="System.ValueTuple" Version="4.4.0" />
|
<PackageReference Include="System.ValueTuple" Version="4.4.0" />
|
||||||
<PackageReference Include="System.Xml.XmlSerializer" Version="4.0.11" />
|
<PackageReference Include="System.Xml.XmlSerializer" Version="4.3.0" />
|
||||||
<PackageReference Include="Text.Analyzers" Version="2.6.0" />
|
<PackageReference Include="Text.Analyzers" Version="2.6.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.6" />
|
<PackageReference Include="Microsoft.AspNetCore.App" Version="2.1.0-rc1-final" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.0.2" PrivateAssets="All" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version=" 2.1.0-rc1-final" PrivateAssets="All" />
|
||||||
<PackageReference Include="YamlDotNet" Version="4.3.1" />
|
<PackageReference Include="YamlDotNet" Version="4.3.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.0" />
|
|
||||||
<DotNetCliToolReference Include="Microsoft.Extensions.SecretManager.Tools" Version="2.0.0" />
|
|
||||||
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0" />
|
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|||||||
@@ -162,6 +162,7 @@ namespace BTCPayServer.Controllers
|
|||||||
|
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[Route("{appId}/pos")]
|
[Route("{appId}/pos")]
|
||||||
|
[IgnoreAntiforgeryToken]
|
||||||
public async Task<IActionResult> ViewPointOfSale(string appId, double amount, string choiceKey)
|
public async Task<IActionResult> ViewPointOfSale(string appId, double amount, string choiceKey)
|
||||||
{
|
{
|
||||||
var app = await GetApp(appId, AppType.PointOfSale);
|
var app = await GetApp(appId, AppType.PointOfSale);
|
||||||
|
|||||||
@@ -176,24 +176,19 @@ namespace BTCPayServer.Controllers
|
|||||||
using (var ctx = _ContextFactory.CreateContext())
|
using (var ctx = _ContextFactory.CreateContext())
|
||||||
{
|
{
|
||||||
return await ctx.UserStore
|
return await ctx.UserStore
|
||||||
.Where(us => us.ApplicationUserId == userId)
|
.Where(us => us.ApplicationUserId == userId)
|
||||||
.Select(us => new
|
.Join(ctx.Apps, us => us.StoreDataId, app => app.StoreDataId,
|
||||||
{
|
(us, app) =>
|
||||||
IsOwner = us.Role == StoreRoles.Owner,
|
new ListAppsViewModel.ListAppViewModel()
|
||||||
StoreId = us.StoreDataId,
|
{
|
||||||
StoreName = us.StoreData.StoreName,
|
IsOwner = us.Role == StoreRoles.Owner,
|
||||||
Apps = us.StoreData.Apps
|
StoreId = us.StoreDataId,
|
||||||
})
|
StoreName = us.StoreData.StoreName,
|
||||||
.SelectMany(us => us.Apps.Select(app => new ListAppsViewModel.ListAppViewModel()
|
AppName = app.Name,
|
||||||
{
|
AppType = app.AppType,
|
||||||
IsOwner = us.IsOwner,
|
Id = app.Id
|
||||||
AppName = app.Name,
|
})
|
||||||
AppType = app.AppType,
|
.ToArrayAsync();
|
||||||
Id = app.Id,
|
|
||||||
StoreId = us.StoreId,
|
|
||||||
StoreName = us.StoreName
|
|
||||||
}))
|
|
||||||
.ToArrayAsync();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ using NBitcoin;
|
|||||||
using BTCPayServer.Data;
|
using BTCPayServer.Data;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Microsoft.Data.Sqlite;
|
|
||||||
using NBXplorer;
|
using NBXplorer;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ using Hangfire.Annotations;
|
|||||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Microsoft.ApplicationInsights.AspNetCore.Extensions;
|
|
||||||
using Microsoft.AspNetCore.Mvc.Cors.Internal;
|
using Microsoft.AspNetCore.Mvc.Cors.Internal;
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.Core;
|
using Microsoft.AspNetCore.Server.Kestrel.Core;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
@@ -104,10 +103,6 @@ namespace BTCPayServer.Hosting
|
|||||||
b.AllowAnyMethod().AllowAnyHeader().AllowAnyOrigin();
|
b.AllowAnyMethod().AllowAnyHeader().AllowAnyOrigin();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
services.Configure<IOptions<ApplicationInsightsServiceOptions>>(o =>
|
|
||||||
{
|
|
||||||
o.Value.DeveloperMode = _Env.IsDevelopment();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Needed to debug U2F for ledger support
|
// Needed to debug U2F for ledger support
|
||||||
//services.Configure<KestrelServerOptions>(kestrel =>
|
//services.Configure<KestrelServerOptions>(kestrel =>
|
||||||
@@ -146,12 +141,8 @@ namespace BTCPayServer.Hosting
|
|||||||
if (env.IsDevelopment())
|
if (env.IsDevelopment())
|
||||||
{
|
{
|
||||||
app.UseDeveloperExceptionPage();
|
app.UseDeveloperExceptionPage();
|
||||||
app.UseBrowserLink();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//App insight do not that by itself...
|
|
||||||
loggerFactory.AddApplicationInsights(prov, LogLevel.Information);
|
|
||||||
|
|
||||||
app.UsePayServer();
|
app.UsePayServer();
|
||||||
app.UseStaticFiles();
|
app.UseStaticFiles();
|
||||||
app.UseAuthentication();
|
app.UseAuthentication();
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
using Microsoft.Extensions.Logging;
|
using System;
|
||||||
using Microsoft.Extensions.Logging.Console;
|
|
||||||
using Microsoft.Extensions.Logging.Console.Internal;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Microsoft.Extensions.Logging.Abstractions.Internal;
|
||||||
|
using Microsoft.Extensions.Logging.Console;
|
||||||
|
using Microsoft.Extensions.Logging.Console.Internal;
|
||||||
|
|
||||||
namespace BTCPayServer.Logging
|
namespace BTCPayServer.Logging
|
||||||
{
|
{
|
||||||
@@ -20,19 +21,18 @@ namespace BTCPayServer.Logging
|
|||||||
}
|
}
|
||||||
public ILogger CreateLogger(string categoryName)
|
public ILogger CreateLogger(string categoryName)
|
||||||
{
|
{
|
||||||
return new CustomConsoleLogger(categoryName, (a, b) => true, false, _Processor);
|
return new CustomerConsoleLogger(categoryName, (a, b) => true, null, _Processor);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A variant of ASP.NET Core ConsoleLogger which does not make new line for the category
|
/// A variant of ASP.NET Core ConsoleLogger which does not make new line for the category
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class CustomConsoleLogger : ILogger
|
public class CustomerConsoleLogger : ILogger
|
||||||
{
|
{
|
||||||
private static readonly string _loglevelPadding = ": ";
|
private static readonly string _loglevelPadding = ": ";
|
||||||
private static readonly string _messagePadding;
|
private static readonly string _messagePadding;
|
||||||
@@ -47,19 +47,33 @@ namespace BTCPayServer.Logging
|
|||||||
[ThreadStatic]
|
[ThreadStatic]
|
||||||
private static StringBuilder _logBuilder;
|
private static StringBuilder _logBuilder;
|
||||||
|
|
||||||
static CustomConsoleLogger()
|
static CustomerConsoleLogger()
|
||||||
{
|
{
|
||||||
var logLevelString = GetLogLevelString(LogLevel.Information);
|
var logLevelString = GetLogLevelString(LogLevel.Information);
|
||||||
_messagePadding = new string(' ', logLevelString.Length + _loglevelPadding.Length);
|
_messagePadding = new string(' ', logLevelString.Length + _loglevelPadding.Length);
|
||||||
_newLineWithMessagePadding = Environment.NewLine + _messagePadding;
|
_newLineWithMessagePadding = Environment.NewLine + _messagePadding;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CustomConsoleLogger(string name, Func<string, LogLevel, bool> filter, bool includeScopes, ConsoleLoggerProcessor loggerProcessor)
|
public CustomerConsoleLogger(string name, Func<string, LogLevel, bool> filter, bool includeScopes)
|
||||||
|
: this(name, filter, includeScopes ? new LoggerExternalScopeProvider() : null, new ConsoleLoggerProcessor())
|
||||||
{
|
{
|
||||||
Name = name ?? throw new ArgumentNullException(nameof(name));
|
}
|
||||||
Filter = filter ?? ((category, logLevel) => true);
|
|
||||||
IncludeScopes = includeScopes;
|
|
||||||
|
|
||||||
|
internal CustomerConsoleLogger(string name, Func<string, LogLevel, bool> filter, IExternalScopeProvider scopeProvider)
|
||||||
|
: this(name, filter, scopeProvider, new ConsoleLoggerProcessor())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
internal CustomerConsoleLogger(string name, Func<string, LogLevel, bool> filter, IExternalScopeProvider scopeProvider, ConsoleLoggerProcessor loggerProcessor)
|
||||||
|
{
|
||||||
|
if (name == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
Name = name;
|
||||||
|
Filter = filter ?? ((category, logLevel) => true);
|
||||||
|
ScopeProvider = scopeProvider;
|
||||||
_queueProcessor = loggerProcessor;
|
_queueProcessor = loggerProcessor;
|
||||||
|
|
||||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||||
@@ -80,7 +94,12 @@ namespace BTCPayServer.Logging
|
|||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
_queueProcessor.Console = value ?? throw new ArgumentNullException(nameof(value));
|
if (value == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
_queueProcessor.Console = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,13 +111,13 @@ namespace BTCPayServer.Logging
|
|||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
_filter = value ?? throw new ArgumentNullException(nameof(value));
|
if (value == null)
|
||||||
}
|
{
|
||||||
}
|
throw new ArgumentNullException(nameof(value));
|
||||||
|
}
|
||||||
|
|
||||||
public bool IncludeScopes
|
_filter = value;
|
||||||
{
|
}
|
||||||
get; set;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Name
|
public string Name
|
||||||
@@ -106,6 +125,16 @@ namespace BTCPayServer.Logging
|
|||||||
get;
|
get;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal IExternalScopeProvider ScopeProvider
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool DisableColors
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
|
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
|
||||||
{
|
{
|
||||||
if (!IsEnabled(logLevel))
|
if (!IsEnabled(logLevel))
|
||||||
@@ -154,10 +183,7 @@ namespace BTCPayServer.Logging
|
|||||||
while (lenAfter++ < 18)
|
while (lenAfter++ < 18)
|
||||||
logBuilder.Append(" ");
|
logBuilder.Append(" ");
|
||||||
// scope information
|
// scope information
|
||||||
if (IncludeScopes)
|
GetScopeInformation(logBuilder);
|
||||||
{
|
|
||||||
GetScopeInformation(logBuilder);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(message))
|
if (!string.IsNullOrEmpty(message))
|
||||||
{
|
{
|
||||||
@@ -202,18 +228,15 @@ namespace BTCPayServer.Logging
|
|||||||
|
|
||||||
public bool IsEnabled(LogLevel logLevel)
|
public bool IsEnabled(LogLevel logLevel)
|
||||||
{
|
{
|
||||||
|
if (logLevel == LogLevel.None)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return Filter(Name, logLevel);
|
return Filter(Name, logLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IDisposable BeginScope<TState>(TState state)
|
public IDisposable BeginScope<TState>(TState state) => ScopeProvider?.Push(state) ?? NullScope.Instance;
|
||||||
{
|
|
||||||
if (state == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(state));
|
|
||||||
}
|
|
||||||
|
|
||||||
return ConsoleLogScope.Push(Name, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GetLogLevelString(LogLevel logLevel)
|
private static string GetLogLevelString(LogLevel logLevel)
|
||||||
{
|
{
|
||||||
@@ -238,6 +261,11 @@ namespace BTCPayServer.Logging
|
|||||||
|
|
||||||
private ConsoleColors GetLogLevelConsoleColors(LogLevel logLevel)
|
private ConsoleColors GetLogLevelConsoleColors(LogLevel logLevel)
|
||||||
{
|
{
|
||||||
|
if (DisableColors)
|
||||||
|
{
|
||||||
|
return new ConsoleColors(null, null);
|
||||||
|
}
|
||||||
|
|
||||||
// We must explicitly set the background color if we are setting the foreground color,
|
// We must explicitly set the background color if we are setting the foreground color,
|
||||||
// since just setting one can look bad on the users console.
|
// since just setting one can look bad on the users console.
|
||||||
switch (logLevel)
|
switch (logLevel)
|
||||||
@@ -259,30 +287,25 @@ namespace BTCPayServer.Logging
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GetScopeInformation(StringBuilder builder)
|
private void GetScopeInformation(StringBuilder stringBuilder)
|
||||||
{
|
{
|
||||||
var current = ConsoleLogScope.Current;
|
var scopeProvider = ScopeProvider;
|
||||||
string scopeLog = string.Empty;
|
if (scopeProvider != null)
|
||||||
var length = builder.Length;
|
|
||||||
|
|
||||||
while (current != null)
|
|
||||||
{
|
{
|
||||||
if (length == builder.Length)
|
var initialLength = stringBuilder.Length;
|
||||||
{
|
|
||||||
scopeLog = $"=> {current}";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
scopeLog = $"=> {current} ";
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.Insert(length, scopeLog);
|
scopeProvider.ForEachScope((scope, state) =>
|
||||||
current = current.Parent;
|
{
|
||||||
}
|
var (builder, length) = state;
|
||||||
if (builder.Length > length)
|
var first = length == builder.Length;
|
||||||
{
|
builder.Append(first ? "=> " : " => ").Append(scope);
|
||||||
builder.Insert(length, _messagePadding);
|
}, (stringBuilder, initialLength));
|
||||||
builder.AppendLine();
|
|
||||||
|
if (stringBuilder.Length > initialLength)
|
||||||
|
{
|
||||||
|
stringBuilder.Insert(initialLength, _messagePadding);
|
||||||
|
stringBuilder.AppendLine();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -333,9 +356,9 @@ namespace BTCPayServer.Logging
|
|||||||
// Start Console message queue processor
|
// Start Console message queue processor
|
||||||
_outputTask = Task.Factory.StartNew(
|
_outputTask = Task.Factory.StartNew(
|
||||||
ProcessLogQueue,
|
ProcessLogQueue,
|
||||||
this,
|
state: this,
|
||||||
default(CancellationToken),
|
cancellationToken: default(CancellationToken),
|
||||||
TaskCreationOptions.LongRunning, TaskScheduler.Default);
|
creationOptions: TaskCreationOptions.LongRunning, scheduler: TaskScheduler.Default);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void EnqueueMessage(LogMessageEntry message)
|
public virtual void EnqueueMessage(LogMessageEntry message)
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ namespace BTCPayServer.Payments.Bitcoin
|
|||||||
{
|
{
|
||||||
EventAggregator _Aggregator;
|
EventAggregator _Aggregator;
|
||||||
ExplorerClientProvider _ExplorerClients;
|
ExplorerClientProvider _ExplorerClients;
|
||||||
IApplicationLifetime _Lifetime;
|
Microsoft.Extensions.Hosting.IApplicationLifetime _Lifetime;
|
||||||
InvoiceRepository _InvoiceRepository;
|
InvoiceRepository _InvoiceRepository;
|
||||||
private TaskCompletionSource<bool> _RunningTask;
|
private TaskCompletionSource<bool> _RunningTask;
|
||||||
private CancellationTokenSource _Cts;
|
private CancellationTokenSource _Cts;
|
||||||
@@ -39,7 +39,7 @@ namespace BTCPayServer.Payments.Bitcoin
|
|||||||
BTCPayWalletProvider wallets,
|
BTCPayWalletProvider wallets,
|
||||||
InvoiceRepository invoiceRepository,
|
InvoiceRepository invoiceRepository,
|
||||||
BTCPayNetworkProvider networkProvider,
|
BTCPayNetworkProvider networkProvider,
|
||||||
EventAggregator aggregator, IApplicationLifetime lifetime)
|
EventAggregator aggregator, Microsoft.Extensions.Hosting.IApplicationLifetime lifetime)
|
||||||
{
|
{
|
||||||
PollInterval = TimeSpan.FromMinutes(1.0);
|
PollInterval = TimeSpan.FromMinutes(1.0);
|
||||||
_Wallets = wallets;
|
_Wallets = wallets;
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ namespace BTCPayServer
|
|||||||
.UseIISIntegration()
|
.UseIISIntegration()
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||||
.UseConfiguration(conf)
|
.UseConfiguration(conf)
|
||||||
.UseApplicationInsights()
|
|
||||||
.ConfigureLogging(l =>
|
.ConfigureLogging(l =>
|
||||||
{
|
{
|
||||||
l.AddFilter("Microsoft", LogLevel.Error);
|
l.AddFilter("Microsoft", LogLevel.Error);
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-lg-12 text-center">
|
<div class="col-lg-12 text-center">
|
||||||
@Html.Partial("_StatusMessage", "Thank you for confirming your email.")
|
<partial name="_StatusMessage" for="@("Thank you for confirming your email.")" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-lg-12 text-center">
|
<div class="col-lg-12 text-center">
|
||||||
@Html.Partial("_StatusMessage", TempData["StatusMessage"])
|
<partial name="_StatusMessage" for="@TempData["StatusMessage"]" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-lg-12 text-center">
|
<div class="col-lg-12 text-center">
|
||||||
@Html.Partial("_StatusMessage", TempData["StatusMessage"])
|
<partial name="_StatusMessage" for="@TempData["StatusMessage"]" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-lg-12 text-center">
|
<div class="col-lg-12 text-center">
|
||||||
@Html.Partial("_StatusMessage", TempData["TempDataProperty-StatusMessage"])
|
<partial name="_StatusMessage" for="@TempData["TempDataProperty-StatusMessage"]" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-lg-12 text-center">
|
<div class="col-lg-12 text-center">
|
||||||
@Html.Partial("_StatusMessage", TempData["TempDataProperty-StatusMessage"])
|
<partial name="_StatusMessage" for="@TempData["TempDataProperty-StatusMessage"]" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
<div class="timer-row">
|
<div class="timer-row">
|
||||||
<div class="timer-row__progress-bar" style="width: 0%;"></div>
|
<div class="timer-row__progress-bar" style="width: 0%;"></div>
|
||||||
<div class="timer-row__spinner">
|
<div class="timer-row__spinner">
|
||||||
@Html.Partial("Checkout-Spinner")
|
<partial name="Checkout-Spinner" />
|
||||||
</div>
|
</div>
|
||||||
<div class="timer-row__message">
|
<div class="timer-row__message">
|
||||||
<span v-if="srvModel.status === 'expired' || srvModel.status === 'invalid'">
|
<span v-if="srvModel.status === 'expired' || srvModel.status === 'invalid'">
|
||||||
@@ -51,7 +51,7 @@
|
|||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<div class="payment__spinner">
|
<div class="payment__spinner">
|
||||||
@Html.Partial("Checkout-Spinner")
|
<partial name="Checkout-Spinner" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -151,7 +151,7 @@
|
|||||||
<button type="submit" class="action-button" style="margin-top: 15px;">
|
<button type="submit" class="action-button" style="margin-top: 15px;">
|
||||||
<span class="button-text">{{$t("Continue")}}</span>
|
<span class="button-text">{{$t("Continue")}}</span>
|
||||||
<div class="loader-wrapper">
|
<div class="loader-wrapper">
|
||||||
@Html.Partial("Checkout-Spinner")
|
<partial name="Checkout-Spinner" />
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
</bp-loading-button>
|
</bp-loading-button>
|
||||||
@@ -323,7 +323,7 @@
|
|||||||
<button class="action-button" style="margin-top: 15px;" type="submit">
|
<button class="action-button" style="margin-top: 15px;" type="submit">
|
||||||
<span class="button-text" lcl="">Request Refund</span>
|
<span class="button-text" lcl="">Request Refund</span>
|
||||||
<div class="loader-wrapper">
|
<div class="loader-wrapper">
|
||||||
@Html.Partial("Checkout-Spinner")
|
<partial name="Checkout-Spinner" />
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
</bp-loading-button>
|
</bp-loading-button>
|
||||||
@@ -430,7 +430,7 @@
|
|||||||
<button class="action-button" style="margin-top: 15px;" type="submit">
|
<button class="action-button" style="margin-top: 15px;" type="submit">
|
||||||
<span class="button-text" lcl="">Request Refund</span>
|
<span class="button-text" lcl="">Request Refund</span>
|
||||||
<div class="loader-wrapper">
|
<div class="loader-wrapper">
|
||||||
@Html.Partial("Checkout-Spinner")
|
<partial name="Checkout-Spinner" />
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
</bp-loading-button>
|
</bp-loading-button>
|
||||||
|
|||||||
@@ -57,7 +57,7 @@
|
|||||||
<div class="modal-content long">
|
<div class="modal-content long">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="invoice">
|
<div class="invoice">
|
||||||
@Html.Partial("Checkout-Body")
|
<partial name="Checkout-Body" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-lg-12 text-center">
|
<div class="col-lg-12 text-center">
|
||||||
@Html.Partial("_StatusMessage", Model.StatusMessage)
|
<partial name="_StatusMessage" for="StatusMessage" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-lg-12 text-center">
|
<div class="col-lg-12 text-center">
|
||||||
@Html.Partial("_StatusMessage", Model.StatusMessage)
|
<partial name="_StatusMessage" for="StatusMessage" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
<h4>@ViewData["Title"]</h4>
|
<h4>@ViewData["Title"]</h4>
|
||||||
@Html.Partial("_StatusMessage", Model.StatusMessage)
|
<partial name="_StatusMessage" for="StatusMessage" />
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<form method="post">
|
<form method="post">
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
ViewData.SetActivePageAndTitle(ManageNavPages.ExternalLogins, "Manage your external logins");
|
ViewData.SetActivePageAndTitle(ManageNavPages.ExternalLogins, "Manage your external logins");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Html.Partial("_StatusMessage", Model.StatusMessage)
|
<partial name="_StatusMessage" for="StatusMessage" />
|
||||||
@if (Model.CurrentLogins?.Count > 0)
|
@if (Model.CurrentLogins?.Count > 0)
|
||||||
{
|
{
|
||||||
<h4>Registered Logins</h4>
|
<h4>Registered Logins</h4>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
<h4>@ViewData["Title"]</h4>
|
<h4>@ViewData["Title"]</h4>
|
||||||
@Html.Partial("_StatusMessage", Model.StatusMessage)
|
<partial name="_StatusMessage" for="StatusMessage" />
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
<h4>Set your password</h4>
|
<h4>Set your password</h4>
|
||||||
@Html.Partial("_StatusMessage", Model.StatusMessage)
|
<partial name="_StatusMessage" for="StatusMessage" />
|
||||||
<p class="text-info">
|
<p class="text-info">
|
||||||
You do not have a local username/password for this site. Add a local
|
You do not have a local username/password for this site. Add a local
|
||||||
account so you can log in without an external login.
|
account so you can log in without an external login.
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
|
|
||||||
<h4>@ViewData["Title"]</h4>
|
<h4>@ViewData["Title"]</h4>
|
||||||
@Html.Partial("_StatusMessage", Model.StatusMessage)
|
<partial name="_StatusMessage" for="StatusMessage" />
|
||||||
|
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
|
|
||||||
<h4>@ViewData["Title"]</h4>
|
<h4>@ViewData["Title"]</h4>
|
||||||
@Html.Partial("_StatusMessage", Model.StatusMessage)
|
<partial name="_StatusMessage" for="StatusMessage" />
|
||||||
|
|
||||||
|
|
||||||
<table class="table table-sm table-responsive-md">
|
<table class="table table-sm table-responsive-md">
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
|
|
||||||
<h4>@ViewData["Title"]</h4>
|
<h4>@ViewData["Title"]</h4>
|
||||||
@Html.Partial("_StatusMessage", TempData["StatusMessage"])
|
<partial name="_StatusMessage" for="@TempData["StatusMessage"]" />
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-lg-6">
|
<div class="col-lg-6">
|
||||||
<div asp-validation-summary="All" class="text-danger"></div>
|
<div asp-validation-summary="All" class="text-danger"></div>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
|
|
||||||
<h4>@ViewData["Title"]</h4>
|
<h4>@ViewData["Title"]</h4>
|
||||||
@Html.Partial("_StatusMessage", TempData["TempDataProperty-StatusMessage"])
|
<partial name="_StatusMessage" for="@TempData["TempDataProperty-StatusMessage"]" />
|
||||||
|
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
|
|
||||||
<h4>@ViewData["Title"]</h4>
|
<h4>@ViewData["Title"]</h4>
|
||||||
@Html.Partial("_StatusMessage", TempData["StatusMessage"])
|
<partial name="_StatusMessage" for="@TempData["StatusMessage"]" />
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-lg-6">
|
<div class="col-lg-6">
|
||||||
<div asp-validation-summary="All" class="text-danger"></div>
|
<div asp-validation-summary="All" class="text-danger"></div>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
|
|
||||||
<h4>Modify User - @Model.Email</h4>
|
<h4>Modify User - @Model.Email</h4>
|
||||||
@Html.Partial("_StatusMessage", Model.StatusMessage)
|
<partial name="_StatusMessage" for="StatusMessage" />
|
||||||
|
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|||||||
@@ -86,7 +86,7 @@
|
|||||||
|
|
||||||
@if (!dashboard.IsFullySynched())
|
@if (!dashboard.IsFullySynched())
|
||||||
{
|
{
|
||||||
@Html.Partial("SyncModal")
|
<partial name="SyncModal" />
|
||||||
}
|
}
|
||||||
|
|
||||||
@RenderSection("Scripts", required: false)
|
@RenderSection("Scripts", required: false)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
ViewData.AddActivePage(BTCPayServer.Views.Stores.StoreNavPages.Index);
|
ViewData.AddActivePage(BTCPayServer.Views.Stores.StoreNavPages.Index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Html.Partial("_StatusMessage", Model.StatusMessage)
|
<partial name="_StatusMessage" for="StatusMessage" />
|
||||||
<h4>@ViewData["Title"]</h4>
|
<h4>@ViewData["Title"]</h4>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
<h4>@ViewData["Title"]</h4>
|
<h4>@ViewData["Title"]</h4>
|
||||||
@Html.Partial("_StatusMessage", Model.StatusMessage)
|
<partial name="_StatusMessage" for="StatusMessage" />
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<div asp-validation-summary="All" class="text-danger"></div>
|
<div asp-validation-summary="All" class="text-danger"></div>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
<h4>@ViewData["Title"]</h4>
|
<h4>@ViewData["Title"]</h4>
|
||||||
@Html.Partial("_StatusMessage", TempData["TempDataProperty-StatusMessage"])
|
<partial name="_StatusMessage" for="@TempData["TempDataProperty-StatusMessage"]" />
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
ViewData.AddActivePage(StoreNavPages.Tokens);
|
ViewData.AddActivePage(StoreNavPages.Tokens);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Html.Partial("_StatusMessage", Model.StatusMessage)
|
<partial name="_StatusMessage" for="StatusMessage" />
|
||||||
<h4>Access token</h4>
|
<h4>Access token</h4>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-8">
|
<div class="col-md-8">
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
<h4>@ViewData["Title"]</h4>
|
<h4>@ViewData["Title"]</h4>
|
||||||
@Html.Partial("_StatusMessage", TempData["TempDataProperty-StatusMessage"])
|
<partial name="_StatusMessage" for="@TempData["TempDataProperty-StatusMessage"]" />
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-8">
|
<div class="col-md-8">
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
<h4>@ViewData["Title"]</h4>
|
<h4>@ViewData["Title"]</h4>
|
||||||
@Html.Partial("_StatusMessage", TempData["TempDataProperty-StatusMessage"])
|
<partial name="_StatusMessage" for="@TempData["TempDataProperty-StatusMessage"]" />
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
<h4>@ViewData["Title"]</h4>
|
<h4>@ViewData["Title"]</h4>
|
||||||
@Html.Partial("_StatusMessage", TempData["TempDataProperty-StatusMessage"])
|
<partial name="_StatusMessage" for="@TempData["TempDataProperty-StatusMessage"]" />
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-lg-12 text-center">
|
<div class="col-lg-12 text-center">
|
||||||
@Html.Partial("_StatusMessage", TempData["TempDataProperty-StatusMessage"])
|
<partial name="_StatusMessage" for="@TempData["TempDataProperty-StatusMessage"]" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
FROM microsoft/aspnetcore-build:2.0.6-2.1.101-stretch AS builder
|
FROM microsoft/dotnet:2.1.300-rc1-sdk-alpine3.7 AS builder
|
||||||
WORKDIR /source
|
WORKDIR /source
|
||||||
COPY BTCPayServer/BTCPayServer.csproj BTCPayServer.csproj
|
COPY BTCPayServer/BTCPayServer.csproj BTCPayServer.csproj
|
||||||
# Cache some dependencies
|
# Cache some dependencies
|
||||||
@@ -6,7 +6,7 @@ RUN dotnet restore
|
|||||||
COPY BTCPayServer/. .
|
COPY BTCPayServer/. .
|
||||||
RUN dotnet publish --output /app/ --configuration Release
|
RUN dotnet publish --output /app/ --configuration Release
|
||||||
|
|
||||||
FROM microsoft/aspnetcore:2.0.6-stretch
|
FROM microsoft/dotnet:2.1.0-rc1-aspnetcore-runtime-alpine3.7
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
RUN mkdir /datadir
|
RUN mkdir /datadir
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ You can also checkout [The Merchants Guide to accepting Bitcoin directly with no
|
|||||||
|
|
||||||
While the documentation advise using docker-compose, you may want to build yourself outside of development purpose.
|
While the documentation advise using docker-compose, you may want to build yourself outside of development purpose.
|
||||||
|
|
||||||
First install .NET Core SDK as specified by [Microsoft website](https://www.microsoft.com/net/download).
|
First install .NET Core SDK 2.1 as specified by [Microsoft website](https://www.microsoft.com/net/download/dotnet-core/sdk-2.1.300-rc1).
|
||||||
|
|
||||||
On Powershell:
|
On Powershell:
|
||||||
```
|
```
|
||||||
|
|||||||
Reference in New Issue
Block a user