using System.Collections;
using System.Collections.Generic;
using System.Text.Json.Serialization;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization.Metadata;
using System.Security.Cryptography;
internal class MexcSubPersonalPayload
private readonly string _apiSecret;
public MexcSubPersonalPayload(string apiKey, string apiSecret)
public string Operation => "sub.personal";
[JsonPropertyName("api_key")]
public string ApiKey { get; }
[JsonPropertyName("sign")]
public string Signature => Sign(ToString());
[JsonPropertyName("req_time")]
public long RequestTime => DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
private string Sign(string payload)
if (string.IsNullOrWhiteSpace(payload))
using var md5 = MD5.Create();
var sourceBytes = Encoding.UTF8.GetBytes(payload);
var hash = md5.ComputeHash(sourceBytes);
return Convert.ToHexString(hash);
public override string ToString()
return $"api_key={HttpUtility.UrlEncode(ApiKey)}&req_time={RequestTime}&op={Operation}&api_secret={HttpUtility.UrlEncode(_apiSecret)}";
public static partial class JsonExtensions
public static Action<JsonTypeInfo> AlphabetizeProperties(Type type)
if (typeInfo.Kind != JsonTypeInfoKind.Object || !type.IsAssignableFrom(typeInfo.Type))
AlphabetizeProperties()(typeInfo);
public static Action<JsonTypeInfo> AlphabetizeProperties()
return static typeInfo =>
if (typeInfo.Kind != JsonTypeInfoKind.Object)
var properties = typeInfo.Properties.OrderBy(p => p.Name, StringComparer.Ordinal).ToList();
typeInfo.Properties.Clear();
for (int i = 0; i < properties.Count; i++)
typeInfo.Properties.Add(properties[i]);
static readonly string _apiKey = "foo";
static readonly string _apiSecret = "bar";
public static void Test()
var payload = new MexcSubPersonalPayload(_apiKey, _apiSecret);
var options = new JsonSerializerOptions
TypeInfoResolver = new DefaultJsonTypeInfoResolver
Modifiers = { JsonExtensions.AlphabetizeProperties() },
var request = JsonSerializer.Serialize(payload, options);
Console.WriteLine(request);
var keys = JsonNode.Parse(request)!.AsObject().AsDictionary().Keys;
Assert.That(keys.SequenceEqual(keys.OrderBy(n => n, StringComparer.Ordinal)));
public static partial class JsonExtensions
public static IDictionary<String, JsonNode?> AsDictionary(this JsonObject obj) => obj;
public static void Main()
Console.WriteLine("Environment version: {0} ({1}), {2}", System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription , Environment.Version, Environment.OSVersion);
Console.WriteLine("System.Text.Json version: " + typeof(JsonSerializer).Assembly.FullName);
Console.WriteLine("Failed with unhandled exception: ");