Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 12 additions & 23 deletions Transmission.API.RPC/Client.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,6 @@ namespace Transmission.API.RPC
/// </summary>
public partial class Client : ITransmissionClient
{
/// <summary>
/// Provides default JSON serialization options with case-insensitive property name matching.
/// </summary>
/// <remarks>These options configure the JSON serializer to ignore case when matching property
/// names during serialization and deserialization. This can improve compatibility when working with JSON data
/// that may use different casing conventions.</remarks>
private static readonly JsonSerializerOptions _jsonOptions = new()
{
PropertyNameCaseInsensitive = true
};

/// <summary>
/// Authorization header value for requests
/// </summary>
Expand Down Expand Up @@ -192,7 +181,7 @@ public async Task<Statistic> GetSessionStatisticAsync()
{
var request = new TransmissionRequest("session-stats");
var response = await SendRequestAsync(request);
var result = response.Deserialize<Statistic>();
var result = response.Deserialize(TransmissionJsonArgumentsContext.Default.Statistic);
return result;
}

Expand All @@ -205,7 +194,7 @@ public async Task<SessionInfo> GetSessionInformationAsync()
{
var request = new TransmissionRequest("session-get");
var response = await SendRequestAsync(request);
var result = response.Deserialize<SessionInfo>();
var result = response.Deserialize(TransmissionJsonArgumentsContext.Default.SessionInfo);
return result;
}

Expand All @@ -228,16 +217,16 @@ public async Task<NewTorrentInfo> TorrentAddAsync(NewTorrent torrent)
if (response.Arguments == null)
return null;

var json = JsonSerializer.Serialize(response.Arguments);
var json = JsonSerializer.Serialize(response.Arguments, TransmissionJsonArgumentsContext.Default.DictionaryStringObject);
using var doc = JsonDocument.Parse(json);
var root = doc.RootElement;

NewTorrentInfo result = null;

if (root.TryGetProperty("torrent-duplicate", out var dupValue))
result = JsonSerializer.Deserialize<NewTorrentInfo>(dupValue.GetRawText());
result = JsonSerializer.Deserialize(dupValue.GetRawText(), TransmissionJsonArgumentsContext.Default.NewTorrentInfo);
else if (root.TryGetProperty("torrent-added", out var addValue))
result = JsonSerializer.Deserialize<NewTorrentInfo>(addValue.GetRawText());
result = JsonSerializer.Deserialize(addValue.GetRawText(), TransmissionJsonArgumentsContext.Default.NewTorrentInfo);

return result;
}
Expand Down Expand Up @@ -269,7 +258,7 @@ public async Task<TransmissionTorrents> TorrentGetAsync(string[] fields, params
var request = new TransmissionRequest("torrent-get", arguments);

var response = await SendRequestAsync(request);
var result = response.Deserialize<TransmissionTorrents>();
var result = response.Deserialize(TransmissionJsonArgumentsContext.Default.TransmissionTorrents);

return result;
}
Expand Down Expand Up @@ -454,7 +443,7 @@ public async Task<RenameTorrentInfo> TorrentRenamePathAsync(int id, string path,
var request = new TransmissionRequest("torrent-rename-path", arguments);
var response = await SendRequestAsync(request);

var result = response.Deserialize<RenameTorrentInfo>();
var result = response.Deserialize(TransmissionJsonArgumentsContext.Default.RenameTorrentInfo);

return result;
}
Expand All @@ -472,7 +461,7 @@ public async Task<bool> PortTestAsync()
var request = new TransmissionRequest("port-test");
var response = await SendRequestAsync(request);

var json = JsonSerializer.Serialize(response.Arguments);
var json = JsonSerializer.Serialize(response.Arguments, TransmissionJsonArgumentsContext.Default.DictionaryStringObject);
using var doc = JsonDocument.Parse(json);
return doc.RootElement.GetProperty("port-is-open").GetBoolean();
}
Expand All @@ -486,7 +475,7 @@ public async Task<int> BlocklistUpdateAsync()
var request = new TransmissionRequest("blocklist-update");
var response = await SendRequestAsync(request);

var json = JsonSerializer.Serialize(response.Arguments);
var json = JsonSerializer.Serialize(response.Arguments, TransmissionJsonArgumentsContext.Default.DictionaryStringObject);
using var doc = JsonDocument.Parse(json);
return doc.RootElement.GetProperty("blocklist-size").GetInt32();
}
Expand All @@ -503,7 +492,7 @@ public async Task<long> FreeSpaceAsync(string path)
var request = new TransmissionRequest("free-space", arguments);
var response = await SendRequestAsync(request);

var json = JsonSerializer.Serialize(response.Arguments);
var json = JsonSerializer.Serialize(response.Arguments, TransmissionJsonArgumentsContext.Default.DictionaryStringObject);
using var doc = JsonDocument.Parse(json);
return doc.RootElement.GetProperty("size-bytes").GetInt64();
}
Expand Down Expand Up @@ -547,14 +536,14 @@ private async Task<TransmissionResponse> SendRequestAsync(TransmissionRequest re
if (_needAuthorization)
httpRequest.Headers.Add("Authorization", _authorization);

httpRequest.Content = new StringContent(request.ToJson(), Encoding.UTF8, "application/json-rpc");
httpRequest.Content = new StringContent(request.ToRpcJson(), Encoding.UTF8, "application/json-rpc");

using (var httpResponse = await _httpClient.SendAsync(httpRequest))
{
if (httpResponse.IsSuccessStatusCode)
{
var responseString = await httpResponse.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize<TransmissionResponse>(responseString, _jsonOptions);
var result = JsonSerializer.Deserialize(responseString, TransmissionJsonResponseContext.Default.TransmissionResponse);

if (result.Result != "success")
throw new Exception(result.Result);
Expand Down
17 changes: 17 additions & 0 deletions Transmission.API.RPC/Common/CommunicateBase.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
using System.Collections.Generic;
using System;
using System.Diagnostics.CodeAnalysis;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.Json.Serialization.Metadata;

namespace Transmission.API.RPC.Common
{
Expand Down Expand Up @@ -30,6 +33,8 @@ public abstract class CommunicateBase
/// Convert to JSON string
/// </summary>
/// <returns></returns>
[RequiresUnreferencedCode("Use a source-generated JsonTypeInfo overload for trimming and Native AOT.")]
[RequiresDynamicCode("Use a source-generated JsonTypeInfo overload for Native AOT.")]
public virtual string ToJson()
{
return JsonSerializer.Serialize(this, GetType(), _indentedOptions);
Expand All @@ -39,10 +44,22 @@ public virtual string ToJson()
/// Deserialize to class
/// </summary>
/// <returns></returns>
[RequiresUnreferencedCode("Use Deserialize(JsonTypeInfo<T>) with source-generated metadata for trimming and Native AOT.")]
[RequiresDynamicCode("Use Deserialize(JsonTypeInfo<T>) with source-generated metadata for Native AOT.")]
public T Deserialize<T>()
{
var argumentsString = JsonSerializer.Serialize(Arguments);
return JsonSerializer.Deserialize<T>(argumentsString);
}

/// <summary>
/// Deserialize to class
/// </summary>
/// <returns></returns>
public T Deserialize<T>(JsonTypeInfo<T> jsonTypeInfo)
{
var argumentsString = JsonSerializer.Serialize(Arguments, TransmissionJsonArgumentsContext.Default.DictionaryStringObject);
return JsonSerializer.Deserialize(argumentsString, jsonTypeInfo);
}
}
}
35 changes: 35 additions & 0 deletions Transmission.API.RPC/Common/TransmissionJsonArgumentsContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;
using Transmission.API.RPC.Entity;

namespace Transmission.API.RPC.Common
{
[JsonSerializable(typeof(Dictionary<string, object>))]
[JsonSerializable(typeof(JsonElement))]
[JsonSerializable(typeof(object))]
[JsonSerializable(typeof(object[]))]
[JsonSerializable(typeof(string))]
[JsonSerializable(typeof(string[]))]
[JsonSerializable(typeof(int))]
[JsonSerializable(typeof(int[]))]
[JsonSerializable(typeof(long))]
[JsonSerializable(typeof(long[]))]
[JsonSerializable(typeof(bool))]
[JsonSerializable(typeof(bool[]))]
[JsonSerializable(typeof(double))]
[JsonSerializable(typeof(double[]))]
[JsonSerializable(typeof(float))]
[JsonSerializable(typeof(float[]))]
[JsonSerializable(typeof(decimal))]
[JsonSerializable(typeof(decimal[]))]
[JsonSerializable(typeof(Units))]
[JsonSerializable(typeof(NewTorrentInfo))]
[JsonSerializable(typeof(RenameTorrentInfo))]
[JsonSerializable(typeof(SessionInfo))]
[JsonSerializable(typeof(Statistic))]
[JsonSerializable(typeof(TransmissionTorrents))]
internal partial class TransmissionJsonArgumentsContext : JsonSerializerContext
{
}
}
15 changes: 15 additions & 0 deletions Transmission.API.RPC/Common/TransmissionJsonResponseContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Transmission.API.RPC.Common
{
[JsonSourceGenerationOptions(PropertyNameCaseInsensitive = true)]
[JsonSerializable(typeof(TransmissionResponse))]
[JsonSerializable(typeof(Dictionary<string, object>))]
[JsonSerializable(typeof(JsonElement))]
[JsonSerializable(typeof(object))]
internal partial class TransmissionJsonResponseContext : JsonSerializerContext
{
}
}
33 changes: 33 additions & 0 deletions Transmission.API.RPC/Common/TransmissionJsonWriteContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;
using Transmission.API.RPC.Entity;

namespace Transmission.API.RPC.Common
{
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(TransmissionRequest))]
[JsonSerializable(typeof(TransmissionResponse))]
[JsonSerializable(typeof(Dictionary<string, object>))]
[JsonSerializable(typeof(JsonElement))]
[JsonSerializable(typeof(object))]
[JsonSerializable(typeof(object[]))]
[JsonSerializable(typeof(string))]
[JsonSerializable(typeof(string[]))]
[JsonSerializable(typeof(int))]
[JsonSerializable(typeof(int[]))]
[JsonSerializable(typeof(long))]
[JsonSerializable(typeof(long[]))]
[JsonSerializable(typeof(bool))]
[JsonSerializable(typeof(bool[]))]
[JsonSerializable(typeof(double))]
[JsonSerializable(typeof(double[]))]
[JsonSerializable(typeof(float))]
[JsonSerializable(typeof(float[]))]
[JsonSerializable(typeof(decimal))]
[JsonSerializable(typeof(decimal[]))]
[JsonSerializable(typeof(Units))]
internal partial class TransmissionJsonWriteContext : JsonSerializerContext
{
}
}
10 changes: 8 additions & 2 deletions Transmission.API.RPC/Common/TransmissionRequest.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Transmission.API.RPC.Common
Expand All @@ -18,9 +19,14 @@ public class TransmissionRequest : CommunicateBase
/// Initialize request
/// </summary>
/// <param name="method">Method name</param>
public TransmissionRequest(string method)
public TransmissionRequest(string method)
{
this.Method = method;
}

internal string ToRpcJson()
{
this.Method = method;
return JsonSerializer.Serialize(this, TransmissionJsonWriteContext.Default.TransmissionRequest);
}

/// <summary>
Expand Down
1 change: 1 addition & 0 deletions Transmission.API.RPC/Transmission.API.RPC.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>

<!-- Build quality -->
<IsAotCompatible>true</IsAotCompatible>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
Expand Down