.NET 4.5中如何将GraphQL字符串解析为对象?
.NET Framework 4.5 下解析GraphQL字符串到自定义类的解决方案
一、使用兼容的GraphQL解析库
.NET Framework 4.5可选用GraphQL.NET 2.4.0版本(该版本明确支持.NET Framework 4.5),借助它的AST(抽象语法树)解析能力完成转换:
安装对应NuGet包:
Install-Package GraphQL -Version 2.4.0解析GraphQL字符串并映射到自定义类的示例代码:
using GraphQL; using GraphQL.Language.AST; using Newtonsoft.Json.Linq; public static class GraphQLParserHelper { public static GraphQL ParseToCustomGraphQL(string graphqlStr) { var document = Parser.Parse(graphqlStr); var graphQL = new GraphQL { Query = new List<Field>() }; var operation = document.Operations.FirstOrDefault() as Operation; if (operation != null) { foreach (var selection in operation.Selections) { if (selection is Field fieldAst) { graphQL.Query.Add(MapFieldAstToCustomField(fieldAst)); } } } return graphQL; } private static Field MapFieldAstToCustomField(GraphQL.Language.AST.Field fieldAst) { var customField = new Field { Name = fieldAst.Name, Alias = fieldAst.Alias?.Name ?? "", Fields = new List<Field>() }; if (fieldAst.Arguments != null && fieldAst.Arguments.Any()) { var argsObj = new JObject(); foreach (var arg in fieldAst.Arguments) { argsObj[arg.Name] = GetArgumentValue(arg.Value); } customField.Attributes = argsObj; } foreach (var selection in fieldAst.Selections) { if (selection is Field nestedFieldAst) { customField.Fields.Add(MapFieldAstToCustomField(nestedFieldAst)); } } return customField; } private static JToken GetArgumentValue(IValue value) { if (value is StringValue strVal) return JToken.FromObject(strVal.Value); if (value is IntValue intVal) return JToken.FromObject(intVal.Value); if (value is BooleanValue boolVal) return JToken.FromObject(boolVal.Value); return JValue.CreateNull(); } } // 你的自定义类 public class GraphQL { public List<Field> Query { get; set; } } public class Field { public string Name { get; set; } public string Alias { get; set; } = ""; public JObject Attributes { get; set; } public List<Field> Fields { get; set; } }
二、纯自定义解析(无第三方库)
如果不想依赖第三方库,可通过正则配合递归实现基础解析(仅适合简单场景,复杂语法如片段、变量等需额外扩展):
using System.Text.RegularExpressions; using Newtonsoft.Json.Linq; public static class CustomGraphQLParser { private static readonly Regex FieldRegex = new Regex(@"([\w]+)(?:\:([\w]+))?\s*(?:\((.*?)\))?\s*(?:\{(.*?)\})?", RegexOptions.Singleline | RegexOptions.Compiled); public static GraphQL Parse(string graphqlStr) { var cleanStr = Regex.Replace(graphqlStr, @"\s+", " ").Trim(); var match = FieldRegex.Match(cleanStr); var graphQL = new GraphQL { Query = new List<Field>() }; while (match.Success) { var field = new Field { Alias = match.Groups[1].Value, Name = match.Groups[2].Success ? match.Groups[2].Value : match.Groups[1].Value, Fields = new List<Field>() }; var argsStr = match.Groups[3].Value; if (!string.IsNullOrEmpty(argsStr)) { var argsObj = new JObject(); var args = argsStr.Split(','); foreach (var arg in args) { var parts = arg.Split(':', StringSplitOptions.RemoveEmptyEntries); if (parts.Length == 2) { argsObj[parts[0].Trim()] = parts[1].Trim().Trim('"'); } } field.Attributes = argsObj; } var nestedFieldsStr = match.Groups[4].Value; if (!string.IsNullOrEmpty(nestedFieldsStr)) { var nestedGraphQL = Parse($"{{{nestedFieldsStr}}}"); field.Fields.AddRange(nestedGraphQL.Query); } graphQL.Query.Add(field); match = match.NextMatch(); } return graphQL; } }
注意:纯自定义解析仅支持基础的字段、别名、参数和嵌套结构,对于GraphQL的复杂语法(如变量、片段、指令等)处理能力有限,建议优先使用第一种方案。
内容的提问来源于stack exchange,提问作者Divyesh Chaudhari
相关产品推荐
相关产品推荐

