2
0
mirror of https://github.com/esiur/esiur-dotnet.git synced 2026-06-13 22:48:42 +00:00
This commit is contained in:
2026-06-08 16:15:57 +03:00
parent 8143da2eee
commit 340798a5fa
111 changed files with 20647 additions and 27 deletions
+194
View File
@@ -0,0 +1,194 @@
#nullable enable
using System;
using System.Collections.Generic;
namespace Esiur.Tests.RPC.JsonServer
{
// ====================== Enums ======================
public enum Currency
{
IQD,
CNH,
USD,
EUR,
JPY,
GBP
}
public enum DocType
{
Quote,
Order,
Invoice,
CreditNote
}
public enum PaymentMethod
{
Cash,
Card,
Wire,
Crypto,
Other
}
public enum LineType
{
Product,
Service,
Discount,
Shipping
}
// Variant.Kind
public enum Kind
{
Null,
Bool,
Int64,
UInt64,
Double,
Decimal,
String,
Bytes,
DateTime,
Guid
}
// ====================== Variant & Entry helpers ======================
public sealed class Variant
{
public Kind Tag { get; set; }
public bool? Bool { get; set; }
public long? I64 { get; set; }
public ulong? U64 { get; set; }
public double? F64 { get; set; }
public string? Str { get; set; }
public byte[]? Bytes { get; set; }
public DateTime? Dt { get; set; }
public byte[]? Guid { get; set; }
}
public sealed class MetaEntry
{
public string Key { get; set; } = string.Empty;
public Variant Value { get; set; } = new Variant();
}
public sealed class ExtEntry
{
public string Key { get; set; } = string.Empty;
public Variant Value { get; set; } = new Variant();
}
// ====================== Party & Address ======================
public sealed class Address
{
public string Line1 { get; set; } = string.Empty;
public string? Line2 { get; set; }
public string City { get; set; } = string.Empty;
public string Region { get; set; } = string.Empty;
public string Country { get; set; } = string.Empty;
public string? PostalCode { get; set; }
}
public sealed class Party
{
public ulong Id { get; set; }
public string Name { get; set; } = string.Empty;
public string? TaxId { get; set; }
public string? Email { get; set; }
public string? Phone { get; set; }
public Address? Address { get; set; }
public string? PreferredLanguage { get; set; }
}
// ====================== DocumentHeader ======================
public sealed class DocumentHeader
{
// Guid serialized as bytes
public byte[] DocId { get; set; } = Array.Empty<byte>();
public DocType Type { get; set; }
public int Version { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime? UpdatedAt { get; set; }
public Currency Currency { get; set; }
public string? Notes { get; set; }
// corresponds to Dictionary<string, Variant>
public Dictionary<string, Variant> Meta { get; set; } = new();
}
// ====================== LineItem, Payment, Attachment ======================
public sealed class LineItem
{
public int LineNo { get; set; }
public LineType Type { get; set; }
public string SKU { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
public double Qty { get; set; }
public string QtyUnit { get; set; } = string.Empty;
public double UnitPrice { get; set; }
public double? VatRate { get; set; }
public double? Discount { get; set; }
// Dictionary<string, Variant>
public Dictionary<string, Variant> Ext { get; set; } = new();
}
public sealed class Payment
{
public PaymentMethod Method { get; set; }
public double Amount { get; set; }
public string? Reference { get; set; }
public DateTime Timestamp { get; set; }
public double? Fee { get; set; }
public Currency Currency { get; set; }
}
public sealed class Attachment
{
public string Name { get; set; } = string.Empty;
public string MimeType { get; set; } = string.Empty;
public byte[] Data { get; set; } = Array.Empty<byte>();
}
// ====================== Top-level BusinessDocument ======================
public sealed class BusinessDocument
{
public DocumentHeader Header { get; set; } = new DocumentHeader();
public Party Seller { get; set; } = new Party();
public Party Buyer { get; set; } = new Party();
public LineItem[] Items { get; set; } = Array.Empty<LineItem>();
public Payment[] Payments { get; set; } = Array.Empty<Payment>();
public Attachment[] Attachments { get; set; } = Array.Empty<Attachment>();
public int[] RiskScores { get; set; } = Array.Empty<int>();
}
}
@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.8" />
</ItemGroup>
</Project>
@@ -0,0 +1,6 @@
@RPC.JSON_HostAddress = http://localhost:5100
GET {{RPC.JSON_HostAddress}}/weatherforecast/
Accept: application/json
###
+40
View File
@@ -0,0 +1,40 @@
// Echo.JsonRpc/Program.cs (Server)
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Hosting;
using Esiur.Tests.RPC.JsonServer;
using System.Text.Json;
using System.Text.Json.Serialization;
var app = WebApplication.Create(args);
var json = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, DefaultIgnoreCondition = JsonIgnoreCondition.Never };
app.MapPost("/rpc", async (HttpRequest req) =>
{
var rpc = await JsonSerializer.DeserializeAsync<JsonRpcReq>(req.Body, json);
object? result = null;
//switch (rpc!.Method)
//{
// case "EchoBytes": result = rpc.Params.Deserialize<byte[]>(json); break;
// case "EchoDocuments": result = rpc.Params!.Value.GetProperty("docs").Deserialize<BusinessDocument[]>(json); break;
// case "EchoIntArray": result = rpc.Params!.Value.GetProperty("array").Deserialize<int[]>(json); break;
// case "EchoStringArray": result = rpc.Params!.Value.GetProperty("array").Deserialize<string[]>(json); break;
// case "EchoMap": result = rpc.Params!.Value.GetProperty("map").Deserialize<Dictionary<string, BusinessDocument>>(json); break;
// case "EchoEnumArray":
// var arr = rpc.Params!.Value.GetProperty("docTypes").Deserialize<DocType[]>(json)!;
// result = (arr.Length == 0) ? DocType.Quote : arr[^1];
// break;
// default: return Results.BadRequest();
//}
return Results.Json(new JsonRpcRes { Jsonrpc = "2.0", Id = rpc.Id, Result = rpc.Params }, json);
});
app.Urls.Add("http://0.0.0.0:5100");
app.Run();
record JsonRpcReq(string Jsonrpc, string Method, object Params, string Id);
record JsonRpcRes { public string Jsonrpc { get; init; } = "2.0"; public string Id { get; init; } = "1"; public object? Result { get; init; } }
@@ -0,0 +1,23 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"applicationUrl": "http://localhost:5126",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"applicationUrl": "https://localhost:7193;http://localhost:5126",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}
+9
View File
@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}