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.Controls;
|
||||
using VAR.WebFormsCore.Pages;
|
||||
|
||||
@@ -1,17 +1,12 @@
|
||||
namespace VAR.WebFormsCore.TestWebApp
|
||||
{
|
||||
using VAR.WebFormsCore.AspNetCore;
|
||||
|
||||
namespace VAR.WebFormsCore.TestWebApp;
|
||||
|
||||
public static class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
CreateHostBuilder(args).Build().Run();
|
||||
DefaultMain.WebFormCoreMain(args);
|
||||
}
|
||||
|
||||
private static IHostBuilder CreateHostBuilder(string[] args) =>
|
||||
Host.CreateDefaultBuilder(args)
|
||||
.ConfigureWebHostDefaults(webBuilder =>
|
||||
{
|
||||
webBuilder.UseStartup<Startup>();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
namespace VAR.WebFormsCore.TestWebApp;
|
||||
@@ -14,12 +15,12 @@ public class TestWebAppGlobalConfig : IGlobalConfig
|
||||
public List<string> AllowedExtensions { get; } = new()
|
||||
{ ".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;
|
||||
}
|
||||
|
||||
public void UserDeauthenticate(HttpContext context)
|
||||
public void UserDeauthenticate(IWebContext context)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -3,10 +3,10 @@
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\VAR.WebFormsCore.AspNetCore\VAR.WebFormsCore.AspNetCore.csproj" />
|
||||
<ProjectReference Include="..\VAR.WebFormsCore\VAR.WebFormsCore.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VAR.WebFormsCore", "VAR.Web
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VAR.WebFormsCore.TestWebApp", "VAR.WebFormsCore.TestWebApp\VAR.WebFormsCore.TestWebApp.csproj", "{0D81464B-802D-4ECA-92C8-427F481A4583}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VAR.WebFormsCore.AspNetCore", "VAR.WebFormsCore.AspNetCore\VAR.WebFormsCore.AspNetCore.csproj", "{378B98EF-9269-4B96-B894-1B0F9B24EEC2}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
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}.Release|Any CPU.ActiveCfg = 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
|
||||
EndGlobal
|
||||
|
||||
@@ -3,10 +3,9 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace VAR.WebFormsCore.Code
|
||||
{
|
||||
namespace VAR.WebFormsCore.Code;
|
||||
|
||||
public class Bundler
|
||||
{
|
||||
#region Declarations
|
||||
@@ -75,10 +74,10 @@ namespace VAR.WebFormsCore.Code
|
||||
|
||||
private static readonly Encoding Utf8Encoding = new UTF8Encoding();
|
||||
|
||||
public void WriteResponse(HttpResponse response, string contentType)
|
||||
public void WriteResponse(IWebContext context, string contentType)
|
||||
{
|
||||
StringWriter textWriter = new StringWriter();
|
||||
response.ContentType = contentType;
|
||||
context.ResponseContentType = contentType;
|
||||
foreach (string fileName in AssemblyFiles)
|
||||
{
|
||||
Stream? resourceStream = _assembly?.GetManifestResourceStream(fileName);
|
||||
@@ -99,9 +98,8 @@ namespace VAR.WebFormsCore.Code
|
||||
}
|
||||
|
||||
byte[] byteObject = Utf8Encoding.GetBytes(textWriter.ToString());
|
||||
response.Body.WriteAsync(byteObject).GetAwaiter().GetResult();
|
||||
context.ResponseWriteBin(byteObject);
|
||||
}
|
||||
|
||||
#endregion Public methods
|
||||
}
|
||||
}
|
||||
@@ -1,27 +1,31 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using VAR.Json;
|
||||
|
||||
namespace VAR.WebFormsCore.Code
|
||||
{
|
||||
namespace VAR.WebFormsCore.Code;
|
||||
|
||||
public static class ExtensionMethods
|
||||
{
|
||||
#region HttpContext
|
||||
#region IWebContext
|
||||
|
||||
public static string GetRequestParameter(this HttpContext context, string parameter)
|
||||
public static string GetRequestParameter(this IWebContext context, string parameter)
|
||||
{
|
||||
if (context.Request.Method == "POST")
|
||||
if (context.RequestMethod == "POST")
|
||||
{
|
||||
foreach (string key in context.Request.Form.Keys)
|
||||
foreach (string key in context.RequestForm.Keys)
|
||||
{
|
||||
if (string.IsNullOrEmpty(key) == false && key == parameter) { return context.Request.Form[key][0] ?? string.Empty; }
|
||||
if (string.IsNullOrEmpty(key) == false && key == parameter)
|
||||
{
|
||||
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 context.RequestQuery[key] ?? string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
@@ -29,38 +33,13 @@ namespace VAR.WebFormsCore.Code
|
||||
|
||||
private static readonly Encoding Utf8Encoding = new UTF8Encoding();
|
||||
|
||||
public static void ResponseObject(this HttpContext context, object obj, string contentType = "text/json")
|
||||
public static void ResponseObject(this IWebContext context, object obj, string contentType = "text/json")
|
||||
{
|
||||
context.Response.ContentType = contentType;
|
||||
context.ResponseContentType = contentType;
|
||||
string strObject = JsonWriter.WriteObject(obj);
|
||||
byte[] byteObject = Utf8Encoding.GetBytes(strObject);
|
||||
context.Response.Body.WriteAsync(byteObject).GetAwaiter().GetResult();
|
||||
context.ResponseWriteBin(byteObject);
|
||||
}
|
||||
|
||||
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); }
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
#endregion IWebContext
|
||||
}
|
||||
@@ -1,10 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace VAR.WebFormsCore.Code
|
||||
{
|
||||
namespace VAR.WebFormsCore.Code;
|
||||
|
||||
public static class GlobalConfig
|
||||
{
|
||||
private static IGlobalConfig? _globalConfig;
|
||||
@@ -41,14 +40,13 @@ namespace VAR.WebFormsCore.Code
|
||||
public string LoginHandler => string.Empty;
|
||||
public List<string> AllowedExtensions { get; } = new();
|
||||
|
||||
public bool IsUserAuthenticated(HttpContext context)
|
||||
public bool IsUserAuthenticated(IWebContext context)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public void UserDeauthenticate(HttpContext context)
|
||||
public void UserDeauthenticate(IWebContext context)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,18 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using VAR.WebFormsCore.Pages;
|
||||
|
||||
namespace VAR.WebFormsCore.Code
|
||||
{
|
||||
namespace VAR.WebFormsCore.Code;
|
||||
|
||||
public static class GlobalErrorHandler
|
||||
{
|
||||
#region Private methods
|
||||
|
||||
private static void ShowInternalError(HttpContext context, Exception ex)
|
||||
private static void ShowInternalError(IWebContext context, Exception ex)
|
||||
{
|
||||
try
|
||||
{
|
||||
context.Response.StatusCode = 500;
|
||||
context.ResponseStatusCode = 500;
|
||||
|
||||
StringBuilder sbOutput = new StringBuilder();
|
||||
sbOutput.Append("<h2>Internal error</h2>");
|
||||
@@ -35,8 +34,8 @@ namespace VAR.WebFormsCore.Code
|
||||
sbOutput.Append("-->");
|
||||
}
|
||||
|
||||
context.Response.WriteAsync(sbOutput.ToString()).GetAwaiter().GetResult();
|
||||
context.Response.Body.FlushAsync().GetAwaiter().GetResult();
|
||||
context.ResponseWrite(sbOutput.ToString());
|
||||
context.ResponseFlush();
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -48,7 +47,7 @@ namespace VAR.WebFormsCore.Code
|
||||
|
||||
#region Public methods
|
||||
|
||||
public static void HandleError(HttpContext context, Exception ex)
|
||||
public static void HandleError(IWebContext context, Exception ex)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -56,11 +55,10 @@ namespace VAR.WebFormsCore.Code
|
||||
//context.Response.Clear();
|
||||
//context.Handler = frmError;
|
||||
frmError.ProcessRequest(context);
|
||||
context.Response.Body.FlushAsync().GetAwaiter().GetResult();
|
||||
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,8 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace VAR.WebFormsCore.Code
|
||||
{
|
||||
namespace VAR.WebFormsCore.Code;
|
||||
|
||||
public interface IGlobalConfig
|
||||
{
|
||||
string Title { get; }
|
||||
@@ -13,7 +12,6 @@ namespace VAR.WebFormsCore.Code
|
||||
string LoginHandler { get; }
|
||||
List<string> AllowedExtensions { get; }
|
||||
|
||||
bool IsUserAuthenticated(HttpContext context);
|
||||
void UserDeauthenticate(HttpContext context);
|
||||
}
|
||||
bool IsUserAuthenticated(IWebContext context);
|
||||
void UserDeauthenticate(IWebContext context);
|
||||
}
|
||||
@@ -1,9 +1,6 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
namespace VAR.WebFormsCore.Code;
|
||||
|
||||
namespace VAR.WebFormsCore.Code
|
||||
{
|
||||
public interface IHttpHandler
|
||||
{
|
||||
void ProcessRequest(HttpContext context);
|
||||
}
|
||||
void ProcessRequest(IWebContext 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,8 +2,8 @@
|
||||
using System.IO;
|
||||
using VAR.Json;
|
||||
|
||||
namespace VAR.WebFormsCore.Code
|
||||
{
|
||||
namespace VAR.WebFormsCore.Code;
|
||||
|
||||
public static class MultiLang
|
||||
{
|
||||
private static string GetPrivatePath(string baseDir, string fileName)
|
||||
@@ -93,4 +93,3 @@ namespace VAR.WebFormsCore.Code
|
||||
return (literalCurrentCulture[resource] as string) ?? resource;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,8 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace VAR.WebFormsCore.Code
|
||||
{
|
||||
namespace VAR.WebFormsCore.Code;
|
||||
|
||||
public static class ObjectActivator
|
||||
{
|
||||
private static readonly Dictionary<Type, Func<object>> Creators = new();
|
||||
@@ -30,4 +30,3 @@ namespace VAR.WebFormsCore.Code
|
||||
return creator();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,23 +1,21 @@
|
||||
using System.Reflection;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace VAR.WebFormsCore.Code
|
||||
{
|
||||
namespace VAR.WebFormsCore.Code;
|
||||
|
||||
public class ScriptsBundler : IHttpHandler
|
||||
{
|
||||
#region IHttpHandler
|
||||
|
||||
public void ProcessRequest(HttpContext context)
|
||||
public void ProcessRequest(IWebContext context)
|
||||
{
|
||||
Bundler bundler = new Bundler(
|
||||
assembly: Assembly.GetExecutingAssembly(),
|
||||
assemblyNamespace: "Scripts",
|
||||
absolutePath: ServerHelpers.MapContentPath("Scripts")
|
||||
);
|
||||
context.Response.PrepareCacheableResponse();
|
||||
bundler.WriteResponse(context.Response, "text/javascript");
|
||||
context.PrepareCacheableResponse();
|
||||
bundler.WriteResponse(context, "text/javascript");
|
||||
}
|
||||
|
||||
#endregion IHttpHandler
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
|
||||
namespace VAR.WebFormsCore.Code
|
||||
{
|
||||
namespace VAR.WebFormsCore.Code;
|
||||
|
||||
public static class ServerHelpers
|
||||
{
|
||||
private static string? _contentRoot;
|
||||
@@ -115,4 +115,3 @@ namespace VAR.WebFormsCore.Code
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,8 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace VAR.WebFormsCore.Code
|
||||
{
|
||||
namespace VAR.WebFormsCore.Code;
|
||||
|
||||
public static class StaticFileHelper
|
||||
{
|
||||
private static readonly Dictionary<string, string> MimeTypeByExtension = new()
|
||||
@@ -68,17 +67,16 @@ namespace VAR.WebFormsCore.Code
|
||||
{".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();
|
||||
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);
|
||||
context.Response.Body.WriteAsync(fileData).GetAwaiter().GetResult();
|
||||
}
|
||||
context.ResponseWriteBin(fileData);
|
||||
}
|
||||
}
|
||||
@@ -1,23 +1,21 @@
|
||||
using System.Reflection;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace VAR.WebFormsCore.Code
|
||||
{
|
||||
namespace VAR.WebFormsCore.Code;
|
||||
|
||||
public class StylesBundler : IHttpHandler
|
||||
{
|
||||
#region IHttpHandler
|
||||
|
||||
public void ProcessRequest(HttpContext context)
|
||||
public void ProcessRequest(IWebContext context)
|
||||
{
|
||||
Bundler bundler = new Bundler(
|
||||
assembly: Assembly.GetExecutingAssembly(),
|
||||
assemblyNamespace: "Styles",
|
||||
absolutePath: ServerHelpers.MapContentPath("Styles")
|
||||
);
|
||||
context.Response.PrepareCacheableResponse();
|
||||
bundler.WriteResponse(context.Response, "text/css");
|
||||
context.PrepareCacheableResponse();
|
||||
bundler.WriteResponse(context, "text/css");
|
||||
}
|
||||
|
||||
#endregion IHttpHandler
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
namespace VAR.WebFormsCore.Code
|
||||
{
|
||||
namespace VAR.WebFormsCore.Code;
|
||||
|
||||
public class Unit
|
||||
{
|
||||
private readonly int _value;
|
||||
@@ -25,4 +25,3 @@
|
||||
{
|
||||
Pixel, Percentage,
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace VAR.WebFormsCore.Controls
|
||||
{
|
||||
namespace VAR.WebFormsCore.Controls;
|
||||
|
||||
public class Button : Control, IReceivePostbackEvent
|
||||
{
|
||||
public Button() { CssClass = "button"; }
|
||||
@@ -39,4 +39,3 @@ namespace VAR.WebFormsCore.Controls
|
||||
|
||||
public void ReceivePostBack() { Click?.Invoke(this, EventArgs.Empty); }
|
||||
}
|
||||
}
|
||||
@@ -3,8 +3,8 @@ using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using VAR.Json;
|
||||
|
||||
namespace VAR.WebFormsCore.Controls
|
||||
{
|
||||
namespace VAR.WebFormsCore.Controls;
|
||||
|
||||
public class CTextBox : Control, INamingContainer, IValidableControl
|
||||
{
|
||||
#region Declarations
|
||||
@@ -75,7 +75,7 @@ namespace VAR.WebFormsCore.Controls
|
||||
public TextBoxMode TextMode
|
||||
{
|
||||
get => _txtContent.TextMode;
|
||||
init => _txtContent.TextMode = value;
|
||||
set => _txtContent.TextMode = value;
|
||||
}
|
||||
|
||||
#endregion Properties
|
||||
@@ -157,7 +157,7 @@ namespace VAR.WebFormsCore.Controls
|
||||
if (string.IsNullOrEmpty(_hidSize?.Value)) { return null; }
|
||||
|
||||
JsonParser jsonParser = new JsonParser();
|
||||
Dictionary<string, object>? sizeObj = jsonParser.Parse(_hidSize.Value) as Dictionary<string, object>;
|
||||
Dictionary<string, object>? sizeObj = jsonParser.Parse(_hidSize?.Value) as Dictionary<string, object>;
|
||||
if (sizeObj == null) { return null; }
|
||||
|
||||
if (sizeObj.ContainsKey("height") == false) { return null; }
|
||||
@@ -180,7 +180,7 @@ namespace VAR.WebFormsCore.Controls
|
||||
if (string.IsNullOrEmpty(_hidSize?.Value) == false)
|
||||
{
|
||||
JsonParser jsonParser = new JsonParser();
|
||||
sizeObj = jsonParser.Parse(_hidSize.Value) as Dictionary<string, object?>;
|
||||
sizeObj = jsonParser.Parse(_hidSize?.Value) as Dictionary<string, object?>;
|
||||
}
|
||||
sizeObj ??= new Dictionary<string, object?> { { "height", height }, { "width", null }, { "scrollTop", null }, };
|
||||
|
||||
@@ -192,4 +192,3 @@ namespace VAR.WebFormsCore.Controls
|
||||
|
||||
#endregion Public methods
|
||||
}
|
||||
}
|
||||
@@ -5,8 +5,8 @@ using System.Text;
|
||||
using VAR.WebFormsCore.Code;
|
||||
using VAR.WebFormsCore.Pages;
|
||||
|
||||
namespace VAR.WebFormsCore.Controls
|
||||
{
|
||||
namespace VAR.WebFormsCore.Controls;
|
||||
|
||||
public class Control
|
||||
{
|
||||
public event EventHandler? PreInit;
|
||||
@@ -195,4 +195,3 @@ namespace VAR.WebFormsCore.Controls
|
||||
return controls;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace VAR.WebFormsCore.Controls
|
||||
{
|
||||
namespace VAR.WebFormsCore.Controls;
|
||||
|
||||
public class ControlCollection : List<Control>
|
||||
{
|
||||
private readonly Control _parent;
|
||||
@@ -18,4 +18,3 @@ namespace VAR.WebFormsCore.Controls
|
||||
base.Add(control);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
using System.IO;
|
||||
|
||||
namespace VAR.WebFormsCore.Controls
|
||||
{
|
||||
namespace VAR.WebFormsCore.Controls;
|
||||
|
||||
public class HiddenField : Control
|
||||
{
|
||||
private string _value = string.Empty;
|
||||
@@ -14,9 +14,9 @@ namespace VAR.WebFormsCore.Controls
|
||||
|
||||
protected override void Process()
|
||||
{
|
||||
if (Page?.IsPostBack == true && Page?.Context?.Request.Form.ContainsKey(ClientID) == true)
|
||||
if (Page?.IsPostBack == true && Page?.Context?.RequestForm.ContainsKey(ClientID) == true)
|
||||
{
|
||||
Value = Page?.Context.Request.Form[ClientID][0] ?? string.Empty;
|
||||
Value = Page?.Context.RequestForm[ClientID] ?? string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,4 +30,3 @@ namespace VAR.WebFormsCore.Controls
|
||||
textWriter.Write("</input>");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
namespace VAR.WebFormsCore.Controls
|
||||
{
|
||||
namespace VAR.WebFormsCore.Controls;
|
||||
|
||||
public class HtmlBody : HtmlGenericControl
|
||||
{
|
||||
public HtmlBody() : base("body") { }
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
using VAR.WebFormsCore.Code;
|
||||
|
||||
namespace VAR.WebFormsCore.Controls
|
||||
@@ -28,15 +27,15 @@ namespace VAR.WebFormsCore.Controls
|
||||
StringBuilder sbAction = new();
|
||||
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('?');
|
||||
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 value = ServerHelpers.UrlEncode(queryParam.Value[0] ?? string.Empty);
|
||||
string value = ServerHelpers.UrlEncode(queryParam.Value ?? string.Empty);
|
||||
sbAction.Append($"&{key}={value}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using System.IO;
|
||||
|
||||
namespace VAR.WebFormsCore.Controls
|
||||
{
|
||||
namespace VAR.WebFormsCore.Controls;
|
||||
|
||||
public class HtmlGenericControl : Control
|
||||
{
|
||||
private readonly string _tagName;
|
||||
@@ -19,4 +19,3 @@ namespace VAR.WebFormsCore.Controls
|
||||
textWriter.Write("</{0}>", _tagName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
using System.IO;
|
||||
|
||||
namespace VAR.WebFormsCore.Controls
|
||||
{
|
||||
namespace VAR.WebFormsCore.Controls;
|
||||
|
||||
public class HtmlHead : Control
|
||||
{
|
||||
public string Title { get; set; } = string.Empty;
|
||||
@@ -19,4 +19,3 @@ namespace VAR.WebFormsCore.Controls
|
||||
textWriter.Write("</head>");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,12 @@
|
||||
using System.IO;
|
||||
|
||||
namespace VAR.WebFormsCore.Controls
|
||||
{
|
||||
namespace VAR.WebFormsCore.Controls;
|
||||
|
||||
public class HtmlMeta : Control
|
||||
{
|
||||
public string Name { get; init; } = string.Empty;
|
||||
public string Content { get; init; } = string.Empty;
|
||||
public string HttpEquiv { get; internal init; } = string.Empty;
|
||||
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)
|
||||
{
|
||||
@@ -21,4 +21,3 @@ namespace VAR.WebFormsCore.Controls
|
||||
textWriter.Write(" />");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
using System.IO;
|
||||
|
||||
namespace VAR.WebFormsCore.Controls
|
||||
{
|
||||
namespace VAR.WebFormsCore.Controls;
|
||||
|
||||
public class HyperLink : Control
|
||||
{
|
||||
public string NavigateUrl { get; set; } = string.Empty;
|
||||
public string Text { get; init; } = string.Empty;
|
||||
public string Text { get; set; } = string.Empty;
|
||||
|
||||
protected override void Render(TextWriter textWriter)
|
||||
{
|
||||
@@ -22,4 +22,3 @@ namespace VAR.WebFormsCore.Controls
|
||||
textWriter.Write("</a>");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
namespace VAR.WebFormsCore.Controls
|
||||
{
|
||||
namespace VAR.WebFormsCore.Controls;
|
||||
|
||||
public interface INamingContainer
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
namespace VAR.WebFormsCore.Controls
|
||||
{
|
||||
namespace VAR.WebFormsCore.Controls;
|
||||
|
||||
public interface IReceivePostbackEvent
|
||||
{
|
||||
void ReceivePostBack();
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
namespace VAR.WebFormsCore.Controls
|
||||
{
|
||||
namespace VAR.WebFormsCore.Controls;
|
||||
|
||||
public interface IValidableControl
|
||||
{
|
||||
bool IsValid();
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
using System.IO;
|
||||
using VAR.WebFormsCore.Code;
|
||||
|
||||
namespace VAR.WebFormsCore.Controls
|
||||
{
|
||||
namespace VAR.WebFormsCore.Controls;
|
||||
|
||||
public class Label : Control
|
||||
{
|
||||
#region Properties
|
||||
@@ -42,4 +42,3 @@ namespace VAR.WebFormsCore.Controls
|
||||
|
||||
#endregion Life cycle
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
using System.IO;
|
||||
|
||||
namespace VAR.WebFormsCore.Controls
|
||||
{
|
||||
namespace VAR.WebFormsCore.Controls;
|
||||
|
||||
public class LiteralControl : Control
|
||||
{
|
||||
public string Content { get; set; } = string.Empty;
|
||||
@@ -11,4 +11,3 @@ namespace VAR.WebFormsCore.Controls
|
||||
|
||||
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 Panel() : base("div") { }
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
using System.IO;
|
||||
using VAR.WebFormsCore.Code;
|
||||
|
||||
namespace VAR.WebFormsCore.Controls
|
||||
{
|
||||
namespace VAR.WebFormsCore.Controls;
|
||||
|
||||
public class TextBox : Control
|
||||
{
|
||||
public string Text { get; set; } = string.Empty;
|
||||
@@ -11,9 +11,9 @@ namespace VAR.WebFormsCore.Controls
|
||||
|
||||
protected override void Process()
|
||||
{
|
||||
if (Page?.IsPostBack == true && Page?.Context?.Request.Form.ContainsKey(ClientID) == true)
|
||||
if (Page?.IsPostBack == true && Page?.Context?.RequestForm.ContainsKey(ClientID) == true)
|
||||
{
|
||||
Text = Page?.Context.Request.Form[ClientID][0] ?? string.Empty;
|
||||
Text = Page?.Context.RequestForm[ClientID] ?? string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,4 +52,3 @@ namespace VAR.WebFormsCore.Controls
|
||||
{
|
||||
Normal, Password, MultiLine,
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
using VAR.WebFormsCore.Controls;
|
||||
|
||||
namespace VAR.WebFormsCore.Pages
|
||||
{
|
||||
namespace VAR.WebFormsCore.Pages;
|
||||
|
||||
public static class FormUtils
|
||||
{
|
||||
public static Control CreatePanel(string cssClass, Control? ctrl = null)
|
||||
@@ -63,4 +63,3 @@ namespace VAR.WebFormsCore.Pages
|
||||
return valid;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,20 +1,21 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using VAR.Json;
|
||||
using VAR.Json;
|
||||
using VAR.WebFormsCore.Code;
|
||||
|
||||
namespace VAR.WebFormsCore.Pages
|
||||
{
|
||||
namespace VAR.WebFormsCore.Pages;
|
||||
|
||||
public class FrmEcho : IHttpHandler
|
||||
{
|
||||
#region IHttpHandler
|
||||
|
||||
public void ProcessRequest(HttpContext context)
|
||||
public void ProcessRequest(IWebContext context)
|
||||
{
|
||||
context.Response.WriteAsync("<pre><code>").GetAwaiter().GetResult();
|
||||
context.Response.WriteAsync(JsonWriter.WriteObject(context.Request, indent: true)).GetAwaiter().GetResult();
|
||||
context.Response.WriteAsync("</code></pre>").GetAwaiter().GetResult();
|
||||
context.ResponseContentType = "text/html";
|
||||
context.ResponseWrite("<pre><code>");
|
||||
context.ResponseWrite($"Header:{JsonWriter.WriteObject(context.RequestHeader, indent: true)}\n");
|
||||
context.ResponseWrite($"Query:{JsonWriter.WriteObject(context.RequestQuery, indent: true)}\n");
|
||||
context.ResponseWrite($"Form:{JsonWriter.WriteObject(context.RequestForm, indent: true)}\n");
|
||||
context.ResponseWrite("</code></pre>");
|
||||
}
|
||||
|
||||
#endregion IHttpHandler
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,8 @@
|
||||
using System.Web;
|
||||
using VAR.WebFormsCore.Controls;
|
||||
|
||||
namespace VAR.WebFormsCore.Pages
|
||||
{
|
||||
namespace VAR.WebFormsCore.Pages;
|
||||
|
||||
public class FrmError : PageCommon
|
||||
{
|
||||
#region Declarations
|
||||
@@ -58,4 +58,3 @@ namespace VAR.WebFormsCore.Pages
|
||||
|
||||
#endregion Private methods
|
||||
}
|
||||
}
|
||||
@@ -2,21 +2,20 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using VAR.WebFormsCore.Code;
|
||||
using VAR.WebFormsCore.Controls;
|
||||
|
||||
namespace VAR.WebFormsCore.Pages
|
||||
{
|
||||
namespace VAR.WebFormsCore.Pages;
|
||||
|
||||
public class Page : Control, IHttpHandler
|
||||
{
|
||||
protected string Title { get; set; } = string.Empty;
|
||||
|
||||
public HttpContext? Context { get; private set; }
|
||||
public IWebContext? Context { get; private set; }
|
||||
|
||||
private static readonly Encoding Utf8Encoding = new UTF8Encoding();
|
||||
|
||||
public void ProcessRequest(HttpContext context)
|
||||
public void ProcessRequest(IWebContext context)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -25,16 +24,16 @@ namespace VAR.WebFormsCore.Pages
|
||||
Context = context;
|
||||
Page = this;
|
||||
|
||||
if (context.Request.Method == "POST") { _isPostBack = true; }
|
||||
if (context.RequestMethod == "POST") { _isPostBack = true; }
|
||||
|
||||
OnPreInit(EventArgs.Empty);
|
||||
if (context.Response.HasStarted) { return; }
|
||||
if (context.ResponseHasStarted) { return; }
|
||||
|
||||
OnInit(EventArgs.Empty);
|
||||
if (context.Response.HasStarted) { return; }
|
||||
if (context.ResponseHasStarted) { return; }
|
||||
|
||||
OnLoad(EventArgs.Empty);
|
||||
if (context.Response.HasStarted) { return; }
|
||||
if (context.ResponseHasStarted) { return; }
|
||||
|
||||
if (_isPostBack)
|
||||
{
|
||||
@@ -42,23 +41,24 @@ namespace VAR.WebFormsCore.Pages
|
||||
foreach (Control control in controls)
|
||||
{
|
||||
string clientID = control.ClientID;
|
||||
if (context.Request.Form.ContainsKey(clientID))
|
||||
if (context.RequestForm.ContainsKey(clientID))
|
||||
{
|
||||
(control as IReceivePostbackEvent)?.ReceivePostBack();
|
||||
if (context.Response.HasStarted) { return; }
|
||||
if (context.ResponseHasStarted) { return; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OnPreRender(EventArgs.Empty);
|
||||
if (context.Response.HasStarted) { return; }
|
||||
if (context.ResponseHasStarted) { return; }
|
||||
|
||||
Render(stringWriter);
|
||||
if (context.Response.HasStarted) { return; }
|
||||
if (context.ResponseHasStarted) { return; }
|
||||
|
||||
context.Response.Headers.SafeSet("Content-Type", "text/html");
|
||||
//context.SetResponseHeader("Content-Type", "text/html");
|
||||
context.ResponseContentType = "text/html";
|
||||
byte[] byteObject = Utf8Encoding.GetBytes(stringWriter.ToString());
|
||||
context.Response.Body.WriteAsync(byteObject).GetAwaiter().GetResult();
|
||||
context.ResponseWriteBin(byteObject);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -74,4 +74,3 @@ namespace VAR.WebFormsCore.Pages
|
||||
|
||||
public bool IsPostBack => _isPostBack;
|
||||
}
|
||||
}
|
||||
@@ -3,8 +3,8 @@ using System.Reflection;
|
||||
using VAR.WebFormsCore.Code;
|
||||
using VAR.WebFormsCore.Controls;
|
||||
|
||||
namespace VAR.WebFormsCore.Pages
|
||||
{
|
||||
namespace VAR.WebFormsCore.Pages;
|
||||
|
||||
public class PageCommon : Page
|
||||
{
|
||||
#region Declarations
|
||||
@@ -24,7 +24,7 @@ namespace VAR.WebFormsCore.Pages
|
||||
|
||||
public new ControlCollection Controls => _pnlContainer.Controls;
|
||||
|
||||
public bool MustBeAuthenticated { get; init; } = true;
|
||||
public bool MustBeAuthenticated { get; set; } = true;
|
||||
|
||||
#endregion Properties
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace VAR.WebFormsCore.Pages
|
||||
|
||||
private void PageCommon_PreInit(object? sender, EventArgs e)
|
||||
{
|
||||
Context?.Response.PrepareUncacheableResponse();
|
||||
Context?.PrepareUncacheableResponse();
|
||||
|
||||
if (Context != null)
|
||||
{
|
||||
@@ -48,7 +48,7 @@ namespace VAR.WebFormsCore.Pages
|
||||
|
||||
if (MustBeAuthenticated && _isAuthenticated == false)
|
||||
{
|
||||
Context?.Response.Redirect(GlobalConfig.Get().LoginHandler);
|
||||
Context?.ResponseRedirect(GlobalConfig.Get().LoginHandler);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ namespace VAR.WebFormsCore.Pages
|
||||
{
|
||||
GlobalConfig.Get().UserDeauthenticate(Context);
|
||||
}
|
||||
if (MustBeAuthenticated) { Context?.Response.Redirect(GlobalConfig.Get().LoginHandler); }
|
||||
if (MustBeAuthenticated) { Context?.ResponseRedirect(GlobalConfig.Get().LoginHandler); }
|
||||
}
|
||||
|
||||
#endregion UI Events
|
||||
@@ -146,4 +146,3 @@ namespace VAR.WebFormsCore.Pages
|
||||
|
||||
#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>
|
||||
<OutputType>Library</OutputType>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<LangVersion>10</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
Reference in New Issue
Block a user