System.Text.Json 的 PublishTrimmed 错误

Ant*_*ife 7 c# json system.text.json

我正在尝试使用参数 来发布我的 C# 代码-p:PublishTrimmed=true。它使用 System.Text.Json,并向我发出警告。/home/USER/tymaker-config-builder/Program.cs(69,33): warning IL2026: Using member 'System.Text.Json.JsonSerializer.Serialize<SerializeExtra.LetterInfo>(SerializeExtra.LetterInfo, System.Text.Json.JsonSerializerOptions?)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved. [/home/USER/tymaker-config-builder/tymaker-config-builder.csproj]

它还给了我另一个非常相似的警告:/home/tymaker-config-builder/Program.cs(69,13): Trim analysis warning IL2026: SerializeExtra.Program.Main(): Using member 'System.Text.Json.JsonSerializer.Serialize<TValue>(TValue,JsonSerializerOptions)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved. [/home/USER/tymaker-config-builder/tymaker-config-builder.csproj]

有没有办法在保持输出修剪的同时解决这个问题?我不想在我的 GitHub 上发布 ~70MB 的可执行文件。

这是我的代码:

using System.Text.Json;
using System.Text.Json.Serialization;
using System.IO;


namespace SerializeExtra
{
    
    public class LetterInfo
    {
        public string? gift { get; set; }
        public string? party { get; set; }
        public string? sender { get; set; }
        public string? address { get; set; }
    }

    public class Program
    {
        public static void Main()
        {
            
            Console.Write("Thank-you note bot JSON generator");
            Console.Write('\n');
            Console.Write("Version 1.0.0");
            Console.Write("\n\n");
            var letterInfo = new LetterInfo { };
            Console.Write("What gift are you getting?\nThis gift will be used until changed.\nIf you want to skip this, type \"skip\"\n\n");
            letterInfo.gift = Console.ReadLine();
            if (letterInfo.gift == "skip")
            {
                letterInfo.gift = null;
            }
            Console.Write("\n\n");
            Console.Write("What party are the thank-you notes for?\nThis party will be used until changed.\nIf you want to skip this, type \"skip\"\n\n");
            letterInfo.party = Console.ReadLine();
            if (letterInfo.party == "skip")
            {
                letterInfo.party = null;
            }
            Console.Write("\n\n");
            Console.Write("What is your name?\nThis sender will be used until changed.\nIf you want to skip this, type \"skip\"\n\n");
            letterInfo.sender = Console.ReadLine();
            if (letterInfo.sender == "skip")
            {
                letterInfo.sender = null;
            }
            Console.Write("\n\n");
            if (letterInfo.sender == null)
            {
                Console.Write("What do you want your closing word(s) to be? (e.g: {answer}, Joe)\nThis closing word will be used until changed.\nIf you want to skip this, type \"skip\"\n\n");
            } else
            {
                Console.Write("What do you want your closing word(s) to be? (e.g: {answer}, " + letterInfo.sender + ")\nThis closing word will be used until changed.\nIf you want to skip this, type \"skip\"\n\n");
            }
            letterInfo.address = Console.ReadLine();
            if (letterInfo.address == "skip")
            {
                letterInfo.address = null;
            }
            Console.Write("\n\n");
            
            var options = new JsonSerializerOptions { WriteIndented = true };
            string jsonString = JsonSerializer.Serialize(letterInfo, options);

            string savePath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
            File.WriteAllText(Path.Combine(savePath, "tymaker.json"), jsonString);
            Console.Write("Configuration file (tymaker.json) is saved at " + savePath + "\n\n");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Kli*_*ker 1

这篇 Microsoft 文章介绍了如何在使用 System.Text.Json 时使用源生成,这在启用修剪时是必需的。

\n

对于您的示例,您将创建一个派生自JsonSerializerContext.

\n
[JsonSourceGenerationOptions(WriteIndented = true)]\n[JsonSerializable(typeof(LetterInfo))]\ninternal partial class LetterInfoContext : JsonSerializerContext\n{\n}\n
Run Code Online (Sandbox Code Playgroud)\n

当您调用JsonSerializer.Serializeor JsonSerializer.Deserialize, pass 时,您需要在上下文中传递:

\n
string jsonString = JsonSerializer.Serialize(letterInfo, LetterInfoContext.Default.LetterInfo);\n
Run Code Online (Sandbox Code Playgroud)\n

现在,如果您尝试发布,您应该会看到它已成功,并且不会发出以下警告:

\n
\xe2\x9d\xaf dotnet publish -c release -r linux-x64 --sc ./SerializeExtra.csproj\nMSBuild version 17.8.3+195e7f5a3 for .NET\n  Determining projects to restore...\n  All projects are up-to-date for restore.\n  SerializeExtra -> /home/user/repos/temp/SerializeExtra/bin/release/net8.0/linux-x64/SerializeExtra.dll\n  SerializeExtra -> /home/user/repos/temp/SerializeExtra/bin/release/net8.0/linux-x64/publish/\n
Run Code Online (Sandbox Code Playgroud)\n