Doing some fixup
This commit is contained in:
parent
ee57c7a3ca
commit
d07cd21b98
|
@ -2,13 +2,14 @@
|
||||||
[![Tesses.WebServer Nuget](https://badgen.net/nuget/v/Tesses.WebServer)](https://www.nuget.org/packages/Tesses.WebServer/)
|
[![Tesses.WebServer Nuget](https://badgen.net/nuget/v/Tesses.WebServer)](https://www.nuget.org/packages/Tesses.WebServer/)
|
||||||
![Tesses.WebServer Downloads](https://badgen.net/nuget/dt/Tesses.WebServer)
|
![Tesses.WebServer Downloads](https://badgen.net/nuget/dt/Tesses.WebServer)
|
||||||
|
|
||||||
|
|
||||||
# License
|
# License
|
||||||
Starting with 1.0.3.9 this library will use GPL-3.0
|
Starting with 1.0.3.9 this library will use GPL-3.0
|
||||||
If you can not use GPL either use 1.0.3.8 or use another library
|
If you can not use GPL either use 1.0.3.8 or use another library
|
||||||
|
|
||||||
A TcpListener HTTP Server
|
A TcpListener HTTP Server
|
||||||
|
|
||||||
WARNING: use at least version 1.0.4.2 because of security issue with paths
|
> WARNING: use at least version 1.0.4.2 because of security issue with paths
|
||||||
|
|
||||||
To make your life easier, install [Tesses.WebServer.EasyServer](https://www.nuget.org/packages/Tesses.WebServer.EasyServer) alongside [Tesses.WebServer](https://www.nuget.org/packages/Tesses.WebServer) and use this code:
|
To make your life easier, install [Tesses.WebServer.EasyServer](https://www.nuget.org/packages/Tesses.WebServer.EasyServer) alongside [Tesses.WebServer](https://www.nuget.org/packages/Tesses.WebServer) and use this code:
|
||||||
|
|
||||||
|
@ -50,3 +51,5 @@ server.StartServer(9500); //or any port number
|
||||||
- Reverse Proxy (in a seperate library)
|
- Reverse Proxy (in a seperate library)
|
||||||
|
|
||||||
> Note: Range code, POST code and Route Class is not mine its a modified version of the code from ( [dajuric/simple-http](https://github.com/dajuric/simple-http/blob/master/Source/SimpleHTTP/Extensions/Response/ResponseExtensions.PartialStream.cs "dajuric/simple-http"))
|
> Note: Range code, POST code and Route Class is not mine its a modified version of the code from ( [dajuric/simple-http](https://github.com/dajuric/simple-http/blob/master/Source/SimpleHTTP/Extensions/Response/ResponseExtensions.PartialStream.cs "dajuric/simple-http"))
|
||||||
|
|
||||||
|
> Note the nuget icon is from [here](https://uxwing.com/http-icon/)
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
using Tesses;
|
using System.Drawing;
|
||||||
|
using Tesses;
|
||||||
using Tesses.WebServer;
|
using Tesses.WebServer;
|
||||||
|
using Tesses.WebServer.HtmlLayout;
|
||||||
namespace Tesses.WebServer.ConsoleApp
|
namespace Tesses.WebServer.ConsoleApp
|
||||||
{
|
{
|
||||||
class JsonObj
|
class JsonObj
|
||||||
|
@ -8,10 +10,60 @@ namespace Tesses.WebServer.ConsoleApp
|
||||||
|
|
||||||
public DateTime Birthday {get;set;}=DateTime.Now;
|
public DateTime Birthday {get;set;}=DateTime.Now;
|
||||||
}
|
}
|
||||||
|
public class MyOther
|
||||||
|
{
|
||||||
|
[FormNewLine]
|
||||||
|
|
||||||
|
public string Hello {get;set;}="";
|
||||||
|
[FormNewLine]
|
||||||
|
|
||||||
|
public Color FavoriteColor {get;set;}=Color.Pink;
|
||||||
|
// [FormNewLine]
|
||||||
|
|
||||||
|
//public HttpFileResponseEntry[] Files {get;set;}=new HttpFileResponseEntry[0];
|
||||||
|
}
|
||||||
|
public enum TestEnum
|
||||||
|
{
|
||||||
|
Apple,
|
||||||
|
Orange,
|
||||||
|
Grape,
|
||||||
|
Banana,
|
||||||
|
Raspberry,
|
||||||
|
|
||||||
|
Blueberry,
|
||||||
|
Strawberry
|
||||||
|
}
|
||||||
|
class Test
|
||||||
|
{
|
||||||
|
[FormNewLine]
|
||||||
|
[FormText("Your Name",Placeholder="Name",Name="name")]
|
||||||
|
public string Name {get;set;}="";
|
||||||
|
[FormNewLine]
|
||||||
|
[FormText("Describe yourself",Placeholder="Description",Name="description")]
|
||||||
|
public string Description {get;set;}="";
|
||||||
|
[FormNewLine]
|
||||||
|
[FormCheckbox("Are you an adult")]
|
||||||
|
public bool Adult {get;set;}=false;
|
||||||
|
[FormNewLine]
|
||||||
|
[FormCheckbox("Email Me")]
|
||||||
|
public bool EmailMe {get;set;}=true;
|
||||||
|
|
||||||
|
[FormNewLine]
|
||||||
|
[FormRadio("fruit")]
|
||||||
|
public TestEnum Fruit {get;set;}=TestEnum.Raspberry;
|
||||||
|
|
||||||
|
[FormNewLine]
|
||||||
|
[FormFieldSet]
|
||||||
|
public MyOther MyOther {get;set;}=new MyOther();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
class MainClass
|
class MainClass
|
||||||
{
|
{
|
||||||
public static void Main(string[] args)
|
public static void Main(string[] args)
|
||||||
{
|
{
|
||||||
|
|
||||||
TestObject some_object = new TestObject();
|
TestObject some_object = new TestObject();
|
||||||
RouteServer rserver = new RouteServer();
|
RouteServer rserver = new RouteServer();
|
||||||
rserver.Add("/", async(ctx) => {
|
rserver.Add("/", async(ctx) => {
|
||||||
|
@ -20,6 +72,43 @@ namespace Tesses.WebServer.ConsoleApp
|
||||||
rserver.Add("/page", async(ctx) => {
|
rserver.Add("/page", async(ctx) => {
|
||||||
await ctx.SendTextAsync("Demetria Devonne Lovato 8/20/1992");
|
await ctx.SendTextAsync("Demetria Devonne Lovato 8/20/1992");
|
||||||
});
|
});
|
||||||
|
rserver.Add("/john",async(ctx)=>{
|
||||||
|
Test other = new Test();
|
||||||
|
ctx.ParseSmartForm(other);
|
||||||
|
|
||||||
|
await ctx.SendJsonAsync(other);
|
||||||
|
},"POST");
|
||||||
|
rserver.Add("/html_ex",async(ctx)=>{await ctx.SendHtmlAsync(H.Html(
|
||||||
|
H.Head(
|
||||||
|
H.Meta().WithAttribute("charset","UTF-8"),
|
||||||
|
H.Meta().WithAttribute("name","viewport").WithAttribute("content","width=device-width, initial-scale=1.0"),
|
||||||
|
H.Title("Document")
|
||||||
|
),
|
||||||
|
H.Body(H.Form("./john",new Test(),true))
|
||||||
|
).WithAttribute("lang","en"));});
|
||||||
|
rserver.Add("/absolute_paths",(ctx)=>{
|
||||||
|
using(var sw = ctx.GetResponseStreamWriter())
|
||||||
|
{
|
||||||
|
sw.WriteLine($"Root: {ctx.GetRealRootUrl()}");
|
||||||
|
sw.WriteLine($"Current Server Root: {ctx.GetCurrentServerPath()}");
|
||||||
|
sw.WriteLine($"Demetria: {ctx.GetRealUrlRelativeToCurrentServer("/page")}");
|
||||||
|
sw.WriteLine($"Headers: {ctx.GetRealUrlRelativeToCurrentServer("/headers")}");
|
||||||
|
sw.WriteLine($"Relative To Root: {ctx.GetRealUrl("/johnconnor/")}");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
rserver.Add("/headers",(ctx)=>{
|
||||||
|
using(var sw = ctx.GetResponseStreamWriter())
|
||||||
|
{
|
||||||
|
foreach(var item in ctx.RequestHeaders)
|
||||||
|
{
|
||||||
|
foreach(var item2 in item.Value)
|
||||||
|
{
|
||||||
|
sw.WriteLine($"{item.Key}: {item2}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
rserver.Add("/jsonEndpoint",async(ctx)=>{
|
rserver.Add("/jsonEndpoint",async(ctx)=>{
|
||||||
var res=await ctx.ReadJsonAsync<JsonObj>();
|
var res=await ctx.ReadJsonAsync<JsonObj>();
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Tesses.WebServer.NetStandard\Tesses.WebServer.NetStandard.csproj" />
|
<ProjectReference Include="..\Tesses.WebServer.NetStandard\Tesses.WebServer.NetStandard.csproj" />
|
||||||
|
<ProjectReference Include="..\Tesses.WebServer.HtmlLayout\Tesses.WebServer.HtmlLayout.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
|
|
|
@ -3,6 +3,7 @@ using System.IO;
|
||||||
using System;
|
using System;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
namespace Tesses.WebServer
|
namespace Tesses.WebServer
|
||||||
{
|
{
|
||||||
|
@ -71,6 +72,17 @@ internal class SizedStream : Stream
|
||||||
}
|
}
|
||||||
public class ServerContext
|
public class ServerContext
|
||||||
{
|
{
|
||||||
|
static Mutex mtx=new Mutex();
|
||||||
|
static long _unique=0;
|
||||||
|
|
||||||
|
public static long UniqueNumber()
|
||||||
|
{
|
||||||
|
mtx.WaitOne();
|
||||||
|
long u=_unique++;
|
||||||
|
mtx.ReleaseMutex();
|
||||||
|
return u;
|
||||||
|
}
|
||||||
|
|
||||||
const string bad_chars = "<>?/\\\"*|:";
|
const string bad_chars = "<>?/\\\"*|:";
|
||||||
public static string FixFileName(string filename,bool requireAscii=false)
|
public static string FixFileName(string filename,bool requireAscii=false)
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,9 +5,11 @@ using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using HeyRed.Mime;
|
using HeyRed.Mime;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Tesses.WebServer
|
namespace Tesses.WebServer
|
||||||
{
|
{
|
||||||
|
@ -200,8 +202,7 @@ namespace Tesses.WebServer
|
||||||
|
|
||||||
}
|
}
|
||||||
ctx.ResponseHeaders.Add("Content-Length", (end - start + 1).ToString());
|
ctx.ResponseHeaders.Add("Content-Length", (end - start + 1).ToString());
|
||||||
ctx.ResponseHeaders.Add("Content-Type", contentType);
|
ctx.WithMimeType(contentType);
|
||||||
|
|
||||||
await ctx.WriteHeadersAsync();
|
await ctx.WriteHeadersAsync();
|
||||||
if (!ctx.Method.Equals("HEAD", StringComparison.Ordinal))
|
if (!ctx.Method.Equals("HEAD", StringComparison.Ordinal))
|
||||||
{
|
{
|
||||||
|
@ -537,6 +538,11 @@ namespace Tesses.WebServer
|
||||||
}
|
}
|
||||||
return files;
|
return files;
|
||||||
}
|
}
|
||||||
|
public static HttpFileResponse ParseBodyWithTempDirectory(this ServerContext request)
|
||||||
|
{
|
||||||
|
DateTime dt=DateTime.Now;
|
||||||
|
return request.ParseBodyWithTempDirectory(Path.Combine(Path.GetTempPath(),$"TWSUPLOAD_{dt.ToString("yyyyMMdd_HHmmss")}_{ServerContext.UniqueNumber()}"));
|
||||||
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Parses body of the request including form and multi-part form data, allowing multiple file with same key and storing the files in a temp directory specified by the user.
|
/// Parses body of the request including form and multi-part form data, allowing multiple file with same key and storing the files in a temp directory specified by the user.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -568,6 +574,7 @@ namespace Tesses.WebServer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public sealed class HttpFileResponseEntry
|
public sealed class HttpFileResponseEntry
|
||||||
{
|
{
|
||||||
public HttpFileResponseEntry(string path, string filename, string fieldname, string contype)
|
public HttpFileResponseEntry(string path, string filename, string fieldname, string contype)
|
||||||
|
@ -584,8 +591,10 @@ namespace Tesses.WebServer
|
||||||
public string Path {get;}
|
public string Path {get;}
|
||||||
|
|
||||||
public string FieldName {get;}
|
public string FieldName {get;}
|
||||||
|
[JsonIgnore]
|
||||||
public FileInfo FileInfo => new FileInfo(Path);
|
public FileInfo FileInfo => new FileInfo(Path);
|
||||||
|
[JsonIgnore]
|
||||||
|
public object PrivateData {get;set;}=null;
|
||||||
|
|
||||||
public Stream OpenRead()
|
public Stream OpenRead()
|
||||||
{
|
{
|
||||||
|
@ -606,10 +615,16 @@ namespace Tesses.WebServer
|
||||||
public IReadOnlyList<HttpFileResponseEntry> Files {get;}
|
public IReadOnlyList<HttpFileResponseEntry> Files {get;}
|
||||||
public string Directory {get;}
|
public string Directory {get;}
|
||||||
|
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
|
if(System.IO.Directory.Exists(Directory))
|
||||||
System.IO.Directory.Delete(Directory,true);
|
System.IO.Directory.Delete(Directory,true);
|
||||||
}
|
}
|
||||||
|
~HttpFileResponse()
|
||||||
|
{
|
||||||
|
Dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -5,14 +5,16 @@
|
||||||
<PackageId>Tesses.WebServer</PackageId>
|
<PackageId>Tesses.WebServer</PackageId>
|
||||||
<Author>Mike Nolan</Author>
|
<Author>Mike Nolan</Author>
|
||||||
<Company>Tesses</Company>
|
<Company>Tesses</Company>
|
||||||
<Version>1.0.4.2</Version>
|
<Version>1.0.4.3</Version>
|
||||||
<AssemblyVersion>1.0.4.2</AssemblyVersion>
|
<AssemblyVersion>1.0.4.3</AssemblyVersion>
|
||||||
<FileVersion>1.0.4.2</FileVersion>
|
<FileVersion>1.0.4.3</FileVersion>
|
||||||
<Description>A TCP Listener HTTP(s) Server</Description>
|
<Description>A TCP Listener HTTP(s) Server</Description>
|
||||||
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
|
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
|
||||||
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
|
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
|
||||||
<PackageTags>HTTP, WebServer, Website</PackageTags>
|
<PackageTags>HTTP, WebServer, Website</PackageTags>
|
||||||
<RepositoryUrl>https://gitlab.tesses.net/tesses50/tesses.webserver</RepositoryUrl>
|
<RepositoryUrl>https://gitea.site.tesses.net/tesses50/tesses.webserver</RepositoryUrl>
|
||||||
|
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||||
|
<PackageIcon>http-icon.png</PackageIcon>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -20,5 +22,8 @@
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||||
<PackageReference Include="Tesses.VirtualFileSystem.Base" Version="1.0.0" />
|
<PackageReference Include="Tesses.VirtualFileSystem.Base" Version="1.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="..\http-icon.png" Pack="true" PackagePath="\" />
|
||||||
|
<None Include="..\README.md" Pack="true" PackagePath="\" />
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -15,6 +15,7 @@ using System.Security.Authentication;
|
||||||
using System.Web;
|
using System.Web;
|
||||||
using Tesses.VirtualFilesystem;
|
using Tesses.VirtualFilesystem;
|
||||||
using System.Net.Mime;
|
using System.Net.Mime;
|
||||||
|
using System.Numerics;
|
||||||
|
|
||||||
namespace Tesses.WebServer
|
namespace Tesses.WebServer
|
||||||
{
|
{
|
||||||
|
@ -43,6 +44,41 @@ namespace Tesses.WebServer
|
||||||
|
|
||||||
public static class Extensions
|
public static class Extensions
|
||||||
{
|
{
|
||||||
|
public static string GetRealRootUrl(this ServerContext ctx)
|
||||||
|
{
|
||||||
|
if(ctx.RequestHeaders.TryGetFirst("X-Forwarded-Path",out var xfwp))
|
||||||
|
{
|
||||||
|
return $"{xfwp.TrimEnd('/')}/";
|
||||||
|
}
|
||||||
|
else if(ctx.RequestHeaders.TryGetFirst("X-Forwarded-Host",out var host))
|
||||||
|
{
|
||||||
|
if(!ctx.RequestHeaders.TryGetFirst("X-Forwarded-Proto",out var proto)) proto="http";
|
||||||
|
return $"{proto}://{host}/";
|
||||||
|
}
|
||||||
|
else if(ctx.RequestHeaders.TryGetFirst("Host",out var theHost))
|
||||||
|
{
|
||||||
|
return $"http://{theHost}/";
|
||||||
|
}
|
||||||
|
return $"http://{ctx.Client}/";
|
||||||
|
}
|
||||||
|
public static string GetRealUrl(this ServerContext ctx,string url)
|
||||||
|
{
|
||||||
|
return $"{ctx.GetRealRootUrl()}{url.TrimStart('/')}";
|
||||||
|
}
|
||||||
|
public static string GetCurrentServerPath(this ServerContext ctx)
|
||||||
|
{
|
||||||
|
if(ctx.UrlPath == ctx.OriginalUrlPath) return "/";
|
||||||
|
return $"{ctx.OriginalUrlPath.Remove(ctx.OriginalUrlPath.Length-ctx.UrlPath.Length).TrimEnd('/')}/";
|
||||||
|
}
|
||||||
|
public static string GetRealUrlRelativeToCurrentServer(this ServerContext ctx, string url)
|
||||||
|
{
|
||||||
|
return ctx.GetRealUrl($"{ctx.GetCurrentServerPath()}{url.TrimStart('/')}");
|
||||||
|
}
|
||||||
|
public static ServerContext WithStatusCode(this ServerContext ctx, int statusCode)
|
||||||
|
{
|
||||||
|
ctx.StatusCode = statusCode;
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
public static ServerContext WithStatusCode(this ServerContext ctx, HttpStatusCode statusCode)
|
public static ServerContext WithStatusCode(this ServerContext ctx, HttpStatusCode statusCode)
|
||||||
{
|
{
|
||||||
ctx.StatusCode = (int)statusCode;
|
ctx.StatusCode = (int)statusCode;
|
||||||
|
@ -116,7 +152,11 @@ namespace Tesses.WebServer
|
||||||
try{
|
try{
|
||||||
EventHandler<SendEventArgs> cb= (sender,e0)=>{
|
EventHandler<SendEventArgs> cb= (sender,e0)=>{
|
||||||
if(__connected)
|
if(__connected)
|
||||||
|
{
|
||||||
ctx.NetworkStream.Write($"data: {e0.Data}\n\n");
|
ctx.NetworkStream.Write($"data: {e0.Data}\n\n");
|
||||||
|
ctx.NetworkStream.Flush();
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
evt.EventReceived += cb;
|
evt.EventReceived += cb;
|
||||||
while(ctx.Connected);
|
while(ctx.Connected);
|
||||||
|
@ -483,6 +523,229 @@ namespace Tesses.WebServer
|
||||||
value = default(T2);
|
value = default(T2);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
public static void Add<T1>(this Dictionary<T1,List<string>> args,T1 key, object value)
|
||||||
|
{
|
||||||
|
args.Add(key,value.ToString());
|
||||||
|
}
|
||||||
|
public static void Add<T1>(this Dictionary<T1,List<string>> args,T1 key, int value)
|
||||||
|
{
|
||||||
|
args.Add(key,value.ToString());
|
||||||
|
}
|
||||||
|
public static void Add<T1>(this Dictionary<T1,List<string>> args,T1 key, short value)
|
||||||
|
{
|
||||||
|
args.Add(key,value.ToString());
|
||||||
|
}
|
||||||
|
public static void Add<T1>(this Dictionary<T1,List<string>> args,T1 key, long value)
|
||||||
|
{
|
||||||
|
args.Add(key,value.ToString());
|
||||||
|
}
|
||||||
|
public static void Add<T1>(this Dictionary<T1,List<string>> args,T1 key, Guid value)
|
||||||
|
{
|
||||||
|
args.Add(key,value.ToString());
|
||||||
|
}
|
||||||
|
public static void Add<T1>(this Dictionary<T1,List<string>> args,T1 key, byte value)
|
||||||
|
{
|
||||||
|
args.Add(key,value.ToString());
|
||||||
|
}
|
||||||
|
public static void Add<T1>(this Dictionary<T1,List<string>> args,T1 key, sbyte value)
|
||||||
|
{
|
||||||
|
args.Add(key,value.ToString());
|
||||||
|
}
|
||||||
|
public static void Add<T1>(this Dictionary<T1,List<string>> args,T1 key, uint value)
|
||||||
|
{
|
||||||
|
args.Add(key,value.ToString());
|
||||||
|
}
|
||||||
|
public static void Add<T1>(this Dictionary<T1,List<string>> args,T1 key, ushort value)
|
||||||
|
{
|
||||||
|
args.Add(key,value.ToString());
|
||||||
|
}
|
||||||
|
public static void Add<T1>(this Dictionary<T1,List<string>> args,T1 key, ulong value)
|
||||||
|
{
|
||||||
|
args.Add(key,value.ToString());
|
||||||
|
}
|
||||||
|
public static void Add<T1>(this Dictionary<T1,List<string>> args,T1 key, bool value)
|
||||||
|
{
|
||||||
|
args.Add(key,value ? "true" : "false");
|
||||||
|
}
|
||||||
|
public static void Add<T1>(this Dictionary<T1,List<string>> args,T1 key, float value)
|
||||||
|
{
|
||||||
|
args.Add(key,value.ToString());
|
||||||
|
}
|
||||||
|
public static void Add<T1>(this Dictionary<T1,List<string>> args,T1 key, double value)
|
||||||
|
{
|
||||||
|
args.Add(key,value.ToString());
|
||||||
|
}
|
||||||
|
public static void Add<T1>(this Dictionary<T1,List<string>> args,T1 key, decimal value)
|
||||||
|
{
|
||||||
|
args.Add(key,value.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool TryGetFirstInt64<T1>(this Dictionary<T1,List<string>> args,T1 key, out long value)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(args.TryGetFirst(key,out var str))
|
||||||
|
{
|
||||||
|
bool res= long.TryParse(str,out var val);
|
||||||
|
value = val;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
value=0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
public static bool TryGetFirstInt32<T1>(this Dictionary<T1,List<string>> args,T1 key, out int value)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(args.TryGetFirst(key,out var str))
|
||||||
|
{
|
||||||
|
bool res= int.TryParse(str,out var val);
|
||||||
|
value = val;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
value=0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
public static bool TryGetFirstInt16<T1>(this Dictionary<T1,List<string>> args,T1 key, out short value)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(args.TryGetFirst(key,out var str))
|
||||||
|
{
|
||||||
|
bool res= short.TryParse(str,out var val);
|
||||||
|
value = val;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
value=0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
public static bool TryGetFirstInt8<T1>(this Dictionary<T1,List<string>> args,T1 key, out sbyte value)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(args.TryGetFirst(key,out var str))
|
||||||
|
{
|
||||||
|
bool res= sbyte.TryParse(str,out var val);
|
||||||
|
value = val;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
value=0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
public static bool GetFirstBoolean<T1>(this Dictionary<T1,List<string>> args,T1 key)
|
||||||
|
{
|
||||||
|
if(args.TryGetFirst(key,out var value))
|
||||||
|
{
|
||||||
|
value=value.ToLower();
|
||||||
|
if(value == "off" || value == "no" || value == "false" || value == "0") return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
public static bool TryGetFirstGuid<T1>(this Dictionary<T1,List<string>> args,T1 key, out Guid value)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(args.TryGetFirst(key,out var str))
|
||||||
|
{
|
||||||
|
bool res= Guid.TryParse(str,out var val);
|
||||||
|
value = val;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
value=Guid.Empty;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
public static bool TryGetFirstUInt8<T1>(this Dictionary<T1,List<string>> args,T1 key, out byte value)
|
||||||
|
{
|
||||||
|
if(args.TryGetFirst(key,out var str))
|
||||||
|
{
|
||||||
|
bool res= byte.TryParse(str,out var val);
|
||||||
|
value = val;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
value=0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
public static bool TryGetFirstUInt16<T1>(this Dictionary<T1,List<string>> args,T1 key, out ushort value)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(args.TryGetFirst(key,out var str))
|
||||||
|
{
|
||||||
|
bool res= ushort.TryParse(str,out var val);
|
||||||
|
value = val;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
value=0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
public static bool TryGetFirstUInt64<T1>(this Dictionary<T1,List<string>> args,T1 key, out ulong value)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(args.TryGetFirst(key,out var str))
|
||||||
|
{
|
||||||
|
bool res= ulong.TryParse(str,out var val);
|
||||||
|
value = val;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
value=0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
public static bool TryGetFirstUInt32<T1>(this Dictionary<T1,List<string>> args,T1 key, out uint value)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(args.TryGetFirst(key,out var str))
|
||||||
|
{
|
||||||
|
bool res= uint.TryParse(str,out var val);
|
||||||
|
value = val;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
value=0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool TryGetFirstFloat<T1>(this Dictionary<T1,List<string>> args,T1 key, out float value)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(args.TryGetFirst(key,out var str))
|
||||||
|
{
|
||||||
|
bool res= float.TryParse(str,out var val);
|
||||||
|
value = val;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
value=0.0f;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
public static bool TryGetFirstBigInteger<T1>(this Dictionary<T1,List<string>> args,T1 key, out BigInteger value)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(args.TryGetFirst(key,out var str))
|
||||||
|
{
|
||||||
|
bool res= BigInteger.TryParse(str,out var val);
|
||||||
|
value = val;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
value=0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
public static bool TryGetFirstDecimal<T1>(this Dictionary<T1,List<string>> args,T1 key, out decimal value)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(args.TryGetFirst(key,out var str))
|
||||||
|
{
|
||||||
|
bool res= decimal.TryParse(str,out var val);
|
||||||
|
value = val;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
value=0.0M;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
public static bool TryGetFirstDouble<T1>(this Dictionary<T1,List<string>> args,T1 key, out double value)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(args.TryGetFirst(key,out var str))
|
||||||
|
{
|
||||||
|
bool res= double.TryParse(str,out var val);
|
||||||
|
value = val;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
value=0.0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Add item to the Dictionary<T1,List<T2>> with specified key (will create key in dictionary if not exist)
|
/// Add item to the Dictionary<T1,List<T2>> with specified key (will create key in dictionary if not exist)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
Loading…
Reference in New Issue