为什么反序列化返回null?

huangapple go评论83阅读模式
英文:

Why does the deserialization return null?

问题

我正在尝试在 C# .NET 7 中反序列化来自 SteamAPI 的响应。我使用 RestSharp 发送 REST 请求并将内容保存为文件。然后,我加载文件并希望使用 LINQ 进行反序列化以进行搜索。但是使用各种 JsonSerializerOptions 选项都无法正常工作。SteamAppList.AppList 始终为 null。

对于数据模型,我使用了 Json2Csharp 和 JetBrains Rider。

这是我的模型 (SteamAppList.cs):

[Serializable]
public class SteamAppList
{
    [JsonPropertyName("applist")]
    public Applist Applist;
}
[Serializable]
public class Applist
{
    [JsonPropertyName("apps")]
    public List<App> Apps;
}
[Serializable]
public class App
{
    [JsonPropertyName("appid")]
    public int Appid;

    [JsonPropertyName("name")]
    public string Name;
}

以及用于请求和反序列化的 SteamApps.cs:

public class SteamApps
{
    private readonly CancellationToken cancellationToken;

    private async Task<RestResponse> GetSteamApps()
    {
        var client = new RestClient();
        var request = new RestRequest("https://api.steampowered.com/ISteamApps/GetAppList/v2/");
        request.AddHeader("Accept", "*/*");
        request.AddHeader("User-Agent", "Major GSM");
        var response = await client.GetAsync(request, cancellationToken);
        return response;
    }

    public bool RetrieveAndSaveSteamApps()
    {
        var path = FileModule.GetDirectoryPath(MajorGsmLibrary.ApplicationDirectory.Games);
        var fileName = "steam.library.json";
        RestResponse restResponse = GetSteamApps().Result;
        
        try
        {
            File.WriteAllText(Path.Combine(path, fileName), restResponse.Content);
        }
        catch (IOException exception)
        {
            LogModule.WriteError("Could not write steam library file!", exception);
            return false;
        }
        catch (ArgumentNullException exception)
        {
            LogModule.WriteError("Missing data for steam library file", exception);
            return false;
        }
        return true;
    }

    public static string CheckGameAgainstSteamLibraryWithAppId(string appId)
    {
        var path = FileModule.GetDirectoryPath(MajorGsmLibrary.ApplicationDirectory.Games);
        var fileName = "steam.library.json";
        var fileData =
            File.ReadAllText(Path.Combine(path, fileName));
        SteamAppList? steamAppList = JsonSerializer.Deserialize<SteamAppList>(fileData, new JsonSerializerOptions { MaxDepth = 64, Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping });

        if (steamAppList!.Applist != null)
        {
            var app = steamAppList.Applist.Apps.SingleOrDefault(x => x.Appid.ToString() == appId);
            if (app != null) return app.Name;
        }

        return "Unknown";
    }
}

我从一个 GTK# 应用程序中调用 SteamApps 类:

foreach (var game in Games)
{
    var appName = SteamApps.CheckGameAgainstSteamLibraryWithAppId(game.AppId);
    if (appName == "Unknown") return;
    game.FoundInSteamLibrary = true;
    game.SteamLibraryName = appName;
}

我收到的 JSON 如下所示:

{
    "applist": {
        "apps": [
            {
                "appid": 1941401,
                "name": ""
            },
            {
                "appid": 1897482,
                "name": ""
            },
            {
                "appid": 2112761,
                "name": ""
            },
            {
                "appid": 1470110,
                "name": "Who's Your Daddy Playtest"
            },
            {
                "appid": 2340170,
                "name": "Melon Knight"
            },
            {
                "appid": 1793090,
                "name": "Blockbuster Inc."
            }
        ]
    }
}

希望这对你有所帮助!

英文:

I am trying to deserialize the response from the SteamAPI in C# .NET 7. I make the REST request via RestSharp and save the content as a file. Later I load the file and want to deserialize it to search it with LINQ. But with various options of JsonSerializerOptions it does not work. The SteamAppList.AppList is always null.

For the data model I used Json2Csharp and Jetbrains Rider.

I tried different JsonSerializerOptions and did debugging via vscode and Jetbrains Rider.

Here is my model (SteamAppList.cs):

[Serializable]
    public class SteamAppList
    {
        [JsonPropertyName(&quot;applist&quot;)]
        public Applist Applist;
    }
    [Serializable]
    public class Applist
    {
        [JsonPropertyName(&quot;apps&quot;)]
        public List&lt;App&gt; Apps;
    }
    [Serializable]
    public class App
    {
        [JsonPropertyName(&quot;appid&quot;)]
        public int Appid;

        [JsonPropertyName(&quot;name&quot;)]
        public string Name;
    }

And my SteamApps.cs for the request and the deserialisation:

public class SteamApps
    {
        private readonly CancellationToken cancellationToken;

        private async Task&lt;RestResponse&gt; GetSteamApps()
        {
            var client = new RestClient();
            var request = new RestRequest(&quot;https://api.steampowered.com/ISteamApps/GetAppList/v2/&quot;);
            request.AddHeader(&quot;Accept&quot;, &quot;*/*&quot;);
            request.AddHeader(&quot;User-Agent&quot;, &quot;Major GSM&quot;);
            var response = await client.GetAsync(request, cancellationToken);
            return response;
        }

        public bool RetireveAndSaveSteamApps()
        {
            var path = FileModule.GetDirectoryPath(MajorGsmLibrary.ApplicationDirectory.Games);
            var fileName = &quot;steam.library.json&quot;;
            RestResponse restResponse = GetSteamApps().Result;
            
            try
            {
                File.WriteAllText(Path.Combine(path, fileName), restResponse.Content);
            }
            catch (IOException exception)
            {
                LogModule.WriteError(&quot;Could not write steam libarary file!&quot;, exception);
                return false;
            }
            catch (ArgumentNullException exception)
            {
                LogModule.WriteError(&quot;Missing data for steam library file&quot;, exception);
                return false;
            }
            return true;
        }

        public static string CheckGameAgainstSteamLibraryWithAppId(string appId)
        {
            var path = FileModule.GetDirectoryPath(MajorGsmLibrary.ApplicationDirectory.Games);
            var fileName = &quot;steam.library.json&quot;;
            var fileData =
                File.ReadAllText(Path.Combine(path, fileName));
            SteamAppList? steamAppList = JsonSerializer.Deserialize&lt;SteamAppList&gt;(fileData, new JsonSerializerOptions { MaxDepth = 64, Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping });

            if (steamAppList!.Applist != null)
            {
                var app = steamAppList.Applist.Apps.SingleOrDefault(x =&gt; x.Appid.ToString() == appId);
                if (app != null) return app.Name;
            }

            return &quot;Unknown&quot;;
        }
    }

Im calling the SteamApps-class from a GTK# Application:

foreach (var game in Games)
            {
                var appName = SteamApps.CheckGameAgainstSteamLibraryWithAppId(game.AppId);
                if (appName == &quot;Unknown&quot;) return;
                game.FoundInSteamLibrary = true;
                game.SteamLibraryName = appName;
            }

The JSON I'm receiving looks like this:

{
&quot;applist&quot;: {
    &quot;apps&quot;: [
        {
            &quot;appid&quot;: 1941401,
            &quot;name&quot;: &quot;&quot;
        },
        {
            &quot;appid&quot;: 1897482,
            &quot;name&quot;: &quot;&quot;
        },
        {
            &quot;appid&quot;: 2112761,
            &quot;name&quot;: &quot;&quot;
        },
        {
            &quot;appid&quot;: 1470110,
            &quot;name&quot;: &quot;Who&#39;s Your Daddy Playtest&quot;
        },
        {
            &quot;appid&quot;: 2340170,
            &quot;name&quot;: &quot;Melon Knight&quot;
        },
        {
            &quot;appid&quot;: 1793090,
            &quot;name&quot;: &quot;Blockbuster Inc.&quot;
        }
    ]
}

}

答案1

得分: 1

你的反序列化失败是因为你的模型有字段,默认情况下会被忽略。你有两个选项:

  • 在你的模型中将字段更改为属性

或者

  • 使用 [JsonInclude] 注解字段

英文:

Your deserialization fails because your models have fields and fields by default are ignored. You have two options:

  • change fields to properties in your models

or

  • annotate fields with [JsonInclude]

答案2

得分: 1

我对模型做了更多尝试,找到了一个解决方案。
以下是匹配的模型:

public class SteamAppList
{
    [JsonPropertyName("applist")]
    public Applist Applist { get; set; }
}

public class Applist
{
    [JsonPropertyName("apps")]
    public App[] Apps { get; set; }
}

public class App
{
    [JsonPropertyName("appid")]
    public long Appid { get; set; }

    [JsonPropertyName("name")]
    public string? Name { get; set; }
}
英文:

I played around with the model a bit more and found a solution.
Here is the matching model:

public class SteamAppList
{
    [JsonPropertyName(&quot;applist&quot;)]
    public Applist Applist { get; set; }
}

public class Applist
{
    [JsonPropertyName(&quot;apps&quot;)]
    public App[] Apps { get; set; }
}

public class App
{
    [JsonPropertyName(&quot;appid&quot;)]
    public long Appid { get; set; }

    [JsonPropertyName(&quot;name&quot;)]
    public string? Name { get; set; }
}

huangapple
  • 本文由 发表于 2023年6月13日 07:05:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/76460797.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定