Extract AspNetCore dependency to VAR.WebFormsCore.AspNetCore.
* Abstract HttpContext with IWebContext. * Move AspNetCore dependant code to isolated classes. * Downgrade VAR.WebFormsCore to netstandard2.0.
This commit is contained in:
134
VAR.WebFormsCore.AspNetCore/Code/AspnetCoreWebContext.cs
Normal file
134
VAR.WebFormsCore.AspNetCore/Code/AspnetCoreWebContext.cs
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using VAR.WebFormsCore.Code;
|
||||||
|
|
||||||
|
namespace VAR.WebFormsCore.AspNetCore.Code;
|
||||||
|
|
||||||
|
public class AspnetCoreWebContext : IWebContext
|
||||||
|
{
|
||||||
|
private readonly HttpContext _context;
|
||||||
|
|
||||||
|
public AspnetCoreWebContext(HttpContext context)
|
||||||
|
{
|
||||||
|
_context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string RequestPath => _context.Request.Path;
|
||||||
|
|
||||||
|
public string RequestMethod => _context.Request.Method;
|
||||||
|
|
||||||
|
|
||||||
|
private Dictionary<string, string?>? _requestHeader;
|
||||||
|
|
||||||
|
public Dictionary<string, string?> RequestHeader
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_requestHeader == null)
|
||||||
|
{
|
||||||
|
_requestHeader = _context.Request.Headers
|
||||||
|
.ToDictionary(p => p.Key, p => p.Value[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return _requestHeader;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Dictionary<string, string?>? _requestQuery;
|
||||||
|
|
||||||
|
public Dictionary<string, string?> RequestQuery
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_requestQuery == null)
|
||||||
|
{
|
||||||
|
_requestQuery = _context.Request.Query
|
||||||
|
.ToDictionary(p => p.Key, p => p.Value[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return _requestQuery;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Dictionary<string, string?>? _requestForm;
|
||||||
|
|
||||||
|
public Dictionary<string, string?> RequestForm
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_requestForm == null)
|
||||||
|
{
|
||||||
|
if (_context.Request.Method == "POST")
|
||||||
|
{
|
||||||
|
_requestForm = _context.Request.Form
|
||||||
|
.ToDictionary(p => p.Key, p => p.Value[0]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_requestForm = new Dictionary<string, string?>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return _requestForm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ResponseWrite(string text)
|
||||||
|
{
|
||||||
|
_context.Response.WriteAsync(text).GetAwaiter().GetResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ResponseWriteBin(byte[] content)
|
||||||
|
{
|
||||||
|
_context.Response.Body.WriteAsync(content).GetAwaiter().GetResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ResponseFlush()
|
||||||
|
{
|
||||||
|
_context.Response.Body.FlushAsync().GetAwaiter().GetResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ResponseRedirect(string url)
|
||||||
|
{
|
||||||
|
_context.Response.Redirect(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool ResponseHasStarted => _context.Response.HasStarted;
|
||||||
|
|
||||||
|
public int ResponseStatusCode
|
||||||
|
{
|
||||||
|
get => _context.Response.StatusCode;
|
||||||
|
set => _context.Response.StatusCode = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string? ResponseContentType
|
||||||
|
{
|
||||||
|
get => _context.Response.ContentType;
|
||||||
|
set => _context.Response.ContentType = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetResponseHeader(string key, string value)
|
||||||
|
{
|
||||||
|
_context.Response.Headers.SafeSet(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PrepareCacheableResponse()
|
||||||
|
{
|
||||||
|
const int secondsInDay = 86400;
|
||||||
|
_context.Response.Headers.SafeSet("Cache-Control", $"public, max-age={secondsInDay}");
|
||||||
|
string expireDate = DateTime.UtcNow.AddSeconds(secondsInDay)
|
||||||
|
.ToString("ddd, dd MMM yyyy HH:mm:ss", System.Globalization.CultureInfo.InvariantCulture);
|
||||||
|
_context.Response.Headers.SafeSet("Expires", $"{expireDate} GMT");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PrepareUncacheableResponse()
|
||||||
|
{
|
||||||
|
_context.Response.Headers.SafeSet("Cache-Control", "max-age=0, no-cache, no-store");
|
||||||
|
string expireDate = DateTime.UtcNow.AddSeconds(-1500)
|
||||||
|
.ToString("ddd, dd MMM yyyy HH:mm:ss", System.Globalization.CultureInfo.InvariantCulture);
|
||||||
|
_context.Response.Headers.SafeSet("Expires", $"{expireDate} GMT");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
18
VAR.WebFormsCore.AspNetCore/Code/ExtensionMethods.cs
Normal file
18
VAR.WebFormsCore.AspNetCore/Code/ExtensionMethods.cs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
||||||
|
namespace VAR.WebFormsCore.AspNetCore.Code
|
||||||
|
{
|
||||||
|
public static class ExtensionMethods
|
||||||
|
{
|
||||||
|
#region IHeaderDictionary
|
||||||
|
|
||||||
|
public static void SafeSet(this IHeaderDictionary header, string key, string value) { header[key] = value; }
|
||||||
|
|
||||||
|
public static void SafeDel(this IHeaderDictionary header, string key)
|
||||||
|
{
|
||||||
|
if (header.ContainsKey(key)) { header.Remove(key); }
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion IHeaderDictionary
|
||||||
|
}
|
||||||
|
}
|
||||||
61
VAR.WebFormsCore.AspNetCore/Code/GlobalRouterMiddleware.cs
Normal file
61
VAR.WebFormsCore.AspNetCore/Code/GlobalRouterMiddleware.cs
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
using System;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using VAR.WebFormsCore.Code;
|
||||||
|
|
||||||
|
namespace VAR.WebFormsCore.AspNetCore.Code;
|
||||||
|
|
||||||
|
public class GlobalRouterMiddleware
|
||||||
|
{
|
||||||
|
private readonly GlobalRouter _globalRouter = new();
|
||||||
|
|
||||||
|
public GlobalRouterMiddleware(RequestDelegate next, IWebHostEnvironment env)
|
||||||
|
{
|
||||||
|
ServerHelpers.SetContentRoot(env.ContentRootPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Invoke(HttpContext httpContext)
|
||||||
|
{
|
||||||
|
httpContext.Response.Headers.SafeDel("Server");
|
||||||
|
httpContext.Response.Headers.SafeDel("X-Powered-By");
|
||||||
|
httpContext.Response.Headers.SafeSet("X-Content-Type-Options", "nosniff");
|
||||||
|
httpContext.Response.Headers.SafeSet("X-Frame-Options", "SAMEORIGIN");
|
||||||
|
httpContext.Response.Headers.SafeSet("X-XSS-Protection", "1; mode=block");
|
||||||
|
|
||||||
|
IWebContext webContext = new AspnetCoreWebContext(httpContext);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_globalRouter.RouteRequest(webContext);
|
||||||
|
await httpContext.Response.Body.FlushAsync();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
if (IsIgnoreException(ex) == false)
|
||||||
|
{
|
||||||
|
// TODO: Implement better error logging
|
||||||
|
Console.WriteLine("!!!!!!!!!!");
|
||||||
|
Console.Write("Message: {0}\nStacktrace: {1}\n", ex.Message, ex.StackTrace);
|
||||||
|
|
||||||
|
GlobalErrorHandler.HandleError(webContext, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsIgnoreException(Exception ex) { return ex is ThreadAbortException; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class GlobalRouterMiddlewareExtensions
|
||||||
|
{
|
||||||
|
public static IApplicationBuilder UseGlobalRouterMiddleware(
|
||||||
|
this IApplicationBuilder builder,
|
||||||
|
IWebHostEnvironment env
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return builder.UseMiddleware<GlobalRouterMiddleware>(env);
|
||||||
|
}
|
||||||
|
}
|
||||||
19
VAR.WebFormsCore.AspNetCore/Program.cs
Normal file
19
VAR.WebFormsCore.AspNetCore/Program.cs
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
|
||||||
|
namespace VAR.WebFormsCore.AspNetCore;
|
||||||
|
|
||||||
|
public static class DefaultMain
|
||||||
|
{
|
||||||
|
public static void WebFormCoreMain(string[] args)
|
||||||
|
{
|
||||||
|
CreateHostBuilder(args).Build().Run();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IHostBuilder CreateHostBuilder(string[] args) =>
|
||||||
|
Host.CreateDefaultBuilder(args)
|
||||||
|
.ConfigureWebHostDefaults(webBuilder =>
|
||||||
|
{
|
||||||
|
webBuilder.UseStartup<Startup>();
|
||||||
|
});
|
||||||
|
}
|
||||||
24
VAR.WebFormsCore.AspNetCore/Startup.cs
Normal file
24
VAR.WebFormsCore.AspNetCore/Startup.cs
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.AspNetCore.Server.Kestrel.Core;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using VAR.WebFormsCore.AspNetCore.Code;
|
||||||
|
|
||||||
|
namespace VAR.WebFormsCore.AspNetCore;
|
||||||
|
|
||||||
|
public class Startup
|
||||||
|
{
|
||||||
|
public void ConfigureServices(IServiceCollection services)
|
||||||
|
{
|
||||||
|
// If using Kestrel:
|
||||||
|
services.Configure<KestrelServerOptions>(options =>
|
||||||
|
{
|
||||||
|
options.AddServerHeader = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
|
||||||
|
{
|
||||||
|
app.UseGlobalRouterMiddleware(env);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\VAR.WebFormsCore\VAR.WebFormsCore.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using System;
|
||||||
using VAR.WebFormsCore.Code;
|
using VAR.WebFormsCore.Code;
|
||||||
using VAR.WebFormsCore.Controls;
|
using VAR.WebFormsCore.Controls;
|
||||||
using VAR.WebFormsCore.Pages;
|
using VAR.WebFormsCore.Pages;
|
||||||
|
|||||||
@@ -1,17 +1,12 @@
|
|||||||
namespace VAR.WebFormsCore.TestWebApp
|
using VAR.WebFormsCore.AspNetCore;
|
||||||
{
|
|
||||||
public static class Program
|
|
||||||
{
|
|
||||||
public static void Main(string[] args)
|
|
||||||
{
|
|
||||||
CreateHostBuilder(args).Build().Run();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IHostBuilder CreateHostBuilder(string[] args) =>
|
namespace VAR.WebFormsCore.TestWebApp;
|
||||||
Host.CreateDefaultBuilder(args)
|
|
||||||
.ConfigureWebHostDefaults(webBuilder =>
|
public static class Program
|
||||||
{
|
{
|
||||||
webBuilder.UseStartup<Startup>();
|
public static void Main(string[] args)
|
||||||
});
|
{
|
||||||
|
DefaultMain.WebFormCoreMain(args);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
}
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
using Microsoft.AspNetCore.Server.Kestrel.Core;
|
|
||||||
using VAR.WebFormsCore.Code;
|
|
||||||
|
|
||||||
namespace VAR.WebFormsCore.TestWebApp
|
|
||||||
{
|
|
||||||
public class Startup
|
|
||||||
{
|
|
||||||
public void ConfigureServices(IServiceCollection services)
|
|
||||||
{
|
|
||||||
// If using Kestrel:
|
|
||||||
services.Configure<KestrelServerOptions>(options =>
|
|
||||||
{
|
|
||||||
options.AddServerHeader = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
|
|
||||||
{
|
|
||||||
app.UseGlobalRouterMiddleware(env);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
using VAR.WebFormsCore.Code;
|
using VAR.WebFormsCore.Code;
|
||||||
|
|
||||||
namespace VAR.WebFormsCore.TestWebApp;
|
namespace VAR.WebFormsCore.TestWebApp;
|
||||||
@@ -14,12 +15,12 @@ public class TestWebAppGlobalConfig : IGlobalConfig
|
|||||||
public List<string> AllowedExtensions { get; } = new()
|
public List<string> AllowedExtensions { get; } = new()
|
||||||
{ ".png", ".jpg", ".jpeg", ".gif", ".ico", ".wav", ".mp3", ".ogg", ".mp4", ".webm", ".webp", ".mkv", ".avi" };
|
{ ".png", ".jpg", ".jpeg", ".gif", ".ico", ".wav", ".mp3", ".ogg", ".mp4", ".webm", ".webp", ".mkv", ".avi" };
|
||||||
|
|
||||||
public bool IsUserAuthenticated(HttpContext context)
|
public bool IsUserAuthenticated(IWebContext context)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UserDeauthenticate(HttpContext context)
|
public void UserDeauthenticate(IWebContext context)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,10 +3,10 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net7.0</TargetFramework>
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\VAR.WebFormsCore.AspNetCore\VAR.WebFormsCore.AspNetCore.csproj" />
|
||||||
<ProjectReference Include="..\VAR.WebFormsCore\VAR.WebFormsCore.csproj" />
|
<ProjectReference Include="..\VAR.WebFormsCore\VAR.WebFormsCore.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VAR.WebFormsCore", "VAR.Web
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VAR.WebFormsCore.TestWebApp", "VAR.WebFormsCore.TestWebApp\VAR.WebFormsCore.TestWebApp.csproj", "{0D81464B-802D-4ECA-92C8-427F481A4583}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VAR.WebFormsCore.TestWebApp", "VAR.WebFormsCore.TestWebApp\VAR.WebFormsCore.TestWebApp.csproj", "{0D81464B-802D-4ECA-92C8-427F481A4583}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VAR.WebFormsCore.AspNetCore", "VAR.WebFormsCore.AspNetCore\VAR.WebFormsCore.AspNetCore.csproj", "{378B98EF-9269-4B96-B894-1B0F9B24EEC2}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@@ -18,5 +20,9 @@ Global
|
|||||||
{0D81464B-802D-4ECA-92C8-427F481A4583}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{0D81464B-802D-4ECA-92C8-427F481A4583}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{0D81464B-802D-4ECA-92C8-427F481A4583}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{0D81464B-802D-4ECA-92C8-427F481A4583}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{0D81464B-802D-4ECA-92C8-427F481A4583}.Release|Any CPU.Build.0 = Release|Any CPU
|
{0D81464B-802D-4ECA-92C8-427F481A4583}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{378B98EF-9269-4B96-B894-1B0F9B24EEC2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{378B98EF-9269-4B96-B894-1B0F9B24EEC2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{378B98EF-9269-4B96-B894-1B0F9B24EEC2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{378B98EF-9269-4B96-B894-1B0F9B24EEC2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
|||||||
@@ -3,105 +3,103 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
|
|
||||||
namespace VAR.WebFormsCore.Code
|
namespace VAR.WebFormsCore.Code;
|
||||||
|
|
||||||
|
public class Bundler
|
||||||
{
|
{
|
||||||
public class Bundler
|
#region Declarations
|
||||||
|
|
||||||
|
private readonly Assembly? _assembly;
|
||||||
|
private readonly string? _assemblyNamespace;
|
||||||
|
private List<string>? _assemblyFiles;
|
||||||
|
private readonly string? _absolutePath;
|
||||||
|
private List<string>? _absoluteFiles;
|
||||||
|
|
||||||
|
#endregion Declarations
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
|
||||||
|
private List<string> AssemblyFiles
|
||||||
{
|
{
|
||||||
#region Declarations
|
get
|
||||||
|
|
||||||
private readonly Assembly? _assembly;
|
|
||||||
private readonly string? _assemblyNamespace;
|
|
||||||
private List<string>? _assemblyFiles;
|
|
||||||
private readonly string? _absolutePath;
|
|
||||||
private List<string>? _absoluteFiles;
|
|
||||||
|
|
||||||
#endregion Declarations
|
|
||||||
|
|
||||||
#region Properties
|
|
||||||
|
|
||||||
private List<string> AssemblyFiles
|
|
||||||
{
|
{
|
||||||
get
|
if (_assemblyFiles != null) { return _assemblyFiles; }
|
||||||
|
|
||||||
|
if (_assembly == null || string.IsNullOrEmpty(_assemblyNamespace))
|
||||||
{
|
{
|
||||||
if (_assemblyFiles != null) { return _assemblyFiles; }
|
_assemblyFiles = new List<string>();
|
||||||
|
|
||||||
if (_assembly == null || string.IsNullOrEmpty(_assemblyNamespace))
|
|
||||||
{
|
|
||||||
_assemblyFiles = new List<string>();
|
|
||||||
return _assemblyFiles;
|
|
||||||
}
|
|
||||||
|
|
||||||
string assemblyPath = string.Concat(_assembly.GetName().Name, ".", _assemblyNamespace, ".");
|
|
||||||
_assemblyFiles = _assembly.GetManifestResourceNames().Where(r => r.StartsWith(assemblyPath)).ToList();
|
|
||||||
return _assemblyFiles;
|
return _assemblyFiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string assemblyPath = string.Concat(_assembly.GetName().Name, ".", _assemblyNamespace, ".");
|
||||||
|
_assemblyFiles = _assembly.GetManifestResourceNames().Where(r => r.StartsWith(assemblyPath)).ToList();
|
||||||
|
return _assemblyFiles;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private List<string> AbsoluteFiles
|
private List<string> AbsoluteFiles
|
||||||
|
{
|
||||||
|
get
|
||||||
{
|
{
|
||||||
get
|
if (_absoluteFiles != null) { return _absoluteFiles; }
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(_absolutePath))
|
||||||
{
|
{
|
||||||
if (_absoluteFiles != null) { return _absoluteFiles; }
|
_absoluteFiles = new List<string>();
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(_absolutePath))
|
|
||||||
{
|
|
||||||
_absoluteFiles = new List<string>();
|
|
||||||
return _absoluteFiles;
|
|
||||||
}
|
|
||||||
|
|
||||||
DirectoryInfo dir = new DirectoryInfo(_absolutePath);
|
|
||||||
FileInfo[] files = dir.GetFiles();
|
|
||||||
_absoluteFiles = files.OrderBy(file => file.FullName).Select(file2 => file2.FullName).ToList();
|
|
||||||
return _absoluteFiles;
|
return _absoluteFiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DirectoryInfo dir = new DirectoryInfo(_absolutePath);
|
||||||
|
FileInfo[] files = dir.GetFiles();
|
||||||
|
_absoluteFiles = files.OrderBy(file => file.FullName).Select(file2 => file2.FullName).ToList();
|
||||||
|
return _absoluteFiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion Properties
|
|
||||||
|
|
||||||
#region Creator
|
|
||||||
|
|
||||||
public Bundler(Assembly? assembly = null, string? assemblyNamespace = null, string? absolutePath = null)
|
|
||||||
{
|
|
||||||
_assembly = assembly;
|
|
||||||
_assemblyNamespace = assemblyNamespace;
|
|
||||||
_absolutePath = absolutePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Creator
|
|
||||||
|
|
||||||
#region Public methods
|
|
||||||
|
|
||||||
private static readonly Encoding Utf8Encoding = new UTF8Encoding();
|
|
||||||
|
|
||||||
public void WriteResponse(HttpResponse response, string contentType)
|
|
||||||
{
|
|
||||||
StringWriter textWriter = new StringWriter();
|
|
||||||
response.ContentType = contentType;
|
|
||||||
foreach (string fileName in AssemblyFiles)
|
|
||||||
{
|
|
||||||
Stream? resourceStream = _assembly?.GetManifestResourceStream(fileName);
|
|
||||||
if (resourceStream != null)
|
|
||||||
{
|
|
||||||
string fileContent = new StreamReader(resourceStream).ReadToEnd();
|
|
||||||
textWriter.Write(fileContent);
|
|
||||||
}
|
|
||||||
|
|
||||||
textWriter.Write("\n\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (string fileName in AbsoluteFiles)
|
|
||||||
{
|
|
||||||
string fileContent = File.ReadAllText(fileName);
|
|
||||||
textWriter.Write(fileContent);
|
|
||||||
textWriter.Write("\n\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] byteObject = Utf8Encoding.GetBytes(textWriter.ToString());
|
|
||||||
response.Body.WriteAsync(byteObject).GetAwaiter().GetResult();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Public methods
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion Properties
|
||||||
|
|
||||||
|
#region Creator
|
||||||
|
|
||||||
|
public Bundler(Assembly? assembly = null, string? assemblyNamespace = null, string? absolutePath = null)
|
||||||
|
{
|
||||||
|
_assembly = assembly;
|
||||||
|
_assemblyNamespace = assemblyNamespace;
|
||||||
|
_absolutePath = absolutePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion Creator
|
||||||
|
|
||||||
|
#region Public methods
|
||||||
|
|
||||||
|
private static readonly Encoding Utf8Encoding = new UTF8Encoding();
|
||||||
|
|
||||||
|
public void WriteResponse(IWebContext context, string contentType)
|
||||||
|
{
|
||||||
|
StringWriter textWriter = new StringWriter();
|
||||||
|
context.ResponseContentType = contentType;
|
||||||
|
foreach (string fileName in AssemblyFiles)
|
||||||
|
{
|
||||||
|
Stream? resourceStream = _assembly?.GetManifestResourceStream(fileName);
|
||||||
|
if (resourceStream != null)
|
||||||
|
{
|
||||||
|
string fileContent = new StreamReader(resourceStream).ReadToEnd();
|
||||||
|
textWriter.Write(fileContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
textWriter.Write("\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (string fileName in AbsoluteFiles)
|
||||||
|
{
|
||||||
|
string fileContent = File.ReadAllText(fileName);
|
||||||
|
textWriter.Write(fileContent);
|
||||||
|
textWriter.Write("\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] byteObject = Utf8Encoding.GetBytes(textWriter.ToString());
|
||||||
|
context.ResponseWriteBin(byteObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion Public methods
|
||||||
}
|
}
|
||||||
@@ -1,66 +1,45 @@
|
|||||||
using System;
|
using System.Text;
|
||||||
using System.Text;
|
using VAR.Json;
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using VAR.Json;
|
namespace VAR.WebFormsCore.Code;
|
||||||
|
|
||||||
namespace VAR.WebFormsCore.Code
|
public static class ExtensionMethods
|
||||||
{
|
{
|
||||||
public static class ExtensionMethods
|
#region IWebContext
|
||||||
{
|
|
||||||
#region HttpContext
|
public static string GetRequestParameter(this IWebContext context, string parameter)
|
||||||
|
{
|
||||||
public static string GetRequestParameter(this HttpContext context, string parameter)
|
if (context.RequestMethod == "POST")
|
||||||
{
|
{
|
||||||
if (context.Request.Method == "POST")
|
foreach (string key in context.RequestForm.Keys)
|
||||||
{
|
{
|
||||||
foreach (string key in context.Request.Form.Keys)
|
if (string.IsNullOrEmpty(key) == false && key == parameter)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(key) == false && key == parameter) { return context.Request.Form[key][0] ?? string.Empty; }
|
return context.RequestForm[key] ?? string.Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
foreach (string key in context.Request.Query.Keys)
|
|
||||||
{
|
foreach (string key in context.RequestQuery.Keys)
|
||||||
if (string.IsNullOrEmpty(key) == false && key == parameter) { return context.Request.Query[key][0] ?? string.Empty; }
|
{
|
||||||
}
|
if (string.IsNullOrEmpty(key) == false && key == parameter)
|
||||||
|
{
|
||||||
return string.Empty;
|
return context.RequestQuery[key] ?? string.Empty;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
private static readonly Encoding Utf8Encoding = new UTF8Encoding();
|
|
||||||
|
return string.Empty;
|
||||||
public static void ResponseObject(this HttpContext context, object obj, string contentType = "text/json")
|
}
|
||||||
{
|
|
||||||
context.Response.ContentType = contentType;
|
private static readonly Encoding Utf8Encoding = new UTF8Encoding();
|
||||||
string strObject = JsonWriter.WriteObject(obj);
|
|
||||||
byte[] byteObject = Utf8Encoding.GetBytes(strObject);
|
public static void ResponseObject(this IWebContext context, object obj, string contentType = "text/json")
|
||||||
context.Response.Body.WriteAsync(byteObject).GetAwaiter().GetResult();
|
{
|
||||||
}
|
context.ResponseContentType = contentType;
|
||||||
|
string strObject = JsonWriter.WriteObject(obj);
|
||||||
public static void SafeSet(this IHeaderDictionary header, string key, string value) { header[key] = value; }
|
byte[] byteObject = Utf8Encoding.GetBytes(strObject);
|
||||||
|
context.ResponseWriteBin(byteObject);
|
||||||
public static void SafeDel(this IHeaderDictionary header, string key)
|
}
|
||||||
{
|
|
||||||
if (header.ContainsKey(key)) { header.Remove(key); }
|
#endregion IWebContext
|
||||||
}
|
|
||||||
|
|
||||||
public static void PrepareCacheableResponse(this HttpResponse response)
|
|
||||||
{
|
|
||||||
const int secondsInDay = 86400;
|
|
||||||
response.Headers.SafeSet("Cache-Control", $"public, max-age={secondsInDay}");
|
|
||||||
string expireDate = DateTime.UtcNow.AddSeconds(secondsInDay)
|
|
||||||
.ToString("ddd, dd MMM yyyy HH:mm:ss", System.Globalization.CultureInfo.InvariantCulture);
|
|
||||||
response.Headers.SafeSet("Expires", expireDate + " GMT");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void PrepareUncacheableResponse(this HttpResponse response)
|
|
||||||
{
|
|
||||||
response.Headers.SafeSet("Cache-Control", "max-age=0, no-cache, no-store");
|
|
||||||
string expireDate = DateTime.UtcNow.AddSeconds(-1500)
|
|
||||||
.ToString("ddd, dd MMM yyyy HH:mm:ss", System.Globalization.CultureInfo.InvariantCulture);
|
|
||||||
response.Headers.SafeSet("Expires", expireDate + " GMT");
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion HttpContext
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,54 +1,52 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
|
|
||||||
namespace VAR.WebFormsCore.Code
|
namespace VAR.WebFormsCore.Code;
|
||||||
|
|
||||||
|
public static class GlobalConfig
|
||||||
{
|
{
|
||||||
public static class GlobalConfig
|
private static IGlobalConfig? _globalConfig;
|
||||||
|
|
||||||
|
public static IGlobalConfig Get()
|
||||||
{
|
{
|
||||||
private static IGlobalConfig? _globalConfig;
|
if (_globalConfig != null) { return _globalConfig; }
|
||||||
|
|
||||||
public static IGlobalConfig Get()
|
Type iGlobalConfig = typeof(IGlobalConfig);
|
||||||
|
Type? foundGlobalConfig = AppDomain.CurrentDomain
|
||||||
|
.GetAssemblies()
|
||||||
|
.SelectMany(x => x.GetTypes())
|
||||||
|
.FirstOrDefault(
|
||||||
|
x =>
|
||||||
|
x is { IsAbstract: false, IsInterface: false, IsPublic: true } &&
|
||||||
|
iGlobalConfig.IsAssignableFrom(x)
|
||||||
|
);
|
||||||
|
if(foundGlobalConfig != null)
|
||||||
{
|
{
|
||||||
if (_globalConfig != null) { return _globalConfig; }
|
_globalConfig = ObjectActivator.CreateInstance(foundGlobalConfig) as IGlobalConfig;
|
||||||
|
|
||||||
Type iGlobalConfig = typeof(IGlobalConfig);
|
|
||||||
Type? foundGlobalConfig = AppDomain.CurrentDomain
|
|
||||||
.GetAssemblies()
|
|
||||||
.SelectMany(x => x.GetTypes())
|
|
||||||
.FirstOrDefault(
|
|
||||||
x =>
|
|
||||||
x is { IsAbstract: false, IsInterface: false, IsPublic: true } &&
|
|
||||||
iGlobalConfig.IsAssignableFrom(x)
|
|
||||||
);
|
|
||||||
if(foundGlobalConfig != null)
|
|
||||||
{
|
|
||||||
_globalConfig = ObjectActivator.CreateInstance(foundGlobalConfig) as IGlobalConfig;
|
|
||||||
}
|
|
||||||
|
|
||||||
return _globalConfig ??= new DefaultGlobalConfig();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Better default global config
|
return _globalConfig ??= new DefaultGlobalConfig();
|
||||||
private class DefaultGlobalConfig : IGlobalConfig
|
}
|
||||||
{
|
|
||||||
public string Title => string.Empty;
|
|
||||||
public string TitleSeparator => string.Empty;
|
|
||||||
public string Author => string.Empty;
|
|
||||||
public string Copyright => string.Empty;
|
|
||||||
public string DefaultHandler => string.Empty;
|
|
||||||
public string LoginHandler => string.Empty;
|
|
||||||
public List<string> AllowedExtensions { get; } = new();
|
|
||||||
|
|
||||||
public bool IsUserAuthenticated(HttpContext context)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UserDeauthenticate(HttpContext context)
|
// TODO: Better default global config
|
||||||
{
|
private class DefaultGlobalConfig : IGlobalConfig
|
||||||
}
|
{
|
||||||
|
public string Title => string.Empty;
|
||||||
|
public string TitleSeparator => string.Empty;
|
||||||
|
public string Author => string.Empty;
|
||||||
|
public string Copyright => string.Empty;
|
||||||
|
public string DefaultHandler => string.Empty;
|
||||||
|
public string LoginHandler => string.Empty;
|
||||||
|
public List<string> AllowedExtensions { get; } = new();
|
||||||
|
|
||||||
|
public bool IsUserAuthenticated(IWebContext context)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UserDeauthenticate(IWebContext context)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,66 +1,64 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using VAR.WebFormsCore.Pages;
|
using VAR.WebFormsCore.Pages;
|
||||||
|
|
||||||
namespace VAR.WebFormsCore.Code
|
namespace VAR.WebFormsCore.Code;
|
||||||
|
|
||||||
|
public static class GlobalErrorHandler
|
||||||
{
|
{
|
||||||
public static class GlobalErrorHandler
|
#region Private methods
|
||||||
|
|
||||||
|
private static void ShowInternalError(IWebContext context, Exception ex)
|
||||||
{
|
{
|
||||||
#region Private methods
|
try
|
||||||
|
|
||||||
private static void ShowInternalError(HttpContext context, Exception ex)
|
|
||||||
{
|
{
|
||||||
try
|
context.ResponseStatusCode = 500;
|
||||||
|
|
||||||
|
StringBuilder sbOutput = new StringBuilder();
|
||||||
|
sbOutput.Append("<h2>Internal error</h2>");
|
||||||
|
Exception? exAux = ex;
|
||||||
|
while (exAux != null)
|
||||||
{
|
{
|
||||||
context.Response.StatusCode = 500;
|
sbOutput.Append($"<p><b>Message:</b> {exAux.Message}</p>");
|
||||||
|
sbOutput.Append($"<p><b>StackTrace:</b></p> <pre><code>{exAux.StackTrace}</code></pre>");
|
||||||
StringBuilder sbOutput = new StringBuilder();
|
exAux = exAux.InnerException;
|
||||||
sbOutput.Append("<h2>Internal error</h2>");
|
|
||||||
Exception? exAux = ex;
|
|
||||||
while (exAux != null)
|
|
||||||
{
|
|
||||||
sbOutput.Append($"<p><b>Message:</b> {exAux.Message}</p>");
|
|
||||||
sbOutput.Append($"<p><b>StackTrace:</b></p> <pre><code>{exAux.StackTrace}</code></pre>");
|
|
||||||
exAux = exAux.InnerException;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fill response to 512 bytes to avoid browser "beauty" response of errors.
|
|
||||||
long fillResponse = 512 - sbOutput.Length;
|
|
||||||
if (fillResponse > 0)
|
|
||||||
{
|
|
||||||
sbOutput.Append("<!--");
|
|
||||||
for (int i = 0; i < fillResponse; i++) { sbOutput.Append("A"); }
|
|
||||||
|
|
||||||
sbOutput.Append("-->");
|
|
||||||
}
|
|
||||||
|
|
||||||
context.Response.WriteAsync(sbOutput.ToString()).GetAwaiter().GetResult();
|
|
||||||
context.Response.Body.FlushAsync().GetAwaiter().GetResult();
|
|
||||||
}
|
}
|
||||||
catch
|
|
||||||
|
// Fill response to 512 bytes to avoid browser "beauty" response of errors.
|
||||||
|
long fillResponse = 512 - sbOutput.Length;
|
||||||
|
if (fillResponse > 0)
|
||||||
{
|
{
|
||||||
/* Nom nom nom */
|
sbOutput.Append("<!--");
|
||||||
|
for (int i = 0; i < fillResponse; i++) { sbOutput.Append("A"); }
|
||||||
|
|
||||||
|
sbOutput.Append("-->");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
context.ResponseWrite(sbOutput.ToString());
|
||||||
|
context.ResponseFlush();
|
||||||
}
|
}
|
||||||
|
catch
|
||||||
#endregion Private methods
|
|
||||||
|
|
||||||
#region Public methods
|
|
||||||
|
|
||||||
public static void HandleError(HttpContext context, Exception ex)
|
|
||||||
{
|
{
|
||||||
try
|
/* Nom nom nom */
|
||||||
{
|
|
||||||
IHttpHandler frmError = new FrmError(ex);
|
|
||||||
//context.Response.Clear();
|
|
||||||
//context.Handler = frmError;
|
|
||||||
frmError.ProcessRequest(context);
|
|
||||||
context.Response.Body.FlushAsync().GetAwaiter().GetResult();
|
|
||||||
}
|
|
||||||
catch { ShowInternalError(context, ex); }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion Public methods
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion Private methods
|
||||||
|
|
||||||
|
#region Public methods
|
||||||
|
|
||||||
|
public static void HandleError(IWebContext context, Exception ex)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
IHttpHandler frmError = new FrmError(ex);
|
||||||
|
//context.Response.Clear();
|
||||||
|
//context.Handler = frmError;
|
||||||
|
frmError.ProcessRequest(context);
|
||||||
|
context.ResponseFlush();
|
||||||
|
}
|
||||||
|
catch { ShowInternalError(context, ex); }
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion Public methods
|
||||||
}
|
}
|
||||||
111
VAR.WebFormsCore/Code/GlobalRouter.cs
Normal file
111
VAR.WebFormsCore/Code/GlobalRouter.cs
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace VAR.WebFormsCore.Code;
|
||||||
|
|
||||||
|
public class GlobalRouter
|
||||||
|
{
|
||||||
|
public void RouteRequest(IWebContext context)
|
||||||
|
{
|
||||||
|
string path = context.RequestPath;
|
||||||
|
string file = Path.GetFileName(path);
|
||||||
|
if (string.IsNullOrEmpty(file)) { file = GlobalConfig.Get().DefaultHandler; }
|
||||||
|
|
||||||
|
// Pass allowed extensions requests
|
||||||
|
string extension = Path.GetExtension(path).ToLower();
|
||||||
|
if (GlobalConfig.Get().AllowedExtensions.Contains(extension))
|
||||||
|
{
|
||||||
|
string filePath = ServerHelpers.MapContentPath(path);
|
||||||
|
if (File.Exists(filePath))
|
||||||
|
{
|
||||||
|
StaticFileHelper.ResponseStaticFile(context, filePath);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TODO: FrmNotFound
|
||||||
|
throw new Exception($"NotFound: {path}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IHttpHandler? handler = GetHandler(file);
|
||||||
|
if (handler == null)
|
||||||
|
{
|
||||||
|
// TODO: FrmNotFound
|
||||||
|
throw new Exception($"NotFound: {path}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use handler
|
||||||
|
handler.ProcessRequest(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static readonly Dictionary<string, Type> Handlers = new();
|
||||||
|
|
||||||
|
private static IHttpHandler? GetHandler(string typeName)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(typeName)) { return null; }
|
||||||
|
|
||||||
|
Type? type;
|
||||||
|
lock (Handlers)
|
||||||
|
{
|
||||||
|
if (Handlers.TryGetValue(typeName, out type))
|
||||||
|
{
|
||||||
|
IHttpHandler? handler = ObjectActivator.CreateInstance(type) as IHttpHandler;
|
||||||
|
return handler;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search type on executing assembly
|
||||||
|
Assembly asm = Assembly.GetExecutingAssembly();
|
||||||
|
Type[] types = asm.GetTypes();
|
||||||
|
foreach (Type typeAux in types)
|
||||||
|
{
|
||||||
|
if (typeAux.FullName?.EndsWith(typeName) == true)
|
||||||
|
{
|
||||||
|
type = typeAux;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search type on all loaded assemblies
|
||||||
|
if (type == null)
|
||||||
|
{
|
||||||
|
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
|
||||||
|
foreach (Assembly asmAux in assemblies)
|
||||||
|
{
|
||||||
|
types = asmAux.GetTypes();
|
||||||
|
foreach (Type typeAux in types)
|
||||||
|
{
|
||||||
|
if (typeAux.FullName?.EndsWith(typeName) != true) { continue; }
|
||||||
|
|
||||||
|
type = typeAux;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type != null) { break; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use found type
|
||||||
|
if (type != null)
|
||||||
|
{
|
||||||
|
IHttpHandler? handler = ObjectActivator.CreateInstance(type) as IHttpHandler;
|
||||||
|
if (handler != null)
|
||||||
|
{
|
||||||
|
lock (Handlers)
|
||||||
|
{
|
||||||
|
if (Handlers.ContainsKey(typeName) == false)
|
||||||
|
{
|
||||||
|
Handlers.Add(typeName, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,158 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
|
|
||||||
namespace VAR.WebFormsCore.Code
|
|
||||||
{
|
|
||||||
public class GlobalRouterMiddleware
|
|
||||||
{
|
|
||||||
public GlobalRouterMiddleware(RequestDelegate next, IWebHostEnvironment env)
|
|
||||||
{
|
|
||||||
ServerHelpers.SetContentRoot(env.ContentRootPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task Invoke(HttpContext httpContext)
|
|
||||||
{
|
|
||||||
httpContext.Response.Headers.SafeDel("Server");
|
|
||||||
httpContext.Response.Headers.SafeDel("X-Powered-By");
|
|
||||||
httpContext.Response.Headers.SafeSet("X-Content-Type-Options", "nosniff");
|
|
||||||
httpContext.Response.Headers.SafeSet("X-Frame-Options", "SAMEORIGIN");
|
|
||||||
httpContext.Response.Headers.SafeSet("X-XSS-Protection", "1; mode=block");
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
RouteRequest(httpContext);
|
|
||||||
await httpContext.Response.Body.FlushAsync();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
if (IsIgnoreException(ex) == false)
|
|
||||||
{
|
|
||||||
// TODO: Implement better error logging
|
|
||||||
Console.WriteLine("!!!!!!!!!!");
|
|
||||||
Console.Write("Message: {0}\nStacktrace: {1}\n", ex.Message, ex.StackTrace);
|
|
||||||
|
|
||||||
GlobalErrorHandler.HandleError(httpContext, ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static bool IsIgnoreException(Exception ex) { return ex is ThreadAbortException; }
|
|
||||||
|
|
||||||
private void RouteRequest(HttpContext context)
|
|
||||||
{
|
|
||||||
string path = context.Request.Path;
|
|
||||||
string file = Path.GetFileName(path);
|
|
||||||
if (string.IsNullOrEmpty(file)) { file = GlobalConfig.Get().DefaultHandler; }
|
|
||||||
|
|
||||||
// Pass allowed extensions requests
|
|
||||||
string extension = Path.GetExtension(path).ToLower();
|
|
||||||
if (GlobalConfig.Get().AllowedExtensions.Contains(extension))
|
|
||||||
{
|
|
||||||
string filePath = ServerHelpers.MapContentPath(path);
|
|
||||||
if (File.Exists(filePath))
|
|
||||||
{
|
|
||||||
StaticFileHelper.ResponseStaticFile(context, filePath);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// TODO: FrmNotFound
|
|
||||||
throw new Exception($"NotFound: {path}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
IHttpHandler? handler = GetHandler(file);
|
|
||||||
if (handler == null)
|
|
||||||
{
|
|
||||||
// TODO: FrmNotFound
|
|
||||||
throw new Exception($"NotFound: {path}");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use handler
|
|
||||||
handler.ProcessRequest(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static readonly Dictionary<string, Type> Handlers = new();
|
|
||||||
|
|
||||||
private static IHttpHandler? GetHandler(string typeName)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(typeName)) { return null; }
|
|
||||||
|
|
||||||
Type? type;
|
|
||||||
lock (Handlers)
|
|
||||||
{
|
|
||||||
if (Handlers.TryGetValue(typeName, out type))
|
|
||||||
{
|
|
||||||
IHttpHandler? handler = ObjectActivator.CreateInstance(type) as IHttpHandler;
|
|
||||||
return handler;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Search type on executing assembly
|
|
||||||
Assembly asm = Assembly.GetExecutingAssembly();
|
|
||||||
Type[] types = asm.GetTypes();
|
|
||||||
foreach (Type typeAux in types)
|
|
||||||
{
|
|
||||||
if (typeAux.FullName?.EndsWith(typeName) == true)
|
|
||||||
{
|
|
||||||
type = typeAux;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Search type on all loaded assemblies
|
|
||||||
if (type == null)
|
|
||||||
{
|
|
||||||
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
|
|
||||||
foreach (Assembly asmAux in assemblies)
|
|
||||||
{
|
|
||||||
types = asmAux.GetTypes();
|
|
||||||
foreach (Type typeAux in types)
|
|
||||||
{
|
|
||||||
if (typeAux.FullName?.EndsWith(typeName) != true) { continue; }
|
|
||||||
|
|
||||||
type = typeAux;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type != null) { break; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use found type
|
|
||||||
if (type != null)
|
|
||||||
{
|
|
||||||
IHttpHandler? handler = ObjectActivator.CreateInstance(type) as IHttpHandler;
|
|
||||||
if (handler != null)
|
|
||||||
{
|
|
||||||
lock (Handlers)
|
|
||||||
{
|
|
||||||
Handlers.TryAdd(typeName, type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return handler;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class GlobalRouterMiddlewareExtensions
|
|
||||||
{
|
|
||||||
public static IApplicationBuilder UseGlobalRouterMiddleware(
|
|
||||||
this IApplicationBuilder builder,
|
|
||||||
IWebHostEnvironment env
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return builder.UseMiddleware<GlobalRouterMiddleware>(env);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,19 +1,17 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
|
|
||||||
namespace VAR.WebFormsCore.Code
|
namespace VAR.WebFormsCore.Code;
|
||||||
|
|
||||||
|
public interface IGlobalConfig
|
||||||
{
|
{
|
||||||
public interface IGlobalConfig
|
string Title { get; }
|
||||||
{
|
string TitleSeparator { get; }
|
||||||
string Title { get; }
|
string Author { get; }
|
||||||
string TitleSeparator { get; }
|
string Copyright { get; }
|
||||||
string Author { get; }
|
string DefaultHandler { get; }
|
||||||
string Copyright { get; }
|
string LoginHandler { get; }
|
||||||
string DefaultHandler { get; }
|
List<string> AllowedExtensions { get; }
|
||||||
string LoginHandler { get; }
|
|
||||||
List<string> AllowedExtensions { get; }
|
|
||||||
|
|
||||||
bool IsUserAuthenticated(HttpContext context);
|
bool IsUserAuthenticated(IWebContext context);
|
||||||
void UserDeauthenticate(HttpContext context);
|
void UserDeauthenticate(IWebContext context);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,6 @@
|
|||||||
using Microsoft.AspNetCore.Http;
|
namespace VAR.WebFormsCore.Code;
|
||||||
|
|
||||||
namespace VAR.WebFormsCore.Code
|
public interface IHttpHandler
|
||||||
{
|
{
|
||||||
public interface IHttpHandler
|
void ProcessRequest(IWebContext context);
|
||||||
{
|
|
||||||
void ProcessRequest(HttpContext context);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
25
VAR.WebFormsCore/Code/IWebContext.cs
Normal file
25
VAR.WebFormsCore/Code/IWebContext.cs
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace VAR.WebFormsCore.Code;
|
||||||
|
|
||||||
|
public interface IWebContext
|
||||||
|
{
|
||||||
|
string RequestPath { get; }
|
||||||
|
string RequestMethod { get; }
|
||||||
|
Dictionary<string, string?> RequestForm { get; }
|
||||||
|
Dictionary<string, string?> RequestQuery { get; }
|
||||||
|
Dictionary<string, string?> RequestHeader { get; }
|
||||||
|
|
||||||
|
void ResponseWrite(string text);
|
||||||
|
void ResponseWriteBin(byte[] content);
|
||||||
|
void ResponseFlush();
|
||||||
|
void ResponseRedirect(string url);
|
||||||
|
|
||||||
|
bool ResponseHasStarted { get; }
|
||||||
|
int ResponseStatusCode { get; set; }
|
||||||
|
string? ResponseContentType { get; set; }
|
||||||
|
void SetResponseHeader(string key, string value);
|
||||||
|
|
||||||
|
void PrepareCacheableResponse();
|
||||||
|
void PrepareUncacheableResponse();
|
||||||
|
}
|
||||||
@@ -2,95 +2,94 @@
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using VAR.Json;
|
using VAR.Json;
|
||||||
|
|
||||||
namespace VAR.WebFormsCore.Code
|
namespace VAR.WebFormsCore.Code;
|
||||||
|
|
||||||
|
public static class MultiLang
|
||||||
{
|
{
|
||||||
public static class MultiLang
|
private static string GetPrivatePath(string baseDir, string fileName)
|
||||||
{
|
{
|
||||||
private static string GetPrivatePath(string baseDir, string fileName)
|
string currentDir = Directory.GetCurrentDirectory();
|
||||||
|
string privatePath = Path.Combine(currentDir, baseDir);
|
||||||
|
while (Directory.Exists(privatePath) == false)
|
||||||
{
|
{
|
||||||
string currentDir = Directory.GetCurrentDirectory();
|
DirectoryInfo? dirInfo = Directory.GetParent(currentDir);
|
||||||
string privatePath = Path.Combine(currentDir, baseDir);
|
if (dirInfo == null) { break; }
|
||||||
while (Directory.Exists(privatePath) == false)
|
|
||||||
{
|
|
||||||
DirectoryInfo? dirInfo = Directory.GetParent(currentDir);
|
|
||||||
if (dirInfo == null) { break; }
|
|
||||||
|
|
||||||
currentDir = dirInfo.FullName;
|
currentDir = dirInfo.FullName;
|
||||||
privatePath = Path.Combine(currentDir, baseDir);
|
privatePath = Path.Combine(currentDir, baseDir);
|
||||||
}
|
|
||||||
|
|
||||||
return Path.Combine(privatePath, fileName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Dictionary<string, Dictionary<string, object>?>? _literals;
|
return Path.Combine(privatePath, fileName);
|
||||||
|
}
|
||||||
|
|
||||||
private static void InitializeLiterals()
|
private static Dictionary<string, Dictionary<string, object>?>? _literals;
|
||||||
|
|
||||||
|
private static void InitializeLiterals()
|
||||||
|
{
|
||||||
|
_literals = new Dictionary<string, Dictionary<string, object>?>();
|
||||||
|
|
||||||
|
JsonParser jsonParser = new JsonParser();
|
||||||
|
foreach (string lang in new[] {"en", "es"})
|
||||||
{
|
{
|
||||||
_literals = new Dictionary<string, Dictionary<string, object>?>();
|
string filePath = GetPrivatePath("Resources", $"Literals.{lang}.json");
|
||||||
|
if (File.Exists(filePath) == false) { continue; }
|
||||||
|
|
||||||
JsonParser jsonParser = new JsonParser();
|
string strJsonLiteralsLanguage = File.ReadAllText(filePath);
|
||||||
foreach (string lang in new[] {"en", "es"})
|
object result = jsonParser.Parse(strJsonLiteralsLanguage);
|
||||||
{
|
_literals.Add(lang, result as Dictionary<string, object>);
|
||||||
string filePath = GetPrivatePath("Resources", $"Literals.{lang}.json");
|
|
||||||
if (File.Exists(filePath) == false) { continue; }
|
|
||||||
|
|
||||||
string strJsonLiteralsLanguage = File.ReadAllText(filePath);
|
|
||||||
object result = jsonParser.Parse(strJsonLiteralsLanguage);
|
|
||||||
_literals.Add(lang, result as Dictionary<string, object>);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private const string DefaultLanguage = "en";
|
|
||||||
|
|
||||||
private static string GetUserLanguage()
|
|
||||||
{
|
|
||||||
// TODO: Needs replacement for ctx.Request.UserLanguages
|
|
||||||
//HttpContext ctx = HttpContext.Current;
|
|
||||||
//if (ctx != null)
|
|
||||||
//{
|
|
||||||
// if (ctx.Items["UserLang"] != null)
|
|
||||||
// {
|
|
||||||
// return (string)ctx.Items["UserLang"];
|
|
||||||
// }
|
|
||||||
|
|
||||||
// IEnumerable<string> userLanguages = ctx.Request.UserLanguages
|
|
||||||
// .Select(lang =>
|
|
||||||
// {
|
|
||||||
// if (lang.Contains(";"))
|
|
||||||
// {
|
|
||||||
// lang = lang.Split(';')[0];
|
|
||||||
// }
|
|
||||||
// if (lang.Contains("-"))
|
|
||||||
// {
|
|
||||||
// lang = lang.Split('-')[0];
|
|
||||||
// }
|
|
||||||
// return lang.ToLower();
|
|
||||||
// })
|
|
||||||
// .Where(lang => _literals.ContainsKey(lang));
|
|
||||||
// string userLang = userLanguages.FirstOrDefault() ?? _defaultLanguage;
|
|
||||||
|
|
||||||
// ctx.Items["UserLang"] = userLang;
|
|
||||||
// return userLang;
|
|
||||||
//}
|
|
||||||
return DefaultLanguage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string GetLiteral(string resource, string? culture = null)
|
|
||||||
{
|
|
||||||
if (_literals == null) { InitializeLiterals(); }
|
|
||||||
|
|
||||||
culture ??= GetUserLanguage();
|
|
||||||
|
|
||||||
if (_literals == null || _literals.ContainsKey(culture) == false) { return resource; }
|
|
||||||
|
|
||||||
Dictionary<string, object>? literalCurrentCulture = _literals[culture];
|
|
||||||
|
|
||||||
if (literalCurrentCulture == null || literalCurrentCulture.ContainsKey(resource) == false)
|
|
||||||
{
|
|
||||||
return resource;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (literalCurrentCulture[resource] as string) ?? resource;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private const string DefaultLanguage = "en";
|
||||||
|
|
||||||
|
private static string GetUserLanguage()
|
||||||
|
{
|
||||||
|
// TODO: Needs replacement for ctx.Request.UserLanguages
|
||||||
|
//HttpContext ctx = HttpContext.Current;
|
||||||
|
//if (ctx != null)
|
||||||
|
//{
|
||||||
|
// if (ctx.Items["UserLang"] != null)
|
||||||
|
// {
|
||||||
|
// return (string)ctx.Items["UserLang"];
|
||||||
|
// }
|
||||||
|
|
||||||
|
// IEnumerable<string> userLanguages = ctx.Request.UserLanguages
|
||||||
|
// .Select(lang =>
|
||||||
|
// {
|
||||||
|
// if (lang.Contains(";"))
|
||||||
|
// {
|
||||||
|
// lang = lang.Split(';')[0];
|
||||||
|
// }
|
||||||
|
// if (lang.Contains("-"))
|
||||||
|
// {
|
||||||
|
// lang = lang.Split('-')[0];
|
||||||
|
// }
|
||||||
|
// return lang.ToLower();
|
||||||
|
// })
|
||||||
|
// .Where(lang => _literals.ContainsKey(lang));
|
||||||
|
// string userLang = userLanguages.FirstOrDefault() ?? _defaultLanguage;
|
||||||
|
|
||||||
|
// ctx.Items["UserLang"] = userLang;
|
||||||
|
// return userLang;
|
||||||
|
//}
|
||||||
|
return DefaultLanguage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string GetLiteral(string resource, string? culture = null)
|
||||||
|
{
|
||||||
|
if (_literals == null) { InitializeLiterals(); }
|
||||||
|
|
||||||
|
culture ??= GetUserLanguage();
|
||||||
|
|
||||||
|
if (_literals == null || _literals.ContainsKey(culture) == false) { return resource; }
|
||||||
|
|
||||||
|
Dictionary<string, object>? literalCurrentCulture = _literals[culture];
|
||||||
|
|
||||||
|
if (literalCurrentCulture == null || literalCurrentCulture.ContainsKey(resource) == false)
|
||||||
|
{
|
||||||
|
return resource;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (literalCurrentCulture[resource] as string) ?? resource;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -2,32 +2,31 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
|
|
||||||
namespace VAR.WebFormsCore.Code
|
namespace VAR.WebFormsCore.Code;
|
||||||
|
|
||||||
|
public static class ObjectActivator
|
||||||
{
|
{
|
||||||
public static class ObjectActivator
|
private static readonly Dictionary<Type, Func<object>> Creators = new();
|
||||||
|
|
||||||
|
private static Func<object> GetLambdaNew(Type type)
|
||||||
{
|
{
|
||||||
private static readonly Dictionary<Type, Func<object>> Creators = new();
|
lock (Creators)
|
||||||
|
|
||||||
private static Func<object> GetLambdaNew(Type type)
|
|
||||||
{
|
{
|
||||||
lock (Creators)
|
if (Creators.TryGetValue(type, out var creator)) { return creator; }
|
||||||
{
|
|
||||||
if (Creators.TryGetValue(type, out var creator)) { return creator; }
|
|
||||||
|
|
||||||
NewExpression newExp = Expression.New(type);
|
NewExpression newExp = Expression.New(type);
|
||||||
LambdaExpression lambda = Expression.Lambda(typeof(Func<object>), newExp);
|
LambdaExpression lambda = Expression.Lambda(typeof(Func<object>), newExp);
|
||||||
Func<object> compiledLambdaNew = (Func<object>) lambda.Compile();
|
Func<object> compiledLambdaNew = (Func<object>) lambda.Compile();
|
||||||
|
|
||||||
Creators.Add(type, compiledLambdaNew);
|
Creators.Add(type, compiledLambdaNew);
|
||||||
|
|
||||||
return Creators[type];
|
return Creators[type];
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static object CreateInstance(Type type)
|
|
||||||
{
|
|
||||||
Func<object> creator = GetLambdaNew(type);
|
|
||||||
return creator();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static object CreateInstance(Type type)
|
||||||
|
{
|
||||||
|
Func<object> creator = GetLambdaNew(type);
|
||||||
|
return creator();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,23 +1,21 @@
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
|
|
||||||
namespace VAR.WebFormsCore.Code
|
namespace VAR.WebFormsCore.Code;
|
||||||
|
|
||||||
|
public class ScriptsBundler : IHttpHandler
|
||||||
{
|
{
|
||||||
public class ScriptsBundler : IHttpHandler
|
#region IHttpHandler
|
||||||
|
|
||||||
|
public void ProcessRequest(IWebContext context)
|
||||||
{
|
{
|
||||||
#region IHttpHandler
|
Bundler bundler = new Bundler(
|
||||||
|
assembly: Assembly.GetExecutingAssembly(),
|
||||||
public void ProcessRequest(HttpContext context)
|
assemblyNamespace: "Scripts",
|
||||||
{
|
absolutePath: ServerHelpers.MapContentPath("Scripts")
|
||||||
Bundler bundler = new Bundler(
|
);
|
||||||
assembly: Assembly.GetExecutingAssembly(),
|
context.PrepareCacheableResponse();
|
||||||
assemblyNamespace: "Scripts",
|
bundler.WriteResponse(context, "text/javascript");
|
||||||
absolutePath: ServerHelpers.MapContentPath("Scripts")
|
|
||||||
);
|
|
||||||
context.Response.PrepareCacheableResponse();
|
|
||||||
bundler.WriteResponse(context.Response, "text/javascript");
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion IHttpHandler
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion IHttpHandler
|
||||||
}
|
}
|
||||||
@@ -1,118 +1,117 @@
|
|||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace VAR.WebFormsCore.Code
|
namespace VAR.WebFormsCore.Code;
|
||||||
|
|
||||||
|
public static class ServerHelpers
|
||||||
{
|
{
|
||||||
public static class ServerHelpers
|
private static string? _contentRoot;
|
||||||
|
|
||||||
|
public static void SetContentRoot(string contentRoot)
|
||||||
{
|
{
|
||||||
private static string? _contentRoot;
|
_contentRoot = contentRoot;
|
||||||
|
}
|
||||||
|
|
||||||
public static void SetContentRoot(string contentRoot)
|
public static string MapContentPath(string path)
|
||||||
|
{
|
||||||
|
string mappedPath = string.Concat(_contentRoot, "/", path);
|
||||||
|
return mappedPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string HtmlEncode(string text)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(text))
|
||||||
{
|
{
|
||||||
_contentRoot = contentRoot;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string MapContentPath(string path)
|
StringBuilder sbResult = new();
|
||||||
|
|
||||||
|
foreach (var ch in text)
|
||||||
{
|
{
|
||||||
string mappedPath = string.Concat(_contentRoot, "/", path);
|
switch (ch)
|
||||||
return mappedPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string HtmlEncode(string text)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(text))
|
|
||||||
{
|
{
|
||||||
return text;
|
case '<':
|
||||||
}
|
sbResult.Append("<");
|
||||||
|
break;
|
||||||
StringBuilder sbResult = new();
|
case '>':
|
||||||
|
sbResult.Append(">");
|
||||||
foreach (var ch in text)
|
break;
|
||||||
{
|
case '"':
|
||||||
switch (ch)
|
sbResult.Append(""");
|
||||||
|
break;
|
||||||
|
case '\'':
|
||||||
|
sbResult.Append("'");
|
||||||
|
break;
|
||||||
|
case '&':
|
||||||
|
sbResult.Append("&");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
{
|
{
|
||||||
case '<':
|
if (ch > 127)
|
||||||
sbResult.Append("<");
|
|
||||||
break;
|
|
||||||
case '>':
|
|
||||||
sbResult.Append(">");
|
|
||||||
break;
|
|
||||||
case '"':
|
|
||||||
sbResult.Append(""");
|
|
||||||
break;
|
|
||||||
case '\'':
|
|
||||||
sbResult.Append("'");
|
|
||||||
break;
|
|
||||||
case '&':
|
|
||||||
sbResult.Append("&");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
{
|
{
|
||||||
if (ch > 127)
|
sbResult.Append("&#");
|
||||||
{
|
sbResult.Append(((int)ch).ToString(NumberFormatInfo.InvariantInfo));
|
||||||
sbResult.Append("&#");
|
sbResult.Append(';');
|
||||||
sbResult.Append(((int)ch).ToString(NumberFormatInfo.InvariantInfo));
|
|
||||||
sbResult.Append(';');
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sbResult.Append(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sbResult.Append(ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return sbResult.ToString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string UrlEncode(string text)
|
return sbResult.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string UrlEncode(string text)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(text))
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(text))
|
return text;
|
||||||
{
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
|
|
||||||
StringBuilder sbResult = new();
|
|
||||||
|
|
||||||
foreach (var ch in text)
|
|
||||||
{
|
|
||||||
if (ch == ' ')
|
|
||||||
{
|
|
||||||
sbResult.Append('+');
|
|
||||||
}
|
|
||||||
else if (IsUrlSafe(ch) == false)
|
|
||||||
{
|
|
||||||
sbResult.Append($"%{ch:X02}");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sbResult.Append(ch);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return sbResult.ToString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool IsUrlSafe(char ch)
|
StringBuilder sbResult = new();
|
||||||
|
|
||||||
|
foreach (var ch in text)
|
||||||
{
|
{
|
||||||
if (
|
if (ch == ' ')
|
||||||
(ch >= 'a' && ch <= 'z') ||
|
|
||||||
(ch >= 'A' && ch <= 'Z') ||
|
|
||||||
(ch >= '0' && ch <= '9') ||
|
|
||||||
ch == '-' ||
|
|
||||||
ch == '_' ||
|
|
||||||
ch == '.' ||
|
|
||||||
ch == '!' ||
|
|
||||||
ch == '*' ||
|
|
||||||
ch == '(' ||
|
|
||||||
ch == ')')
|
|
||||||
{
|
{
|
||||||
return true;
|
sbResult.Append('+');
|
||||||
|
}
|
||||||
|
else if (IsUrlSafe(ch) == false)
|
||||||
|
{
|
||||||
|
sbResult.Append($"%{ch:X02}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sbResult.Append(ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return sbResult.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsUrlSafe(char ch)
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
(ch >= 'a' && ch <= 'z') ||
|
||||||
|
(ch >= 'A' && ch <= 'Z') ||
|
||||||
|
(ch >= '0' && ch <= '9') ||
|
||||||
|
ch == '-' ||
|
||||||
|
ch == '_' ||
|
||||||
|
ch == '.' ||
|
||||||
|
ch == '!' ||
|
||||||
|
ch == '*' ||
|
||||||
|
ch == '(' ||
|
||||||
|
ch == ')')
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,84 +1,82 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
|
|
||||||
namespace VAR.WebFormsCore.Code
|
namespace VAR.WebFormsCore.Code;
|
||||||
|
|
||||||
|
public static class StaticFileHelper
|
||||||
{
|
{
|
||||||
public static class StaticFileHelper
|
private static readonly Dictionary<string, string> MimeTypeByExtension = new()
|
||||||
{
|
{
|
||||||
private static readonly Dictionary<string, string> MimeTypeByExtension = new()
|
{".aac", "audio/aac"},
|
||||||
{
|
{".abw", "application/x-abiword"},
|
||||||
{".aac", "audio/aac"},
|
{".arc", "application/octet-stream"},
|
||||||
{".abw", "application/x-abiword"},
|
{".avi", "video/x-msvideo"},
|
||||||
{".arc", "application/octet-stream"},
|
{".azw", "application/vnd.amazon.ebook"},
|
||||||
{".avi", "video/x-msvideo"},
|
{".bin", "application/octet-stream"},
|
||||||
{".azw", "application/vnd.amazon.ebook"},
|
{".bz", "application/x-bzip"},
|
||||||
{".bin", "application/octet-stream"},
|
{".bz2", "application/x-bzip2"},
|
||||||
{".bz", "application/x-bzip"},
|
{".csh", "application/x-csh"},
|
||||||
{".bz2", "application/x-bzip2"},
|
{".css", "text/css"},
|
||||||
{".csh", "application/x-csh"},
|
{".csv", "text/csv"},
|
||||||
{".css", "text/css"},
|
{".doc", "application/msword"},
|
||||||
{".csv", "text/csv"},
|
{".epub", "application/epub+zip"},
|
||||||
{".doc", "application/msword"},
|
{".gif", "image/gif"},
|
||||||
{".epub", "application/epub+zip"},
|
{".htm", "text/html"},
|
||||||
{".gif", "image/gif"},
|
{".html", "text/html"},
|
||||||
{".htm", "text/html"},
|
{".ico", "image/x-icon"},
|
||||||
{".html", "text/html"},
|
{".ics", "text/calendar"},
|
||||||
{".ico", "image/x-icon"},
|
{".jar", "application/java-archive"},
|
||||||
{".ics", "text/calendar"},
|
{".jpg", "image/jpeg"},
|
||||||
{".jar", "application/java-archive"},
|
{".jpeg", "image/jpeg"},
|
||||||
{".jpg", "image/jpeg"},
|
{".js", "application/javascript"},
|
||||||
{".jpeg", "image/jpeg"},
|
{".json", "application/json"},
|
||||||
{".js", "application/javascript"},
|
{".mid", "audio/midi"},
|
||||||
{".json", "application/json"},
|
{".midi", "audio/midi"},
|
||||||
{".mid", "audio/midi"},
|
{".mpeg", "video/mpeg"},
|
||||||
{".midi", "audio/midi"},
|
{".mpkg", "application/vnd.apple.installer+xml"},
|
||||||
{".mpeg", "video/mpeg"},
|
{".odp", "application/vnd.oasis.opendocument.presentation"},
|
||||||
{".mpkg", "application/vnd.apple.installer+xml"},
|
{".ods", "application/vnd.oasis.opendocument.spreadsheet"},
|
||||||
{".odp", "application/vnd.oasis.opendocument.presentation"},
|
{".odt", "application/vnd.oasis.opendocument.text"},
|
||||||
{".ods", "application/vnd.oasis.opendocument.spreadsheet"},
|
{".oga", "audio/ogg"},
|
||||||
{".odt", "application/vnd.oasis.opendocument.text"},
|
{".ogv", "video/ogg"},
|
||||||
{".oga", "audio/ogg"},
|
{".ogx", "application/ogg"},
|
||||||
{".ogv", "video/ogg"},
|
{".png", "image/png"},
|
||||||
{".ogx", "application/ogg"},
|
{".pdf", "application/pdf"},
|
||||||
{".png", "image/png"},
|
{".ppt", "application/vnd.ms-powerpoint"},
|
||||||
{".pdf", "application/pdf"},
|
{".rar", "application/x-rar-compressed"},
|
||||||
{".ppt", "application/vnd.ms-powerpoint"},
|
{".rtf", "application/rtf"},
|
||||||
{".rar", "application/x-rar-compressed"},
|
{".sh", "application/x-sh"},
|
||||||
{".rtf", "application/rtf"},
|
{".svg", "image/svg+xml"},
|
||||||
{".sh", "application/x-sh"},
|
{".swf", "application/x-shockwave-flash"},
|
||||||
{".svg", "image/svg+xml"},
|
{".tar", "application/x-tar"},
|
||||||
{".swf", "application/x-shockwave-flash"},
|
{".tiff", "image/tiff"},
|
||||||
{".tar", "application/x-tar"},
|
{".tif", "image/tiff"},
|
||||||
{".tiff", "image/tiff"},
|
{".ttf", "font/ttf"},
|
||||||
{".tif", "image/tiff"},
|
{".vsd", "application/vnd.visio"},
|
||||||
{".ttf", "font/ttf"},
|
{".wav", "audio/x-wav"},
|
||||||
{".vsd", "application/vnd.visio"},
|
{".weba", "audio/webm"},
|
||||||
{".wav", "audio/x-wav"},
|
{".webm", "video/webm"},
|
||||||
{".weba", "audio/webm"},
|
{".webp", "image/webp"},
|
||||||
{".webm", "video/webm"},
|
{".woff", "font/woff"},
|
||||||
{".webp", "image/webp"},
|
{".woff2", "font/woff2"},
|
||||||
{".woff", "font/woff"},
|
{".xhtml", "application/xhtml+xml"},
|
||||||
{".woff2", "font/woff2"},
|
{".xls", "application/vnd.ms-excel"},
|
||||||
{".xhtml", "application/xhtml+xml"},
|
{".xml", "application/xml"},
|
||||||
{".xls", "application/vnd.ms-excel"},
|
{".xul", "application/vnd.mozilla.xul+xml"},
|
||||||
{".xml", "application/xml"},
|
{".zip", "application/zip"},
|
||||||
{".xul", "application/vnd.mozilla.xul+xml"},
|
{".7z", "application/x-7z-compressed"},
|
||||||
{".zip", "application/zip"},
|
};
|
||||||
{".7z", "application/x-7z-compressed"},
|
|
||||||
};
|
|
||||||
|
|
||||||
public static void ResponseStaticFile(HttpContext context, string filePath)
|
public static void ResponseStaticFile(IWebContext context, string filePath)
|
||||||
{
|
{
|
||||||
string extension = Path.GetExtension(filePath).ToLower();
|
string extension = Path.GetExtension(filePath).ToLower();
|
||||||
MimeTypeByExtension.TryGetValue(extension, out string? contentType);
|
MimeTypeByExtension.TryGetValue(extension, out string? contentType);
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(contentType) == false) { context.Response.ContentType = contentType; }
|
if (string.IsNullOrEmpty(contentType) == false) { context.ResponseContentType = contentType; }
|
||||||
|
|
||||||
context.Response.PrepareCacheableResponse();
|
context.PrepareCacheableResponse();
|
||||||
|
|
||||||
byte[] fileData = File.ReadAllBytes(filePath);
|
byte[] fileData = File.ReadAllBytes(filePath);
|
||||||
context.Response.Body.WriteAsync(fileData).GetAwaiter().GetResult();
|
context.ResponseWriteBin(fileData);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,23 +1,21 @@
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
|
|
||||||
namespace VAR.WebFormsCore.Code
|
namespace VAR.WebFormsCore.Code;
|
||||||
|
|
||||||
|
public class StylesBundler : IHttpHandler
|
||||||
{
|
{
|
||||||
public class StylesBundler : IHttpHandler
|
#region IHttpHandler
|
||||||
|
|
||||||
|
public void ProcessRequest(IWebContext context)
|
||||||
{
|
{
|
||||||
#region IHttpHandler
|
Bundler bundler = new Bundler(
|
||||||
|
assembly: Assembly.GetExecutingAssembly(),
|
||||||
public void ProcessRequest(HttpContext context)
|
assemblyNamespace: "Styles",
|
||||||
{
|
absolutePath: ServerHelpers.MapContentPath("Styles")
|
||||||
Bundler bundler = new Bundler(
|
);
|
||||||
assembly: Assembly.GetExecutingAssembly(),
|
context.PrepareCacheableResponse();
|
||||||
assemblyNamespace: "Styles",
|
bundler.WriteResponse(context, "text/css");
|
||||||
absolutePath: ServerHelpers.MapContentPath("Styles")
|
|
||||||
);
|
|
||||||
context.Response.PrepareCacheableResponse();
|
|
||||||
bundler.WriteResponse(context.Response, "text/css");
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion IHttpHandler
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion IHttpHandler
|
||||||
}
|
}
|
||||||
@@ -1,28 +1,27 @@
|
|||||||
namespace VAR.WebFormsCore.Code
|
namespace VAR.WebFormsCore.Code;
|
||||||
|
|
||||||
|
public class Unit
|
||||||
{
|
{
|
||||||
public class Unit
|
private readonly int _value;
|
||||||
|
private readonly UnitType _unitType;
|
||||||
|
|
||||||
|
public Unit(int value, UnitType type)
|
||||||
{
|
{
|
||||||
private readonly int _value;
|
_value = value;
|
||||||
private readonly UnitType _unitType;
|
_unitType = type;
|
||||||
|
|
||||||
public Unit(int value, UnitType type)
|
|
||||||
{
|
|
||||||
_value = value;
|
|
||||||
_unitType = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
if (_unitType == UnitType.Pixel) { return $"{_value}px"; }
|
|
||||||
|
|
||||||
if (_unitType == UnitType.Percentage) { return $"{_value}%"; }
|
|
||||||
|
|
||||||
return string.Empty;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum UnitType
|
public override string ToString()
|
||||||
{
|
{
|
||||||
Pixel, Percentage,
|
if (_unitType == UnitType.Pixel) { return $"{_value}px"; }
|
||||||
|
|
||||||
|
if (_unitType == UnitType.Percentage) { return $"{_value}%"; }
|
||||||
|
|
||||||
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum UnitType
|
||||||
|
{
|
||||||
|
Pixel, Percentage,
|
||||||
}
|
}
|
||||||
@@ -1,42 +1,41 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace VAR.WebFormsCore.Controls
|
namespace VAR.WebFormsCore.Controls;
|
||||||
|
|
||||||
|
public class Button : Control, IReceivePostbackEvent
|
||||||
{
|
{
|
||||||
public class Button : Control, IReceivePostbackEvent
|
public Button() { CssClass = "button"; }
|
||||||
|
|
||||||
|
private string _text = string.Empty;
|
||||||
|
|
||||||
|
public string Text
|
||||||
{
|
{
|
||||||
public Button() { CssClass = "button"; }
|
get => _text;
|
||||||
|
set => _text = value;
|
||||||
private string _text = string.Empty;
|
|
||||||
|
|
||||||
public string Text
|
|
||||||
{
|
|
||||||
get => _text;
|
|
||||||
set => _text = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string OnClientClick { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
public string CommandArgument { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
public event EventHandler? Click;
|
|
||||||
|
|
||||||
protected override void Render(TextWriter textWriter)
|
|
||||||
{
|
|
||||||
textWriter.Write("<input type=\"submit\" ");
|
|
||||||
RenderAttributes(textWriter);
|
|
||||||
RenderAttribute(textWriter, "value", _text);
|
|
||||||
if (string.IsNullOrEmpty(OnClientClick) == false)
|
|
||||||
{
|
|
||||||
RenderAttribute(textWriter, "onclick", OnClientClick);
|
|
||||||
}
|
|
||||||
textWriter.Write(">");
|
|
||||||
|
|
||||||
base.Render(textWriter);
|
|
||||||
|
|
||||||
textWriter.Write("</input>");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ReceivePostBack() { Click?.Invoke(this, EventArgs.Empty); }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string OnClientClick { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public string CommandArgument { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public event EventHandler? Click;
|
||||||
|
|
||||||
|
protected override void Render(TextWriter textWriter)
|
||||||
|
{
|
||||||
|
textWriter.Write("<input type=\"submit\" ");
|
||||||
|
RenderAttributes(textWriter);
|
||||||
|
RenderAttribute(textWriter, "value", _text);
|
||||||
|
if (string.IsNullOrEmpty(OnClientClick) == false)
|
||||||
|
{
|
||||||
|
RenderAttribute(textWriter, "onclick", OnClientClick);
|
||||||
|
}
|
||||||
|
textWriter.Write(">");
|
||||||
|
|
||||||
|
base.Render(textWriter);
|
||||||
|
|
||||||
|
textWriter.Write("</input>");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ReceivePostBack() { Click?.Invoke(this, EventArgs.Empty); }
|
||||||
}
|
}
|
||||||
@@ -3,193 +3,192 @@ using System.Collections.Generic;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using VAR.Json;
|
using VAR.Json;
|
||||||
|
|
||||||
namespace VAR.WebFormsCore.Controls
|
namespace VAR.WebFormsCore.Controls;
|
||||||
|
|
||||||
|
public class CTextBox : Control, INamingContainer, IValidableControl
|
||||||
{
|
{
|
||||||
public class CTextBox : Control, INamingContainer, IValidableControl
|
#region Declarations
|
||||||
|
|
||||||
|
private readonly TextBox _txtContent = new();
|
||||||
|
|
||||||
|
private HiddenField? _hidSize;
|
||||||
|
|
||||||
|
private const string CssClassBase = "textBox";
|
||||||
|
private string _cssClassExtra = "";
|
||||||
|
|
||||||
|
private bool _allowEmpty = true;
|
||||||
|
|
||||||
|
private string _placeHolder = string.Empty;
|
||||||
|
|
||||||
|
private bool _markedInvalid;
|
||||||
|
|
||||||
|
private Control? _nextFocusOnEnter;
|
||||||
|
|
||||||
|
private bool _keepSize;
|
||||||
|
|
||||||
|
#endregion Declarations
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
|
||||||
|
public string CssClassExtra
|
||||||
{
|
{
|
||||||
#region Declarations
|
get => _cssClassExtra;
|
||||||
|
set => _cssClassExtra = value;
|
||||||
|
}
|
||||||
|
|
||||||
private readonly TextBox _txtContent = new();
|
public bool AllowEmpty
|
||||||
|
{
|
||||||
|
get => _allowEmpty;
|
||||||
|
set => _allowEmpty = value;
|
||||||
|
}
|
||||||
|
|
||||||
private HiddenField? _hidSize;
|
public string PlaceHolder
|
||||||
|
{
|
||||||
|
get => _placeHolder;
|
||||||
|
set => _placeHolder = value;
|
||||||
|
}
|
||||||
|
|
||||||
private const string CssClassBase = "textBox";
|
public bool MarkedInvalid
|
||||||
private string _cssClassExtra = "";
|
{
|
||||||
|
get => _markedInvalid;
|
||||||
|
set => _markedInvalid = value;
|
||||||
|
}
|
||||||
|
|
||||||
private bool _allowEmpty = true;
|
public Control? NextFocusOnEnter
|
||||||
|
{
|
||||||
|
get => _nextFocusOnEnter;
|
||||||
|
set => _nextFocusOnEnter = value;
|
||||||
|
}
|
||||||
|
|
||||||
private string _placeHolder = string.Empty;
|
public bool KeepSize
|
||||||
|
{
|
||||||
|
get => _keepSize;
|
||||||
|
set => _keepSize = value;
|
||||||
|
}
|
||||||
|
|
||||||
private bool _markedInvalid;
|
public string Text
|
||||||
|
{
|
||||||
|
get => _txtContent.Text;
|
||||||
|
set => _txtContent.Text = value;
|
||||||
|
}
|
||||||
|
|
||||||
private Control? _nextFocusOnEnter;
|
public TextBoxMode TextMode
|
||||||
|
{
|
||||||
|
get => _txtContent.TextMode;
|
||||||
|
set => _txtContent.TextMode = value;
|
||||||
|
}
|
||||||
|
|
||||||
private bool _keepSize;
|
#endregion Properties
|
||||||
|
|
||||||
#endregion Declarations
|
#region Control life cycle
|
||||||
|
|
||||||
#region Properties
|
public CTextBox()
|
||||||
|
{
|
||||||
|
Init += CTextBox_Init;
|
||||||
|
PreRender += CTextBox_PreRender;
|
||||||
|
}
|
||||||
|
|
||||||
public string CssClassExtra
|
private void CTextBox_Init(object? sender, EventArgs e)
|
||||||
|
{
|
||||||
|
Controls.Add(_txtContent);
|
||||||
|
|
||||||
|
if (TextMode == TextBoxMode.MultiLine)
|
||||||
{
|
{
|
||||||
get => _cssClassExtra;
|
if (_keepSize)
|
||||||
set => _cssClassExtra = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool AllowEmpty
|
|
||||||
{
|
|
||||||
get => _allowEmpty;
|
|
||||||
set => _allowEmpty = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string PlaceHolder
|
|
||||||
{
|
|
||||||
get => _placeHolder;
|
|
||||||
set => _placeHolder = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool MarkedInvalid
|
|
||||||
{
|
|
||||||
get => _markedInvalid;
|
|
||||||
set => _markedInvalid = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Control? NextFocusOnEnter
|
|
||||||
{
|
|
||||||
get => _nextFocusOnEnter;
|
|
||||||
set => _nextFocusOnEnter = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool KeepSize
|
|
||||||
{
|
|
||||||
get => _keepSize;
|
|
||||||
set => _keepSize = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Text
|
|
||||||
{
|
|
||||||
get => _txtContent.Text;
|
|
||||||
set => _txtContent.Text = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TextBoxMode TextMode
|
|
||||||
{
|
|
||||||
get => _txtContent.TextMode;
|
|
||||||
init => _txtContent.TextMode = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Properties
|
|
||||||
|
|
||||||
#region Control life cycle
|
|
||||||
|
|
||||||
public CTextBox()
|
|
||||||
{
|
|
||||||
Init += CTextBox_Init;
|
|
||||||
PreRender += CTextBox_PreRender;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CTextBox_Init(object? sender, EventArgs e)
|
|
||||||
{
|
|
||||||
Controls.Add(_txtContent);
|
|
||||||
|
|
||||||
if (TextMode == TextBoxMode.MultiLine)
|
|
||||||
{
|
{
|
||||||
if (_keepSize)
|
_hidSize = new HiddenField();
|
||||||
{
|
Controls.Add(_hidSize);
|
||||||
_hidSize = new HiddenField();
|
|
||||||
Controls.Add(_hidSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
string strCfgName = $"{ClientID}_cfg";
|
|
||||||
Dictionary<string, object> cfg = new()
|
|
||||||
{
|
|
||||||
{"txtContent", _txtContent.ClientID}, {"hidSize", _hidSize?.ClientID ?? string.Empty}, {"keepSize", _keepSize},
|
|
||||||
};
|
|
||||||
StringBuilder sbCfg = new StringBuilder();
|
|
||||||
sbCfg.AppendFormat("<script>\n");
|
|
||||||
sbCfg.Append($"var {strCfgName} = {JsonWriter.WriteObject(cfg)};\n");
|
|
||||||
sbCfg.Append($"CTextBox_Multiline_Init({strCfgName});\n");
|
|
||||||
sbCfg.AppendFormat("</script>\n");
|
|
||||||
LiteralControl liScript = new LiteralControl(sbCfg.ToString());
|
|
||||||
Controls.Add(liScript);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CTextBox_PreRender(object? sender, EventArgs e)
|
|
||||||
{
|
|
||||||
_txtContent.CssClass = CssClassBase;
|
|
||||||
if (string.IsNullOrEmpty(_cssClassExtra) == false)
|
|
||||||
{
|
|
||||||
_txtContent.CssClass = $"{CssClassBase} {_cssClassExtra}";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Page?.IsPostBack == true && (_allowEmpty == false && IsEmpty()) || _markedInvalid)
|
string strCfgName = $"{ClientID}_cfg";
|
||||||
|
Dictionary<string, object> cfg = new()
|
||||||
{
|
{
|
||||||
_txtContent.CssClass += " textBoxInvalid";
|
{"txtContent", _txtContent.ClientID}, {"hidSize", _hidSize?.ClientID ?? string.Empty}, {"keepSize", _keepSize},
|
||||||
}
|
};
|
||||||
|
StringBuilder sbCfg = new StringBuilder();
|
||||||
|
sbCfg.AppendFormat("<script>\n");
|
||||||
|
sbCfg.Append($"var {strCfgName} = {JsonWriter.WriteObject(cfg)};\n");
|
||||||
|
sbCfg.Append($"CTextBox_Multiline_Init({strCfgName});\n");
|
||||||
|
sbCfg.AppendFormat("</script>\n");
|
||||||
|
LiteralControl liScript = new LiteralControl(sbCfg.ToString());
|
||||||
|
Controls.Add(liScript);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_txtContent.Attributes.Add("onchange", "ElementRemoveClass(this, 'textBoxInvalid');");
|
private void CTextBox_PreRender(object? sender, EventArgs e)
|
||||||
|
{
|
||||||
if (string.IsNullOrEmpty(_placeHolder) == false)
|
_txtContent.CssClass = CssClassBase;
|
||||||
{
|
if (string.IsNullOrEmpty(_cssClassExtra) == false)
|
||||||
_txtContent.Attributes.Add("placeholder", _placeHolder);
|
{
|
||||||
}
|
_txtContent.CssClass = $"{CssClassBase} {_cssClassExtra}";
|
||||||
|
|
||||||
if (_nextFocusOnEnter != null)
|
|
||||||
{
|
|
||||||
_txtContent.Attributes.Add(
|
|
||||||
"onkeydown",
|
|
||||||
$"if(event.keyCode==13){{document.getElementById('{_nextFocusOnEnter.ClientID}').focus(); return false;}}"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion Control life cycle
|
if (Page?.IsPostBack == true && (_allowEmpty == false && IsEmpty()) || _markedInvalid)
|
||||||
|
|
||||||
#region Public methods
|
|
||||||
|
|
||||||
private bool IsEmpty() { return string.IsNullOrEmpty(_txtContent.Text); }
|
|
||||||
|
|
||||||
public bool IsValid() { return _allowEmpty || (string.IsNullOrEmpty(_txtContent.Text) == false); }
|
|
||||||
|
|
||||||
public int? GetClientsideHeight()
|
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(_hidSize?.Value)) { return null; }
|
_txtContent.CssClass += " textBoxInvalid";
|
||||||
|
|
||||||
JsonParser jsonParser = new JsonParser();
|
|
||||||
Dictionary<string, object>? sizeObj = jsonParser.Parse(_hidSize.Value) as Dictionary<string, object>;
|
|
||||||
if (sizeObj == null) { return null; }
|
|
||||||
|
|
||||||
if (sizeObj.ContainsKey("height") == false) { return null; }
|
|
||||||
|
|
||||||
return (int) sizeObj["height"];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetClientsideHeight(int? height)
|
_txtContent.Attributes.Add("onchange", "ElementRemoveClass(this, 'textBoxInvalid');");
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(_placeHolder) == false)
|
||||||
{
|
{
|
||||||
if (height == null)
|
_txtContent.Attributes.Add("placeholder", _placeHolder);
|
||||||
{
|
}
|
||||||
if (_hidSize != null)
|
|
||||||
{
|
|
||||||
_hidSize.Value = string.Empty;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Dictionary<string, object?>? sizeObj = null;
|
if (_nextFocusOnEnter != null)
|
||||||
if (string.IsNullOrEmpty(_hidSize?.Value) == false)
|
{
|
||||||
{
|
_txtContent.Attributes.Add(
|
||||||
JsonParser jsonParser = new JsonParser();
|
"onkeydown",
|
||||||
sizeObj = jsonParser.Parse(_hidSize.Value) as Dictionary<string, object?>;
|
$"if(event.keyCode==13){{document.getElementById('{_nextFocusOnEnter.ClientID}').focus(); return false;}}"
|
||||||
}
|
);
|
||||||
sizeObj ??= new Dictionary<string, object?> { { "height", height }, { "width", null }, { "scrollTop", null }, };
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion Control life cycle
|
||||||
|
|
||||||
|
#region Public methods
|
||||||
|
|
||||||
|
private bool IsEmpty() { return string.IsNullOrEmpty(_txtContent.Text); }
|
||||||
|
|
||||||
|
public bool IsValid() { return _allowEmpty || (string.IsNullOrEmpty(_txtContent.Text) == false); }
|
||||||
|
|
||||||
|
public int? GetClientsideHeight()
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(_hidSize?.Value)) { return null; }
|
||||||
|
|
||||||
|
JsonParser jsonParser = new JsonParser();
|
||||||
|
Dictionary<string, object>? sizeObj = jsonParser.Parse(_hidSize?.Value) as Dictionary<string, object>;
|
||||||
|
if (sizeObj == null) { return null; }
|
||||||
|
|
||||||
|
if (sizeObj.ContainsKey("height") == false) { return null; }
|
||||||
|
|
||||||
|
return (int) sizeObj["height"];
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetClientsideHeight(int? height)
|
||||||
|
{
|
||||||
|
if (height == null)
|
||||||
|
{
|
||||||
if (_hidSize != null)
|
if (_hidSize != null)
|
||||||
{
|
{
|
||||||
_hidSize.Value = JsonWriter.WriteObject(sizeObj);
|
_hidSize.Value = string.Empty;
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion Public methods
|
Dictionary<string, object?>? sizeObj = null;
|
||||||
|
if (string.IsNullOrEmpty(_hidSize?.Value) == false)
|
||||||
|
{
|
||||||
|
JsonParser jsonParser = new JsonParser();
|
||||||
|
sizeObj = jsonParser.Parse(_hidSize?.Value) as Dictionary<string, object?>;
|
||||||
|
}
|
||||||
|
sizeObj ??= new Dictionary<string, object?> { { "height", height }, { "width", null }, { "scrollTop", null }, };
|
||||||
|
|
||||||
|
if (_hidSize != null)
|
||||||
|
{
|
||||||
|
_hidSize.Value = JsonWriter.WriteObject(sizeObj);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion Public methods
|
||||||
}
|
}
|
||||||
@@ -5,194 +5,193 @@ using System.Text;
|
|||||||
using VAR.WebFormsCore.Code;
|
using VAR.WebFormsCore.Code;
|
||||||
using VAR.WebFormsCore.Pages;
|
using VAR.WebFormsCore.Pages;
|
||||||
|
|
||||||
namespace VAR.WebFormsCore.Controls
|
namespace VAR.WebFormsCore.Controls;
|
||||||
|
|
||||||
|
public class Control
|
||||||
{
|
{
|
||||||
public class Control
|
public event EventHandler? PreInit;
|
||||||
|
|
||||||
|
protected void OnPreInit(EventArgs e)
|
||||||
{
|
{
|
||||||
public event EventHandler? PreInit;
|
PreInit?.Invoke(this, e);
|
||||||
|
foreach (Control control in Controls) { control.OnPreInit(e); }
|
||||||
|
}
|
||||||
|
|
||||||
protected void OnPreInit(EventArgs e)
|
public event EventHandler? Init;
|
||||||
|
|
||||||
|
protected void OnInit(EventArgs e)
|
||||||
|
{
|
||||||
|
Init?.Invoke(this, e);
|
||||||
|
foreach (Control control in Controls) { control.OnInit(e); }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public event EventHandler? Load;
|
||||||
|
|
||||||
|
protected virtual void Process() { }
|
||||||
|
|
||||||
|
protected void OnLoad(EventArgs e)
|
||||||
|
{
|
||||||
|
Process();
|
||||||
|
Load?.Invoke(this, e);
|
||||||
|
foreach (Control control in Controls) { control.OnLoad(e); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public event EventHandler? PreRender;
|
||||||
|
|
||||||
|
protected void OnPreRender(EventArgs e)
|
||||||
|
{
|
||||||
|
PreRender?.Invoke(this, e);
|
||||||
|
foreach (Control control in Controls) { control.OnPreRender(e); }
|
||||||
|
}
|
||||||
|
|
||||||
|
private string? _id;
|
||||||
|
|
||||||
|
public string? ID
|
||||||
|
{
|
||||||
|
get => _id;
|
||||||
|
set
|
||||||
{
|
{
|
||||||
PreInit?.Invoke(this, e);
|
_id = value;
|
||||||
foreach (Control control in Controls) { control.OnPreInit(e); }
|
_clientID = null;
|
||||||
}
|
|
||||||
|
|
||||||
public event EventHandler? Init;
|
|
||||||
|
|
||||||
protected void OnInit(EventArgs e)
|
|
||||||
{
|
|
||||||
Init?.Invoke(this, e);
|
|
||||||
foreach (Control control in Controls) { control.OnInit(e); }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public event EventHandler? Load;
|
|
||||||
|
|
||||||
protected virtual void Process() { }
|
|
||||||
|
|
||||||
protected void OnLoad(EventArgs e)
|
|
||||||
{
|
|
||||||
Process();
|
|
||||||
Load?.Invoke(this, e);
|
|
||||||
foreach (Control control in Controls) { control.OnLoad(e); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public event EventHandler? PreRender;
|
|
||||||
|
|
||||||
protected void OnPreRender(EventArgs e)
|
|
||||||
{
|
|
||||||
PreRender?.Invoke(this, e);
|
|
||||||
foreach (Control control in Controls) { control.OnPreRender(e); }
|
|
||||||
}
|
|
||||||
|
|
||||||
private string? _id;
|
|
||||||
|
|
||||||
public string? ID
|
|
||||||
{
|
|
||||||
get => _id;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_id = value;
|
|
||||||
_clientID = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private string? _clientID;
|
|
||||||
|
|
||||||
public string ClientID
|
|
||||||
{
|
|
||||||
get { return _clientID ??= GenerateClientID(); }
|
|
||||||
}
|
|
||||||
|
|
||||||
private Control? _parent;
|
|
||||||
|
|
||||||
public Control? Parent
|
|
||||||
{
|
|
||||||
get => _parent;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_parent = value;
|
|
||||||
_clientID = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private ControlCollection? _controls;
|
|
||||||
|
|
||||||
public string CssClass { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
public ControlCollection Controls
|
|
||||||
{
|
|
||||||
get { return _controls ??= new ControlCollection(this); }
|
|
||||||
}
|
|
||||||
|
|
||||||
private Page? _page;
|
|
||||||
|
|
||||||
public Page? Page
|
|
||||||
{
|
|
||||||
get => _page;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_page = value;
|
|
||||||
foreach (Control control in Controls) { control.Page = value; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Visible { get; set; } = true;
|
|
||||||
|
|
||||||
private string GenerateClientID()
|
|
||||||
{
|
|
||||||
StringBuilder sbClientID = new();
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(_id) == false) { sbClientID.Insert(0, _id); }
|
|
||||||
else
|
|
||||||
{
|
|
||||||
string currentID = $"ctl{Index:00}";
|
|
||||||
sbClientID.Insert(0, currentID);
|
|
||||||
}
|
|
||||||
|
|
||||||
Control? parent = Parent;
|
|
||||||
while (parent != null)
|
|
||||||
{
|
|
||||||
if (parent is INamingContainer)
|
|
||||||
{
|
|
||||||
sbClientID.Insert(0, "_");
|
|
||||||
if (string.IsNullOrEmpty(parent.ID) == false) { sbClientID.Insert(0, parent.ID); }
|
|
||||||
else
|
|
||||||
{
|
|
||||||
string parentID = $"ctl{parent.Index:00}";
|
|
||||||
sbClientID.Insert(0, parentID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
parent = parent.Parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
return sbClientID.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Dictionary<string, string> Style { get; } = new();
|
|
||||||
|
|
||||||
public Dictionary<string, string> Attributes { get; } = new();
|
|
||||||
|
|
||||||
public int Index { get; set; }
|
|
||||||
|
|
||||||
protected virtual void Render(TextWriter textWriter)
|
|
||||||
{
|
|
||||||
foreach (Control control in Controls)
|
|
||||||
{
|
|
||||||
if (control.Visible == false) { continue; }
|
|
||||||
|
|
||||||
control.Render(textWriter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static void RenderAttribute(TextWriter textWriter, string key, string value)
|
|
||||||
{
|
|
||||||
textWriter.Write(" {0}=\"{1}\"", key, ServerHelpers.HtmlEncode(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void RenderAttributes(TextWriter textWriter, bool forceId = false)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(_id) == false || forceId)
|
|
||||||
{
|
|
||||||
RenderAttribute(textWriter, "id", ClientID);
|
|
||||||
RenderAttribute(textWriter, "name", ClientID);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(CssClass) == false) { RenderAttribute(textWriter, "class", CssClass); }
|
|
||||||
|
|
||||||
foreach (KeyValuePair<string, string> attributePair in Attributes)
|
|
||||||
{
|
|
||||||
RenderAttribute(textWriter, attributePair.Key, attributePair.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Style.Count > 0)
|
|
||||||
{
|
|
||||||
StringBuilder sbStyle = new();
|
|
||||||
foreach (KeyValuePair<string, string> stylePair in Style)
|
|
||||||
{
|
|
||||||
sbStyle.Append($"{stylePair.Key}: {stylePair.Value};");
|
|
||||||
}
|
|
||||||
|
|
||||||
RenderAttribute(textWriter, "style", sbStyle.ToString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected List<Control> ChildsOfType<T>(List<Control>? controls = null)
|
|
||||||
{
|
|
||||||
controls ??= new List<Control>();
|
|
||||||
|
|
||||||
if (this is T) { controls.Add(this); }
|
|
||||||
|
|
||||||
if (_controls != null)
|
|
||||||
{
|
|
||||||
foreach (Control child in _controls)
|
|
||||||
{
|
|
||||||
child.ChildsOfType<T>(controls);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return controls;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string? _clientID;
|
||||||
|
|
||||||
|
public string ClientID
|
||||||
|
{
|
||||||
|
get { return _clientID ??= GenerateClientID(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
private Control? _parent;
|
||||||
|
|
||||||
|
public Control? Parent
|
||||||
|
{
|
||||||
|
get => _parent;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_parent = value;
|
||||||
|
_clientID = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ControlCollection? _controls;
|
||||||
|
|
||||||
|
public string CssClass { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public ControlCollection Controls
|
||||||
|
{
|
||||||
|
get { return _controls ??= new ControlCollection(this); }
|
||||||
|
}
|
||||||
|
|
||||||
|
private Page? _page;
|
||||||
|
|
||||||
|
public Page? Page
|
||||||
|
{
|
||||||
|
get => _page;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_page = value;
|
||||||
|
foreach (Control control in Controls) { control.Page = value; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Visible { get; set; } = true;
|
||||||
|
|
||||||
|
private string GenerateClientID()
|
||||||
|
{
|
||||||
|
StringBuilder sbClientID = new();
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(_id) == false) { sbClientID.Insert(0, _id); }
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string currentID = $"ctl{Index:00}";
|
||||||
|
sbClientID.Insert(0, currentID);
|
||||||
|
}
|
||||||
|
|
||||||
|
Control? parent = Parent;
|
||||||
|
while (parent != null)
|
||||||
|
{
|
||||||
|
if (parent is INamingContainer)
|
||||||
|
{
|
||||||
|
sbClientID.Insert(0, "_");
|
||||||
|
if (string.IsNullOrEmpty(parent.ID) == false) { sbClientID.Insert(0, parent.ID); }
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string parentID = $"ctl{parent.Index:00}";
|
||||||
|
sbClientID.Insert(0, parentID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
parent = parent.Parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sbClientID.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Dictionary<string, string> Style { get; } = new();
|
||||||
|
|
||||||
|
public Dictionary<string, string> Attributes { get; } = new();
|
||||||
|
|
||||||
|
public int Index { get; set; }
|
||||||
|
|
||||||
|
protected virtual void Render(TextWriter textWriter)
|
||||||
|
{
|
||||||
|
foreach (Control control in Controls)
|
||||||
|
{
|
||||||
|
if (control.Visible == false) { continue; }
|
||||||
|
|
||||||
|
control.Render(textWriter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static void RenderAttribute(TextWriter textWriter, string key, string value)
|
||||||
|
{
|
||||||
|
textWriter.Write(" {0}=\"{1}\"", key, ServerHelpers.HtmlEncode(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void RenderAttributes(TextWriter textWriter, bool forceId = false)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(_id) == false || forceId)
|
||||||
|
{
|
||||||
|
RenderAttribute(textWriter, "id", ClientID);
|
||||||
|
RenderAttribute(textWriter, "name", ClientID);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(CssClass) == false) { RenderAttribute(textWriter, "class", CssClass); }
|
||||||
|
|
||||||
|
foreach (KeyValuePair<string, string> attributePair in Attributes)
|
||||||
|
{
|
||||||
|
RenderAttribute(textWriter, attributePair.Key, attributePair.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Style.Count > 0)
|
||||||
|
{
|
||||||
|
StringBuilder sbStyle = new();
|
||||||
|
foreach (KeyValuePair<string, string> stylePair in Style)
|
||||||
|
{
|
||||||
|
sbStyle.Append($"{stylePair.Key}: {stylePair.Value};");
|
||||||
|
}
|
||||||
|
|
||||||
|
RenderAttribute(textWriter, "style", sbStyle.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected List<Control> ChildsOfType<T>(List<Control>? controls = null)
|
||||||
|
{
|
||||||
|
controls ??= new List<Control>();
|
||||||
|
|
||||||
|
if (this is T) { controls.Add(this); }
|
||||||
|
|
||||||
|
if (_controls != null)
|
||||||
|
{
|
||||||
|
foreach (Control child in _controls)
|
||||||
|
{
|
||||||
|
child.ChildsOfType<T>(controls);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return controls;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,21 +1,20 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace VAR.WebFormsCore.Controls
|
namespace VAR.WebFormsCore.Controls;
|
||||||
|
|
||||||
|
public class ControlCollection : List<Control>
|
||||||
{
|
{
|
||||||
public class ControlCollection : List<Control>
|
private readonly Control _parent;
|
||||||
|
private int _index;
|
||||||
|
|
||||||
|
public ControlCollection(Control parent) { _parent = parent; }
|
||||||
|
|
||||||
|
public new void Add(Control control)
|
||||||
{
|
{
|
||||||
private readonly Control _parent;
|
control.Page = _parent.Page;
|
||||||
private int _index;
|
control.Parent = _parent;
|
||||||
|
control.Index = _index;
|
||||||
public ControlCollection(Control parent) { _parent = parent; }
|
_index++;
|
||||||
|
base.Add(control);
|
||||||
public new void Add(Control control)
|
|
||||||
{
|
|
||||||
control.Page = _parent.Page;
|
|
||||||
control.Parent = _parent;
|
|
||||||
control.Index = _index;
|
|
||||||
_index++;
|
|
||||||
base.Add(control);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,33 +1,32 @@
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace VAR.WebFormsCore.Controls
|
namespace VAR.WebFormsCore.Controls;
|
||||||
|
|
||||||
|
public class HiddenField : Control
|
||||||
{
|
{
|
||||||
public class HiddenField : Control
|
private string _value = string.Empty;
|
||||||
|
|
||||||
|
public string Value
|
||||||
{
|
{
|
||||||
private string _value = string.Empty;
|
get => _value;
|
||||||
|
set => _value = value;
|
||||||
|
}
|
||||||
|
|
||||||
public string Value
|
protected override void Process()
|
||||||
|
{
|
||||||
|
if (Page?.IsPostBack == true && Page?.Context?.RequestForm.ContainsKey(ClientID) == true)
|
||||||
{
|
{
|
||||||
get => _value;
|
Value = Page?.Context.RequestForm[ClientID] ?? string.Empty;
|
||||||
set => _value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Process()
|
|
||||||
{
|
|
||||||
if (Page?.IsPostBack == true && Page?.Context?.Request.Form.ContainsKey(ClientID) == true)
|
|
||||||
{
|
|
||||||
Value = Page?.Context.Request.Form[ClientID][0] ?? string.Empty;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Render(TextWriter textWriter)
|
|
||||||
{
|
|
||||||
textWriter.Write("<input type=\"hidden\" ");
|
|
||||||
RenderAttributes(textWriter, forceId: true);
|
|
||||||
if (string.IsNullOrEmpty(Value) == false) { RenderAttribute(textWriter, "value", _value); }
|
|
||||||
|
|
||||||
textWriter.Write(">");
|
|
||||||
textWriter.Write("</input>");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void Render(TextWriter textWriter)
|
||||||
|
{
|
||||||
|
textWriter.Write("<input type=\"hidden\" ");
|
||||||
|
RenderAttributes(textWriter, forceId: true);
|
||||||
|
if (string.IsNullOrEmpty(Value) == false) { RenderAttribute(textWriter, "value", _value); }
|
||||||
|
|
||||||
|
textWriter.Write(">");
|
||||||
|
textWriter.Write("</input>");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
namespace VAR.WebFormsCore.Controls
|
namespace VAR.WebFormsCore.Controls;
|
||||||
|
|
||||||
|
public class HtmlBody : HtmlGenericControl
|
||||||
{
|
{
|
||||||
public class HtmlBody : HtmlGenericControl
|
public HtmlBody() : base("body") { }
|
||||||
{
|
|
||||||
public HtmlBody() : base("body") { }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Microsoft.Extensions.Primitives;
|
|
||||||
using VAR.WebFormsCore.Code;
|
using VAR.WebFormsCore.Code;
|
||||||
|
|
||||||
namespace VAR.WebFormsCore.Controls
|
namespace VAR.WebFormsCore.Controls
|
||||||
@@ -28,15 +27,15 @@ namespace VAR.WebFormsCore.Controls
|
|||||||
StringBuilder sbAction = new();
|
StringBuilder sbAction = new();
|
||||||
sbAction.Append(Page?.GetType().Name);
|
sbAction.Append(Page?.GetType().Name);
|
||||||
|
|
||||||
if ((Page?.Context?.Request.Query.Count ?? 0) <= 0) { return sbAction.ToString(); }
|
if ((Page?.Context?.RequestQuery.Count ?? 0) <= 0) { return sbAction.ToString(); }
|
||||||
|
|
||||||
sbAction.Append('?');
|
sbAction.Append('?');
|
||||||
if (Page?.Context?.Request.Query != null)
|
if (Page?.Context?.RequestQuery != null)
|
||||||
{
|
{
|
||||||
foreach (KeyValuePair<string, StringValues> queryParam in Page.Context.Request.Query)
|
foreach (KeyValuePair<string, string?> queryParam in Page.Context.RequestQuery)
|
||||||
{
|
{
|
||||||
string key = ServerHelpers.UrlEncode(queryParam.Key);
|
string key = ServerHelpers.UrlEncode(queryParam.Key);
|
||||||
string value = ServerHelpers.UrlEncode(queryParam.Value[0] ?? string.Empty);
|
string value = ServerHelpers.UrlEncode(queryParam.Value ?? string.Empty);
|
||||||
sbAction.Append($"&{key}={value}");
|
sbAction.Append($"&{key}={value}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1,21 @@
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace VAR.WebFormsCore.Controls
|
namespace VAR.WebFormsCore.Controls;
|
||||||
|
|
||||||
|
public class HtmlGenericControl : Control
|
||||||
{
|
{
|
||||||
public class HtmlGenericControl : Control
|
private readonly string _tagName;
|
||||||
|
|
||||||
|
public HtmlGenericControl(string tag) { _tagName = tag; }
|
||||||
|
|
||||||
|
protected override void Render(TextWriter textWriter)
|
||||||
{
|
{
|
||||||
private readonly string _tagName;
|
textWriter.Write("<{0} ", _tagName);
|
||||||
|
RenderAttributes(textWriter);
|
||||||
|
textWriter.Write(">");
|
||||||
|
|
||||||
public HtmlGenericControl(string tag) { _tagName = tag; }
|
base.Render(textWriter);
|
||||||
|
|
||||||
protected override void Render(TextWriter textWriter)
|
textWriter.Write("</{0}>", _tagName);
|
||||||
{
|
|
||||||
textWriter.Write("<{0} ", _tagName);
|
|
||||||
RenderAttributes(textWriter);
|
|
||||||
textWriter.Write(">");
|
|
||||||
|
|
||||||
base.Render(textWriter);
|
|
||||||
|
|
||||||
textWriter.Write("</{0}>", _tagName);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,22 +1,21 @@
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace VAR.WebFormsCore.Controls
|
namespace VAR.WebFormsCore.Controls;
|
||||||
|
|
||||||
|
public class HtmlHead : Control
|
||||||
{
|
{
|
||||||
public class HtmlHead : Control
|
public string Title { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
protected override void Render(TextWriter textWriter)
|
||||||
{
|
{
|
||||||
public string Title { get; set; } = string.Empty;
|
textWriter.Write("<head ");
|
||||||
|
RenderAttributes(textWriter);
|
||||||
|
textWriter.Write(">");
|
||||||
|
|
||||||
protected override void Render(TextWriter textWriter)
|
if (string.IsNullOrEmpty(Title) == false) { textWriter.Write("<title>{0}</title>", Title); }
|
||||||
{
|
|
||||||
textWriter.Write("<head ");
|
|
||||||
RenderAttributes(textWriter);
|
|
||||||
textWriter.Write(">");
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(Title) == false) { textWriter.Write("<title>{0}</title>", Title); }
|
base.Render(textWriter);
|
||||||
|
|
||||||
base.Render(textWriter);
|
textWriter.Write("</head>");
|
||||||
|
|
||||||
textWriter.Write("</head>");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,24 +1,23 @@
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace VAR.WebFormsCore.Controls
|
namespace VAR.WebFormsCore.Controls;
|
||||||
|
|
||||||
|
public class HtmlMeta : Control
|
||||||
{
|
{
|
||||||
public class HtmlMeta : Control
|
public string Name { get; set; } = string.Empty;
|
||||||
|
public string Content { get; set; } = string.Empty;
|
||||||
|
public string HttpEquiv { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
protected override void Render(TextWriter textWriter)
|
||||||
{
|
{
|
||||||
public string Name { get; init; } = string.Empty;
|
textWriter.Write("<meta ");
|
||||||
public string Content { get; init; } = string.Empty;
|
RenderAttributes(textWriter);
|
||||||
public string HttpEquiv { get; internal init; } = string.Empty;
|
if (string.IsNullOrEmpty(Name) == false) { textWriter.Write(" name=\"{0}\"", Name); }
|
||||||
|
|
||||||
protected override void Render(TextWriter textWriter)
|
if (string.IsNullOrEmpty(Content) == false) { textWriter.Write(" content=\"{0}\"", Content); }
|
||||||
{
|
|
||||||
textWriter.Write("<meta ");
|
|
||||||
RenderAttributes(textWriter);
|
|
||||||
if (string.IsNullOrEmpty(Name) == false) { textWriter.Write(" name=\"{0}\"", Name); }
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(Content) == false) { textWriter.Write(" content=\"{0}\"", Content); }
|
if (string.IsNullOrEmpty(HttpEquiv) == false) { textWriter.Write(" http-equiv=\"{0}\"", HttpEquiv); }
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(HttpEquiv) == false) { textWriter.Write(" http-equiv=\"{0}\"", HttpEquiv); }
|
textWriter.Write(" />");
|
||||||
|
|
||||||
textWriter.Write(" />");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,25 +1,24 @@
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace VAR.WebFormsCore.Controls
|
namespace VAR.WebFormsCore.Controls;
|
||||||
|
|
||||||
|
public class HyperLink : Control
|
||||||
{
|
{
|
||||||
public class HyperLink : Control
|
public string NavigateUrl { get; set; } = string.Empty;
|
||||||
|
public string Text { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
protected override void Render(TextWriter textWriter)
|
||||||
{
|
{
|
||||||
public string NavigateUrl { get; set; } = string.Empty;
|
textWriter.Write("<a ");
|
||||||
public string Text { get; init; } = string.Empty;
|
RenderAttributes(textWriter);
|
||||||
|
if (string.IsNullOrEmpty(NavigateUrl) == false) { textWriter.Write(" href=\"{0}\"", NavigateUrl); }
|
||||||
|
|
||||||
protected override void Render(TextWriter textWriter)
|
textWriter.Write(">");
|
||||||
{
|
|
||||||
textWriter.Write("<a ");
|
|
||||||
RenderAttributes(textWriter);
|
|
||||||
if (string.IsNullOrEmpty(NavigateUrl) == false) { textWriter.Write(" href=\"{0}\"", NavigateUrl); }
|
|
||||||
|
|
||||||
textWriter.Write(">");
|
if (string.IsNullOrEmpty(Text) == false) { textWriter.Write(Text); }
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(Text) == false) { textWriter.Write(Text); }
|
base.Render(textWriter);
|
||||||
|
|
||||||
base.Render(textWriter);
|
textWriter.Write("</a>");
|
||||||
|
|
||||||
textWriter.Write("</a>");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
namespace VAR.WebFormsCore.Controls
|
namespace VAR.WebFormsCore.Controls;
|
||||||
|
|
||||||
|
public interface INamingContainer
|
||||||
{
|
{
|
||||||
public interface INamingContainer
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
namespace VAR.WebFormsCore.Controls
|
namespace VAR.WebFormsCore.Controls;
|
||||||
|
|
||||||
|
public interface IReceivePostbackEvent
|
||||||
{
|
{
|
||||||
public interface IReceivePostbackEvent
|
void ReceivePostBack();
|
||||||
{
|
|
||||||
void ReceivePostBack();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
namespace VAR.WebFormsCore.Controls
|
namespace VAR.WebFormsCore.Controls;
|
||||||
|
|
||||||
|
public interface IValidableControl
|
||||||
{
|
{
|
||||||
public interface IValidableControl
|
bool IsValid();
|
||||||
{
|
|
||||||
bool IsValid();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,45 +1,44 @@
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using VAR.WebFormsCore.Code;
|
using VAR.WebFormsCore.Code;
|
||||||
|
|
||||||
namespace VAR.WebFormsCore.Controls
|
namespace VAR.WebFormsCore.Controls;
|
||||||
|
|
||||||
|
public class Label : Control
|
||||||
{
|
{
|
||||||
public class Label : Control
|
#region Properties
|
||||||
|
|
||||||
|
private string _tagName = "span";
|
||||||
|
|
||||||
|
public string Tag
|
||||||
{
|
{
|
||||||
#region Properties
|
get => _tagName;
|
||||||
|
set => _tagName = value;
|
||||||
private string _tagName = "span";
|
|
||||||
|
|
||||||
public string Tag
|
|
||||||
{
|
|
||||||
get => _tagName;
|
|
||||||
set => _tagName = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
private string _text = string.Empty;
|
|
||||||
|
|
||||||
public string Text
|
|
||||||
{
|
|
||||||
get => _text;
|
|
||||||
set => _text = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Properties
|
|
||||||
|
|
||||||
#region Life cycle
|
|
||||||
|
|
||||||
protected override void Render(TextWriter textWriter)
|
|
||||||
{
|
|
||||||
textWriter.Write("<{0} ", _tagName);
|
|
||||||
RenderAttributes(textWriter);
|
|
||||||
textWriter.Write(">");
|
|
||||||
|
|
||||||
textWriter.Write(ServerHelpers.HtmlEncode(_text));
|
|
||||||
|
|
||||||
base.Render(textWriter);
|
|
||||||
|
|
||||||
textWriter.Write("</{0}>", _tagName);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Life cycle
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string _text = string.Empty;
|
||||||
|
|
||||||
|
public string Text
|
||||||
|
{
|
||||||
|
get => _text;
|
||||||
|
set => _text = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion Properties
|
||||||
|
|
||||||
|
#region Life cycle
|
||||||
|
|
||||||
|
protected override void Render(TextWriter textWriter)
|
||||||
|
{
|
||||||
|
textWriter.Write("<{0} ", _tagName);
|
||||||
|
RenderAttributes(textWriter);
|
||||||
|
textWriter.Write(">");
|
||||||
|
|
||||||
|
textWriter.Write(ServerHelpers.HtmlEncode(_text));
|
||||||
|
|
||||||
|
base.Render(textWriter);
|
||||||
|
|
||||||
|
textWriter.Write("</{0}>", _tagName);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion Life cycle
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,13 @@
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace VAR.WebFormsCore.Controls
|
namespace VAR.WebFormsCore.Controls;
|
||||||
|
|
||||||
|
public class LiteralControl : Control
|
||||||
{
|
{
|
||||||
public class LiteralControl : Control
|
public string Content { get; set; } = string.Empty;
|
||||||
{
|
|
||||||
public string Content { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
public LiteralControl() { }
|
public LiteralControl() { }
|
||||||
public LiteralControl(string content) { Content = content; }
|
public LiteralControl(string content) { Content = content; }
|
||||||
|
|
||||||
protected override void Render(TextWriter textWriter) { textWriter.Write(Content); }
|
protected override void Render(TextWriter textWriter) { textWriter.Write(Content); }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
namespace VAR.WebFormsCore.Controls
|
namespace VAR.WebFormsCore.Controls;
|
||||||
|
|
||||||
|
public class Panel : HtmlGenericControl, INamingContainer
|
||||||
{
|
{
|
||||||
public class Panel : HtmlGenericControl, INamingContainer
|
public Panel() : base("div") { }
|
||||||
{
|
|
||||||
public Panel() : base("div") { }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,55 +1,54 @@
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using VAR.WebFormsCore.Code;
|
using VAR.WebFormsCore.Code;
|
||||||
|
|
||||||
namespace VAR.WebFormsCore.Controls
|
namespace VAR.WebFormsCore.Controls;
|
||||||
|
|
||||||
|
public class TextBox : Control
|
||||||
{
|
{
|
||||||
public class TextBox : Control
|
public string Text { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public TextBoxMode TextMode { get; set; } = TextBoxMode.Normal;
|
||||||
|
|
||||||
|
protected override void Process()
|
||||||
{
|
{
|
||||||
public string Text { get; set; } = string.Empty;
|
if (Page?.IsPostBack == true && Page?.Context?.RequestForm.ContainsKey(ClientID) == true)
|
||||||
|
|
||||||
public TextBoxMode TextMode { get; set; } = TextBoxMode.Normal;
|
|
||||||
|
|
||||||
protected override void Process()
|
|
||||||
{
|
{
|
||||||
if (Page?.IsPostBack == true && Page?.Context?.Request.Form.ContainsKey(ClientID) == true)
|
Text = Page?.Context.RequestForm[ClientID] ?? string.Empty;
|
||||||
{
|
|
||||||
Text = Page?.Context.Request.Form[ClientID][0] ?? string.Empty;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Render(TextWriter textWriter)
|
|
||||||
{
|
|
||||||
if (TextMode == TextBoxMode.MultiLine)
|
|
||||||
{
|
|
||||||
textWriter.Write("<textarea ");
|
|
||||||
RenderAttributes(textWriter, forceId: true);
|
|
||||||
textWriter.Write(">");
|
|
||||||
textWriter.Write(ServerHelpers.HtmlEncode(Text));
|
|
||||||
textWriter.Write("</textarea>");
|
|
||||||
}
|
|
||||||
else if (TextMode == TextBoxMode.Normal)
|
|
||||||
{
|
|
||||||
textWriter.Write("<input type=\"text\" ");
|
|
||||||
RenderAttributes(textWriter, forceId: true);
|
|
||||||
if (string.IsNullOrEmpty(Text) == false) { RenderAttribute(textWriter, "value", Text); }
|
|
||||||
|
|
||||||
textWriter.Write(">");
|
|
||||||
textWriter.Write("</input>");
|
|
||||||
}
|
|
||||||
else if (TextMode == TextBoxMode.Password)
|
|
||||||
{
|
|
||||||
textWriter.Write("<input type=\"password\" ");
|
|
||||||
RenderAttributes(textWriter, forceId: true);
|
|
||||||
if (string.IsNullOrEmpty(Text) == false) { RenderAttribute(textWriter, "value", Text); }
|
|
||||||
|
|
||||||
textWriter.Write(">");
|
|
||||||
textWriter.Write("</input>");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum TextBoxMode
|
protected override void Render(TextWriter textWriter)
|
||||||
{
|
{
|
||||||
Normal, Password, MultiLine,
|
if (TextMode == TextBoxMode.MultiLine)
|
||||||
|
{
|
||||||
|
textWriter.Write("<textarea ");
|
||||||
|
RenderAttributes(textWriter, forceId: true);
|
||||||
|
textWriter.Write(">");
|
||||||
|
textWriter.Write(ServerHelpers.HtmlEncode(Text));
|
||||||
|
textWriter.Write("</textarea>");
|
||||||
|
}
|
||||||
|
else if (TextMode == TextBoxMode.Normal)
|
||||||
|
{
|
||||||
|
textWriter.Write("<input type=\"text\" ");
|
||||||
|
RenderAttributes(textWriter, forceId: true);
|
||||||
|
if (string.IsNullOrEmpty(Text) == false) { RenderAttribute(textWriter, "value", Text); }
|
||||||
|
|
||||||
|
textWriter.Write(">");
|
||||||
|
textWriter.Write("</input>");
|
||||||
|
}
|
||||||
|
else if (TextMode == TextBoxMode.Password)
|
||||||
|
{
|
||||||
|
textWriter.Write("<input type=\"password\" ");
|
||||||
|
RenderAttributes(textWriter, forceId: true);
|
||||||
|
if (string.IsNullOrEmpty(Text) == false) { RenderAttribute(textWriter, "value", Text); }
|
||||||
|
|
||||||
|
textWriter.Write(">");
|
||||||
|
textWriter.Write("</input>");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum TextBoxMode
|
||||||
|
{
|
||||||
|
Normal, Password, MultiLine,
|
||||||
}
|
}
|
||||||
@@ -1,66 +1,65 @@
|
|||||||
using VAR.WebFormsCore.Controls;
|
using VAR.WebFormsCore.Controls;
|
||||||
|
|
||||||
namespace VAR.WebFormsCore.Pages
|
namespace VAR.WebFormsCore.Pages;
|
||||||
|
|
||||||
|
public static class FormUtils
|
||||||
{
|
{
|
||||||
public static class FormUtils
|
public static Control CreatePanel(string cssClass, Control? ctrl = null)
|
||||||
{
|
{
|
||||||
public static Control CreatePanel(string cssClass, Control? ctrl = null)
|
Panel pnl = new Panel();
|
||||||
|
if (ctrl != null) { pnl.Controls.Add(ctrl); }
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(cssClass) == false) { pnl.CssClass = cssClass; }
|
||||||
|
|
||||||
|
return pnl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Control CreateField(string label, Control fieldControl)
|
||||||
|
{
|
||||||
|
Panel pnlRow = new Panel {CssClass = "formRow"};
|
||||||
|
|
||||||
|
Panel pnlLabelContainer = new Panel {CssClass = "formLabel width25pc"};
|
||||||
|
pnlRow.Controls.Add(pnlLabelContainer);
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(label) == false)
|
||||||
{
|
{
|
||||||
Panel pnl = new Panel();
|
Label lblField = new Label {Text = label};
|
||||||
if (ctrl != null) { pnl.Controls.Add(ctrl); }
|
pnlLabelContainer.Controls.Add(lblField);
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(cssClass) == false) { pnl.CssClass = cssClass; }
|
|
||||||
|
|
||||||
return pnl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Control CreateField(string label, Control fieldControl)
|
Panel pnlFieldContainer = new Panel {CssClass = "formField width75pc"};
|
||||||
|
pnlRow.Controls.Add(pnlFieldContainer);
|
||||||
|
|
||||||
|
pnlFieldContainer.Controls.Add(fieldControl);
|
||||||
|
|
||||||
|
return pnlRow;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool Control_IsValid(Control control)
|
||||||
|
{
|
||||||
|
return (control as IValidableControl)?.IsValid() != false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool Controls_AreValid(ControlCollection controls)
|
||||||
|
{
|
||||||
|
bool valid = true;
|
||||||
|
foreach (Control control in controls)
|
||||||
{
|
{
|
||||||
Panel pnlRow = new Panel {CssClass = "formRow"};
|
if (Control_IsValid(control))
|
||||||
|
|
||||||
Panel pnlLabelContainer = new Panel {CssClass = "formLabel width25pc"};
|
|
||||||
pnlRow.Controls.Add(pnlLabelContainer);
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(label) == false)
|
|
||||||
{
|
{
|
||||||
Label lblField = new Label {Text = label};
|
if (Controls_AreValid(control.Controls) == false)
|
||||||
pnlLabelContainer.Controls.Add(lblField);
|
|
||||||
}
|
|
||||||
|
|
||||||
Panel pnlFieldContainer = new Panel {CssClass = "formField width75pc"};
|
|
||||||
pnlRow.Controls.Add(pnlFieldContainer);
|
|
||||||
|
|
||||||
pnlFieldContainer.Controls.Add(fieldControl);
|
|
||||||
|
|
||||||
return pnlRow;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool Control_IsValid(Control control)
|
|
||||||
{
|
|
||||||
return (control as IValidableControl)?.IsValid() != false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool Controls_AreValid(ControlCollection controls)
|
|
||||||
{
|
|
||||||
bool valid = true;
|
|
||||||
foreach (Control control in controls)
|
|
||||||
{
|
|
||||||
if (Control_IsValid(control))
|
|
||||||
{
|
|
||||||
if (Controls_AreValid(control.Controls) == false)
|
|
||||||
{
|
|
||||||
valid = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
valid = false;
|
valid = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
return valid;
|
{
|
||||||
|
valid = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return valid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,20 +1,21 @@
|
|||||||
using Microsoft.AspNetCore.Http;
|
using VAR.Json;
|
||||||
using VAR.Json;
|
|
||||||
using VAR.WebFormsCore.Code;
|
using VAR.WebFormsCore.Code;
|
||||||
|
|
||||||
namespace VAR.WebFormsCore.Pages
|
namespace VAR.WebFormsCore.Pages;
|
||||||
|
|
||||||
|
public class FrmEcho : IHttpHandler
|
||||||
{
|
{
|
||||||
public class FrmEcho : IHttpHandler
|
#region IHttpHandler
|
||||||
|
|
||||||
|
public void ProcessRequest(IWebContext context)
|
||||||
{
|
{
|
||||||
#region IHttpHandler
|
context.ResponseContentType = "text/html";
|
||||||
|
context.ResponseWrite("<pre><code>");
|
||||||
public void ProcessRequest(HttpContext context)
|
context.ResponseWrite($"Header:{JsonWriter.WriteObject(context.RequestHeader, indent: true)}\n");
|
||||||
{
|
context.ResponseWrite($"Query:{JsonWriter.WriteObject(context.RequestQuery, indent: true)}\n");
|
||||||
context.Response.WriteAsync("<pre><code>").GetAwaiter().GetResult();
|
context.ResponseWrite($"Form:{JsonWriter.WriteObject(context.RequestForm, indent: true)}\n");
|
||||||
context.Response.WriteAsync(JsonWriter.WriteObject(context.Request, indent: true)).GetAwaiter().GetResult();
|
context.ResponseWrite("</code></pre>");
|
||||||
context.Response.WriteAsync("</code></pre>").GetAwaiter().GetResult();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion IHttpHandler
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion IHttpHandler
|
||||||
}
|
}
|
||||||
@@ -2,60 +2,59 @@
|
|||||||
using System.Web;
|
using System.Web;
|
||||||
using VAR.WebFormsCore.Controls;
|
using VAR.WebFormsCore.Controls;
|
||||||
|
|
||||||
namespace VAR.WebFormsCore.Pages
|
namespace VAR.WebFormsCore.Pages;
|
||||||
|
|
||||||
|
public class FrmError : PageCommon
|
||||||
{
|
{
|
||||||
public class FrmError : PageCommon
|
#region Declarations
|
||||||
|
|
||||||
|
private readonly Exception _ex;
|
||||||
|
|
||||||
|
#endregion Declarations
|
||||||
|
|
||||||
|
#region Page life cycle
|
||||||
|
|
||||||
|
public FrmError(Exception ex)
|
||||||
{
|
{
|
||||||
#region Declarations
|
MustBeAuthenticated = false;
|
||||||
|
_ex = ex;
|
||||||
private readonly Exception _ex;
|
Init += FrmError_Init;
|
||||||
|
|
||||||
#endregion Declarations
|
|
||||||
|
|
||||||
#region Page life cycle
|
|
||||||
|
|
||||||
public FrmError(Exception ex)
|
|
||||||
{
|
|
||||||
MustBeAuthenticated = false;
|
|
||||||
_ex = ex;
|
|
||||||
Init += FrmError_Init;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void FrmError_Init(object? sender, EventArgs e) { InitializeControls(); }
|
|
||||||
|
|
||||||
#endregion Page life cycle
|
|
||||||
|
|
||||||
#region Private methods
|
|
||||||
|
|
||||||
private void InitializeControls()
|
|
||||||
{
|
|
||||||
Title = "Application Error";
|
|
||||||
|
|
||||||
Label lblErrorTitle = new Label {Text = Title, Tag = "h2"};
|
|
||||||
Controls.Add(lblErrorTitle);
|
|
||||||
|
|
||||||
Exception? exAux = _ex;
|
|
||||||
//if (exAux is HttpUnhandledException && exAux.InnerException != null) { exAux = exAux.InnerException; }
|
|
||||||
while (exAux != null)
|
|
||||||
{
|
|
||||||
LiteralControl lblMessage = new LiteralControl($"<p><b>Message:</b> {HttpUtility.HtmlEncode(exAux.Message)}</p>");
|
|
||||||
Controls.Add(lblMessage);
|
|
||||||
|
|
||||||
LiteralControl lblStacktraceTitle = new LiteralControl("<p><b>Stacktrace:</b></p>");
|
|
||||||
Controls.Add(lblStacktraceTitle);
|
|
||||||
Panel pnlStacktrace = new Panel
|
|
||||||
{
|
|
||||||
CssClass = "divCode"
|
|
||||||
};
|
|
||||||
Controls.Add(pnlStacktrace);
|
|
||||||
LiteralControl litStackTrace = new LiteralControl(
|
|
||||||
$"<pre><code>{HttpUtility.HtmlEncode(exAux.StackTrace)}</code></pre>");
|
|
||||||
pnlStacktrace.Controls.Add(litStackTrace);
|
|
||||||
|
|
||||||
exAux = exAux.InnerException;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Private methods
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void FrmError_Init(object? sender, EventArgs e) { InitializeControls(); }
|
||||||
|
|
||||||
|
#endregion Page life cycle
|
||||||
|
|
||||||
|
#region Private methods
|
||||||
|
|
||||||
|
private void InitializeControls()
|
||||||
|
{
|
||||||
|
Title = "Application Error";
|
||||||
|
|
||||||
|
Label lblErrorTitle = new Label {Text = Title, Tag = "h2"};
|
||||||
|
Controls.Add(lblErrorTitle);
|
||||||
|
|
||||||
|
Exception? exAux = _ex;
|
||||||
|
//if (exAux is HttpUnhandledException && exAux.InnerException != null) { exAux = exAux.InnerException; }
|
||||||
|
while (exAux != null)
|
||||||
|
{
|
||||||
|
LiteralControl lblMessage = new LiteralControl($"<p><b>Message:</b> {HttpUtility.HtmlEncode(exAux.Message)}</p>");
|
||||||
|
Controls.Add(lblMessage);
|
||||||
|
|
||||||
|
LiteralControl lblStacktraceTitle = new LiteralControl("<p><b>Stacktrace:</b></p>");
|
||||||
|
Controls.Add(lblStacktraceTitle);
|
||||||
|
Panel pnlStacktrace = new Panel
|
||||||
|
{
|
||||||
|
CssClass = "divCode"
|
||||||
|
};
|
||||||
|
Controls.Add(pnlStacktrace);
|
||||||
|
LiteralControl litStackTrace = new LiteralControl(
|
||||||
|
$"<pre><code>{HttpUtility.HtmlEncode(exAux.StackTrace)}</code></pre>");
|
||||||
|
pnlStacktrace.Controls.Add(litStackTrace);
|
||||||
|
|
||||||
|
exAux = exAux.InnerException;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion Private methods
|
||||||
}
|
}
|
||||||
@@ -2,76 +2,75 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using VAR.WebFormsCore.Code;
|
using VAR.WebFormsCore.Code;
|
||||||
using VAR.WebFormsCore.Controls;
|
using VAR.WebFormsCore.Controls;
|
||||||
|
|
||||||
namespace VAR.WebFormsCore.Pages
|
namespace VAR.WebFormsCore.Pages;
|
||||||
|
|
||||||
|
public class Page : Control, IHttpHandler
|
||||||
{
|
{
|
||||||
public class Page : Control, IHttpHandler
|
protected string Title { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public IWebContext? Context { get; private set; }
|
||||||
|
|
||||||
|
private static readonly Encoding Utf8Encoding = new UTF8Encoding();
|
||||||
|
|
||||||
|
public void ProcessRequest(IWebContext context)
|
||||||
{
|
{
|
||||||
protected string Title { get; set; } = string.Empty;
|
try
|
||||||
|
|
||||||
public HttpContext? Context { get; private set; }
|
|
||||||
|
|
||||||
private static readonly Encoding Utf8Encoding = new UTF8Encoding();
|
|
||||||
|
|
||||||
public void ProcessRequest(HttpContext context)
|
|
||||||
{
|
{
|
||||||
try
|
StringWriter stringWriter = new();
|
||||||
|
|
||||||
|
Context = context;
|
||||||
|
Page = this;
|
||||||
|
|
||||||
|
if (context.RequestMethod == "POST") { _isPostBack = true; }
|
||||||
|
|
||||||
|
OnPreInit(EventArgs.Empty);
|
||||||
|
if (context.ResponseHasStarted) { return; }
|
||||||
|
|
||||||
|
OnInit(EventArgs.Empty);
|
||||||
|
if (context.ResponseHasStarted) { return; }
|
||||||
|
|
||||||
|
OnLoad(EventArgs.Empty);
|
||||||
|
if (context.ResponseHasStarted) { return; }
|
||||||
|
|
||||||
|
if (_isPostBack)
|
||||||
{
|
{
|
||||||
StringWriter stringWriter = new();
|
List<Control> controls = ChildsOfType<IReceivePostbackEvent>();
|
||||||
|
foreach (Control control in controls)
|
||||||
Context = context;
|
|
||||||
Page = this;
|
|
||||||
|
|
||||||
if (context.Request.Method == "POST") { _isPostBack = true; }
|
|
||||||
|
|
||||||
OnPreInit(EventArgs.Empty);
|
|
||||||
if (context.Response.HasStarted) { return; }
|
|
||||||
|
|
||||||
OnInit(EventArgs.Empty);
|
|
||||||
if (context.Response.HasStarted) { return; }
|
|
||||||
|
|
||||||
OnLoad(EventArgs.Empty);
|
|
||||||
if (context.Response.HasStarted) { return; }
|
|
||||||
|
|
||||||
if (_isPostBack)
|
|
||||||
{
|
{
|
||||||
List<Control> controls = ChildsOfType<IReceivePostbackEvent>();
|
string clientID = control.ClientID;
|
||||||
foreach (Control control in controls)
|
if (context.RequestForm.ContainsKey(clientID))
|
||||||
{
|
{
|
||||||
string clientID = control.ClientID;
|
(control as IReceivePostbackEvent)?.ReceivePostBack();
|
||||||
if (context.Request.Form.ContainsKey(clientID))
|
if (context.ResponseHasStarted) { return; }
|
||||||
{
|
|
||||||
(control as IReceivePostbackEvent)?.ReceivePostBack();
|
|
||||||
if (context.Response.HasStarted) { return; }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OnPreRender(EventArgs.Empty);
|
|
||||||
if (context.Response.HasStarted) { return; }
|
|
||||||
|
|
||||||
Render(stringWriter);
|
|
||||||
if (context.Response.HasStarted) { return; }
|
|
||||||
|
|
||||||
context.Response.Headers.SafeSet("Content-Type", "text/html");
|
|
||||||
byte[] byteObject = Utf8Encoding.GetBytes(stringWriter.ToString());
|
|
||||||
context.Response.Body.WriteAsync(byteObject).GetAwaiter().GetResult();
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
// TODO: Implement better error logging
|
|
||||||
Console.WriteLine("!!!!!!!!!!");
|
|
||||||
Console.Write("Message: {0}\nStacktrace: {1}\n", ex.Message, ex.StackTrace);
|
|
||||||
|
|
||||||
GlobalErrorHandler.HandleError(context, ex);
|
OnPreRender(EventArgs.Empty);
|
||||||
}
|
if (context.ResponseHasStarted) { return; }
|
||||||
|
|
||||||
|
Render(stringWriter);
|
||||||
|
if (context.ResponseHasStarted) { return; }
|
||||||
|
|
||||||
|
//context.SetResponseHeader("Content-Type", "text/html");
|
||||||
|
context.ResponseContentType = "text/html";
|
||||||
|
byte[] byteObject = Utf8Encoding.GetBytes(stringWriter.ToString());
|
||||||
|
context.ResponseWriteBin(byteObject);
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
// TODO: Implement better error logging
|
||||||
|
Console.WriteLine("!!!!!!!!!!");
|
||||||
|
Console.Write("Message: {0}\nStacktrace: {1}\n", ex.Message, ex.StackTrace);
|
||||||
|
|
||||||
private bool _isPostBack;
|
GlobalErrorHandler.HandleError(context, ex);
|
||||||
|
}
|
||||||
public bool IsPostBack => _isPostBack;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool _isPostBack;
|
||||||
|
|
||||||
|
public bool IsPostBack => _isPostBack;
|
||||||
}
|
}
|
||||||
@@ -3,147 +3,146 @@ using System.Reflection;
|
|||||||
using VAR.WebFormsCore.Code;
|
using VAR.WebFormsCore.Code;
|
||||||
using VAR.WebFormsCore.Controls;
|
using VAR.WebFormsCore.Controls;
|
||||||
|
|
||||||
namespace VAR.WebFormsCore.Pages
|
namespace VAR.WebFormsCore.Pages;
|
||||||
|
|
||||||
|
public class PageCommon : Page
|
||||||
{
|
{
|
||||||
public class PageCommon : Page
|
#region Declarations
|
||||||
|
|
||||||
|
private readonly HtmlHead _head = new();
|
||||||
|
private readonly HtmlBody _body = new();
|
||||||
|
private readonly HtmlForm _form = new() {ID = "formMain"};
|
||||||
|
private readonly Panel _pnlContainer = new();
|
||||||
|
private readonly Button _btnPostback = new();
|
||||||
|
private readonly Button _btnLogout = new();
|
||||||
|
|
||||||
|
private bool _isAuthenticated;
|
||||||
|
|
||||||
|
#endregion Declarations
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
|
||||||
|
public new ControlCollection Controls => _pnlContainer.Controls;
|
||||||
|
|
||||||
|
public bool MustBeAuthenticated { get; set; } = true;
|
||||||
|
|
||||||
|
#endregion Properties
|
||||||
|
|
||||||
|
#region Life cycle
|
||||||
|
|
||||||
|
public PageCommon()
|
||||||
{
|
{
|
||||||
#region Declarations
|
PreInit += PageCommon_PreInit;
|
||||||
|
Init += PageCommon_Init;
|
||||||
private readonly HtmlHead _head = new();
|
PreRender += PageCommon_PreRender;
|
||||||
private readonly HtmlBody _body = new();
|
|
||||||
private readonly HtmlForm _form = new() {ID = "formMain"};
|
|
||||||
private readonly Panel _pnlContainer = new();
|
|
||||||
private readonly Button _btnPostback = new();
|
|
||||||
private readonly Button _btnLogout = new();
|
|
||||||
|
|
||||||
private bool _isAuthenticated;
|
|
||||||
|
|
||||||
#endregion Declarations
|
|
||||||
|
|
||||||
#region Properties
|
|
||||||
|
|
||||||
public new ControlCollection Controls => _pnlContainer.Controls;
|
|
||||||
|
|
||||||
public bool MustBeAuthenticated { get; init; } = true;
|
|
||||||
|
|
||||||
#endregion Properties
|
|
||||||
|
|
||||||
#region Life cycle
|
|
||||||
|
|
||||||
public PageCommon()
|
|
||||||
{
|
|
||||||
PreInit += PageCommon_PreInit;
|
|
||||||
Init += PageCommon_Init;
|
|
||||||
PreRender += PageCommon_PreRender;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void PageCommon_PreInit(object? sender, EventArgs e)
|
|
||||||
{
|
|
||||||
Context?.Response.PrepareUncacheableResponse();
|
|
||||||
|
|
||||||
if (Context != null)
|
|
||||||
{
|
|
||||||
_isAuthenticated = GlobalConfig.Get().IsUserAuthenticated(Context);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (MustBeAuthenticated && _isAuthenticated == false)
|
|
||||||
{
|
|
||||||
Context?.Response.Redirect(GlobalConfig.Get().LoginHandler);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void PageCommon_Init(object? sender, EventArgs e) { CreateControls(); }
|
|
||||||
|
|
||||||
private void PageCommon_PreRender(object? sender, EventArgs e)
|
|
||||||
{
|
|
||||||
_head.Title = string.IsNullOrEmpty(Title)
|
|
||||||
? GlobalConfig.Get().Title
|
|
||||||
: string.Concat(Title, GlobalConfig.Get().TitleSeparator, GlobalConfig.Get().Title);
|
|
||||||
_btnLogout.Visible = _isAuthenticated;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Life cycle
|
|
||||||
|
|
||||||
#region UI Events
|
|
||||||
|
|
||||||
private void btnLogout_Click(object? sender, EventArgs e)
|
|
||||||
{
|
|
||||||
if(Context != null)
|
|
||||||
{
|
|
||||||
GlobalConfig.Get().UserDeauthenticate(Context);
|
|
||||||
}
|
|
||||||
if (MustBeAuthenticated) { Context?.Response.Redirect(GlobalConfig.Get().LoginHandler); }
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion UI Events
|
|
||||||
|
|
||||||
#region Private methods
|
|
||||||
|
|
||||||
private void CreateControls()
|
|
||||||
{
|
|
||||||
//Context.Response.Charset = Encoding.UTF8.WebName;
|
|
||||||
|
|
||||||
var doctype = new LiteralControl("<!DOCTYPE html>\n");
|
|
||||||
base.Controls.Add(doctype);
|
|
||||||
|
|
||||||
var html = new HtmlGenericControl("html");
|
|
||||||
base.Controls.Add(html);
|
|
||||||
|
|
||||||
html.Controls.Add(_head);
|
|
||||||
|
|
||||||
_head.Controls.Add(new HtmlMeta {HttpEquiv = "X-UA-Compatible", Content = "IE=Edge"});
|
|
||||||
_head.Controls.Add(new HtmlMeta {HttpEquiv = "content-type", Content = "text/html; charset=utf-8"});
|
|
||||||
_head.Controls.Add(new HtmlMeta {Name = "author", Content = GlobalConfig.Get().Author});
|
|
||||||
_head.Controls.Add(new HtmlMeta {Name = "Copyright", Content = GlobalConfig.Get().Copyright});
|
|
||||||
_head.Controls.Add(
|
|
||||||
new HtmlMeta
|
|
||||||
{
|
|
||||||
Name = "viewport",
|
|
||||||
Content = "width=device-width, initial-scale=1, maximum-scale=4, user-scalable=1"
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
string? version = Assembly.GetExecutingAssembly().GetName().Version?.ToString();
|
|
||||||
_head.Controls.Add(
|
|
||||||
new LiteralControl($"<script type=\"text/javascript\" src=\"ScriptsBundler?v={version}\"></script>\n")
|
|
||||||
);
|
|
||||||
_head.Controls.Add(
|
|
||||||
new LiteralControl($"<link href=\"StylesBundler?v={version}\" type=\"text/css\" rel=\"stylesheet\"/>\n")
|
|
||||||
);
|
|
||||||
|
|
||||||
html.Controls.Add(_body);
|
|
||||||
_body.Controls.Add(_form);
|
|
||||||
|
|
||||||
var pnlHeader = new Panel {CssClass = "divHeader"};
|
|
||||||
_form.Controls.Add(pnlHeader);
|
|
||||||
|
|
||||||
HyperLink lnkTitle = new HyperLink {NavigateUrl = "."};
|
|
||||||
pnlHeader.Controls.Add(lnkTitle);
|
|
||||||
|
|
||||||
var lblTitle = new Label {Text = GlobalConfig.Get().Title, Tag = "h1"};
|
|
||||||
lnkTitle.Controls.Add(lblTitle);
|
|
||||||
|
|
||||||
_btnPostback.ID = "btnPostback";
|
|
||||||
_btnPostback.Text = "Postback";
|
|
||||||
pnlHeader.Controls.Add(_btnPostback);
|
|
||||||
_btnPostback.Style.Add("display", "none");
|
|
||||||
|
|
||||||
var pnlUserInfo = new Panel {CssClass = "divUserInfo"};
|
|
||||||
pnlHeader.Controls.Add(pnlUserInfo);
|
|
||||||
|
|
||||||
_btnLogout.ID = "btnLogout";
|
|
||||||
_btnLogout.Text = MultiLang.GetLiteral("Logout");
|
|
||||||
_btnLogout.Click += btnLogout_Click;
|
|
||||||
_btnLogout.Attributes.Add(
|
|
||||||
"onclick",
|
|
||||||
$"return confirm('{MultiLang.GetLiteral("ConfirmExit")}');"
|
|
||||||
);
|
|
||||||
pnlUserInfo.Controls.Add(_btnLogout);
|
|
||||||
|
|
||||||
_pnlContainer.CssClass = "divContent";
|
|
||||||
_form.Controls.Add(_pnlContainer);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Private methods
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void PageCommon_PreInit(object? sender, EventArgs e)
|
||||||
|
{
|
||||||
|
Context?.PrepareUncacheableResponse();
|
||||||
|
|
||||||
|
if (Context != null)
|
||||||
|
{
|
||||||
|
_isAuthenticated = GlobalConfig.Get().IsUserAuthenticated(Context);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MustBeAuthenticated && _isAuthenticated == false)
|
||||||
|
{
|
||||||
|
Context?.ResponseRedirect(GlobalConfig.Get().LoginHandler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PageCommon_Init(object? sender, EventArgs e) { CreateControls(); }
|
||||||
|
|
||||||
|
private void PageCommon_PreRender(object? sender, EventArgs e)
|
||||||
|
{
|
||||||
|
_head.Title = string.IsNullOrEmpty(Title)
|
||||||
|
? GlobalConfig.Get().Title
|
||||||
|
: string.Concat(Title, GlobalConfig.Get().TitleSeparator, GlobalConfig.Get().Title);
|
||||||
|
_btnLogout.Visible = _isAuthenticated;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion Life cycle
|
||||||
|
|
||||||
|
#region UI Events
|
||||||
|
|
||||||
|
private void btnLogout_Click(object? sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if(Context != null)
|
||||||
|
{
|
||||||
|
GlobalConfig.Get().UserDeauthenticate(Context);
|
||||||
|
}
|
||||||
|
if (MustBeAuthenticated) { Context?.ResponseRedirect(GlobalConfig.Get().LoginHandler); }
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion UI Events
|
||||||
|
|
||||||
|
#region Private methods
|
||||||
|
|
||||||
|
private void CreateControls()
|
||||||
|
{
|
||||||
|
//Context.Response.Charset = Encoding.UTF8.WebName;
|
||||||
|
|
||||||
|
var doctype = new LiteralControl("<!DOCTYPE html>\n");
|
||||||
|
base.Controls.Add(doctype);
|
||||||
|
|
||||||
|
var html = new HtmlGenericControl("html");
|
||||||
|
base.Controls.Add(html);
|
||||||
|
|
||||||
|
html.Controls.Add(_head);
|
||||||
|
|
||||||
|
_head.Controls.Add(new HtmlMeta {HttpEquiv = "X-UA-Compatible", Content = "IE=Edge"});
|
||||||
|
_head.Controls.Add(new HtmlMeta {HttpEquiv = "content-type", Content = "text/html; charset=utf-8"});
|
||||||
|
_head.Controls.Add(new HtmlMeta {Name = "author", Content = GlobalConfig.Get().Author});
|
||||||
|
_head.Controls.Add(new HtmlMeta {Name = "Copyright", Content = GlobalConfig.Get().Copyright});
|
||||||
|
_head.Controls.Add(
|
||||||
|
new HtmlMeta
|
||||||
|
{
|
||||||
|
Name = "viewport",
|
||||||
|
Content = "width=device-width, initial-scale=1, maximum-scale=4, user-scalable=1"
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
string? version = Assembly.GetExecutingAssembly().GetName().Version?.ToString();
|
||||||
|
_head.Controls.Add(
|
||||||
|
new LiteralControl($"<script type=\"text/javascript\" src=\"ScriptsBundler?v={version}\"></script>\n")
|
||||||
|
);
|
||||||
|
_head.Controls.Add(
|
||||||
|
new LiteralControl($"<link href=\"StylesBundler?v={version}\" type=\"text/css\" rel=\"stylesheet\"/>\n")
|
||||||
|
);
|
||||||
|
|
||||||
|
html.Controls.Add(_body);
|
||||||
|
_body.Controls.Add(_form);
|
||||||
|
|
||||||
|
var pnlHeader = new Panel {CssClass = "divHeader"};
|
||||||
|
_form.Controls.Add(pnlHeader);
|
||||||
|
|
||||||
|
HyperLink lnkTitle = new HyperLink {NavigateUrl = "."};
|
||||||
|
pnlHeader.Controls.Add(lnkTitle);
|
||||||
|
|
||||||
|
var lblTitle = new Label {Text = GlobalConfig.Get().Title, Tag = "h1"};
|
||||||
|
lnkTitle.Controls.Add(lblTitle);
|
||||||
|
|
||||||
|
_btnPostback.ID = "btnPostback";
|
||||||
|
_btnPostback.Text = "Postback";
|
||||||
|
pnlHeader.Controls.Add(_btnPostback);
|
||||||
|
_btnPostback.Style.Add("display", "none");
|
||||||
|
|
||||||
|
var pnlUserInfo = new Panel {CssClass = "divUserInfo"};
|
||||||
|
pnlHeader.Controls.Add(pnlUserInfo);
|
||||||
|
|
||||||
|
_btnLogout.ID = "btnLogout";
|
||||||
|
_btnLogout.Text = MultiLang.GetLiteral("Logout");
|
||||||
|
_btnLogout.Click += btnLogout_Click;
|
||||||
|
_btnLogout.Attributes.Add(
|
||||||
|
"onclick",
|
||||||
|
$"return confirm('{MultiLang.GetLiteral("ConfirmExit")}');"
|
||||||
|
);
|
||||||
|
pnlUserInfo.Controls.Add(_btnLogout);
|
||||||
|
|
||||||
|
_pnlContainer.CssClass = "divContent";
|
||||||
|
_form.Controls.Add(_pnlContainer);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion Private methods
|
||||||
}
|
}
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
{
|
|
||||||
"iisSettings": {
|
|
||||||
"windowsAuthentication": false,
|
|
||||||
"anonymousAuthentication": true,
|
|
||||||
"iisExpress": {
|
|
||||||
"applicationUrl": "http://localhost:58454/",
|
|
||||||
"sslPort": 44386
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"profiles": {
|
|
||||||
"IIS Express": {
|
|
||||||
"commandName": "IISExpress",
|
|
||||||
"launchBrowser": true,
|
|
||||||
"environmentVariables": {
|
|
||||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"VAR.WebFormsCore": {
|
|
||||||
"commandName": "Project",
|
|
||||||
"launchBrowser": true,
|
|
||||||
"environmentVariables": {
|
|
||||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
|
||||||
},
|
|
||||||
"applicationUrl": "https://localhost:5001;http://localhost:5000"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Library</OutputType>
|
<OutputType>Library</OutputType>
|
||||||
<TargetFramework>net7.0</TargetFramework>
|
<TargetFramework>netstandard2.0</TargetFramework>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
|
<LangVersion>10</LangVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
Reference in New Issue
Block a user