XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFEExtension.NetCore.ServerInteractive

[DLL] Server interaction extension, including user identity verification and querying in conjunction with AutoConfig

公开
关注 0 Fork 0 Star 0
返回提交历史

XFEstudio/XFEExtension.NetCore.ServerInteractive

feat: add wildcard path matching support for client RequestAttribute/ResponseAttribute

When using ClientRequester.Request() with paths like "v1/myTest", if no exact match is found, falls back to wildcard pattern matching (e.g., "v1/*"). The Route property is set to the actual requested path, allowing service methods to inspect which specific path was requested via the Route property. Agent-Logs-Url: https://github.com/XFEstudio/XFEExtension.NetCore.ServerInteractive/sessions/e33340ee-5cfe-40f9-8936-8ef6663ccd97 Co-authored-by: XFEstudio <132526994+XFEstudio@users.noreply.github.com>

654509e
copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
提交于

代码差异

2 个文件 +80 -6
Modified XFEExtension.NetCore.ServerInteractive/Utilities/Requester/XFEClientRequester.cs +57 -0
@@ -20,6 +20,7 @@ public abstract class XFEClientRequester : IRequesterBase
20 20 private readonly JsonSerializerOptions _jsonSerializerOptions = new();
21 21 internal Dictionary<string, Func<IRequestService>> RequestServiceDictionary = [];
22 22 internal Dictionary<string, Func<IStandardRequestService>> StandardRequestServiceDictionary = [];
23 internal List<(string Pattern, Func<IStandardRequestService> Factory)> WildcardStandardRequestServiceList = [];
23 24 internal Dictionary<string, StandardClientInstanceRequest> StandardClientInstanceRequestDictionary = [];
24 25 /// <inheritdoc/>
25 26 public string RequestAddress { get; set; } = string.Empty;
@@ -100,6 +101,39 @@ public abstract class XFEClientRequester : IRequesterBase
100 101 result.Message = response;
101 102 }
102 103 }
104 else if (TryMatchWildcardStandardService(serviceName, out var wildcardFactory, out var matchedPattern))
105 {
106 var xFEService = wildcardFactory!();
107 xFEService.XFEClientRequester = this;
108 xFEService.DeviceInfo = DeviceInfo;
109 xFEService.Parameters = parameters;
110 // 通配符匹配:Route设为实际请求路径,以便服务方法中可通过Route属性查看具体路径
111 xFEService.Route = serviceName;
112 if (!xFEService.RequestPoints.TryGetValue(matchedPattern!, out var requestHandler))
113 throw new XFERequesterException($"未找到'{serviceName}'(通配符模式'{matchedPattern}')对应的请求处理方法([Request]标记的方法)");
114 var (response, code) = await InteractiveHelper.GetServerResponse(RequestAddress + $"/{serviceName}", requestHandler(), _jsonSerializerOptions);
115 result.StatusCode = code;
116 if (code == HttpStatusCode.OK)
117 {
118 xFEService.Response = response;
119 xFEService.UnescapedResponse = Regex.Unescape(response);
120 if (xFEService.ResponsePoints.TryGetValue(matchedPattern!, out var responseHandler))
121 {
122 result.Result = responseHandler();
123 }
124 else
125 {
126 result.Result = response;
127 }
128 MessageReceived?.Invoke(this, new ServerInteractiveEventArgsImpl("Success", code));
129 result.Message = "Success";
130 }
131 else
132 {
133 MessageReceived?.Invoke(this, new ServerInteractiveEventArgsImpl(response, code));
134 result.Message = response;
135 }
136 }
103 137 else if (StandardClientInstanceRequestDictionary.TryGetValue(serviceName, out var instance))
104 138 {
105 139 var (response, code) = await InteractiveHelper.GetServerResponse(RequestAddress + $"/{serviceName}", instance.ConstructBody(Session, DeviceInfo, parameters), _jsonSerializerOptions);
@@ -127,4 +161,27 @@ public abstract class XFEClientRequester : IRequesterBase
127 161 return result;
128 162 }
129 163 }
164
165 /// <summary>
166 /// 尝试通过通配符模式匹配标准请求服务
167 /// </summary>
168 /// <param name="serviceName">请求路径</param>
169 /// <param name="factory">匹配到的服务工厂</param>
170 /// <param name="matchedPattern">匹配到的通配符模式</param>
171 /// <returns>是否匹配成功</returns>
172 private bool TryMatchWildcardStandardService(string serviceName, out Func<IStandardRequestService>? factory, out string? matchedPattern)
173 {
174 foreach (var (pattern, serviceFactory) in WildcardStandardRequestServiceList)
175 {
176 if (RouteMatchHelper.MatchWildcardRoute(pattern, serviceName))
177 {
178 factory = serviceFactory;
179 matchedPattern = pattern;
180 return true;
181 }
182 }
183 factory = null;
184 matchedPattern = null;
185 return false;
186 }
130 187 }
Modified XFEExtension.NetCore.ServerInteractive/Utilities/Requester/XFEClientRequesterBuilder.cs +23 -6
@@ -3,6 +3,7 @@ using XFEExtension.NetCore.ServerInteractive.Implements;
3 3 using XFEExtension.NetCore.ServerInteractive.Interfaces.Requester;
4 4 using XFEExtension.NetCore.ServerInteractive.Models.RequesterModels;
5 5 using XFEExtension.NetCore.ServerInteractive.Options;
6 using XFEExtension.NetCore.ServerInteractive.Utilities.Helpers;
6 7
7 8 namespace XFEExtension.NetCore.ServerInteractive.Utilities.Requester;
8 9
@@ -15,6 +16,7 @@ public abstract class XFEClientRequesterBuilder : XFEBuilderBase<XFEClientReques
15 16 private readonly XFEClientRequester _xFEClientRequester = new XFEClientRequesterImpl();
16 17 private readonly Dictionary<string, Func<IRequestService>> _requestServiceDictionary = [];
17 18 private readonly Dictionary<string, Func<IStandardRequestService>> _standardRequestServiceDictionary = [];
19 private readonly List<(string Pattern, Func<IStandardRequestService> Factory)> _wildcardStandardRequestServiceList = [];
18 20 private readonly Dictionary<string, StandardClientInstanceRequest> _standardClientInstanceRequestDictionary = [];
19 21 /// <summary>
20 22 /// 创建构建器
@@ -63,15 +65,29 @@ public abstract class XFEClientRequesterBuilder : XFEBuilderBase<XFEClientReques
63 65 if (routeKeys.Count == 0)
64 66 throw new InvalidOperationException($"类型 {typeof(T).Name} 的 RequestPoints/ResponsePoints/RequestRouteMap 为空,请确保已使用[Request]或[Response]标记方法");
65 67
66 // 为每个路径/名称注册服务工厂
68 // 为每个路径/名称注册服务工厂(通配符路径注册到通配符列表,其余注册到标准字典)
67 69 foreach (var key in routeKeys)
68 70 {
69 _standardRequestServiceDictionary.Add(key, () =>
71 if (RouteMatchHelper.IsWildcardRoute(key))
70 72 {
71 var inst = new T();
72 ApplyParameter(inst);
73 return inst;
74 });
73 if (_wildcardStandardRequestServiceList.Any(w => w.Pattern == key))
74 throw new InvalidOperationException($"通配符路由 '{key}' 重复注册");
75 _wildcardStandardRequestServiceList.Add((key, () =>
76 {
77 var inst = new T();
78 ApplyParameter(inst);
79 return inst;
80 }));
81 }
82 else
83 {
84 _standardRequestServiceDictionary.Add(key, () =>
85 {
86 var inst = new T();
87 ApplyParameter(inst);
88 return inst;
89 });
90 }
75 91 }
76 92 return this;
77 93 }
@@ -112,6 +128,7 @@ public abstract class XFEClientRequesterBuilder : XFEBuilderBase<XFEClientReques
112 128 _xFEClientRequester.DeviceInfo = options.DeviceInfo;
113 129 _xFEClientRequester.RequestServiceDictionary = _requestServiceDictionary;
114 130 _xFEClientRequester.StandardRequestServiceDictionary = _standardRequestServiceDictionary;
131 _xFEClientRequester.WildcardStandardRequestServiceList = _wildcardStandardRequestServiceList;
115 132 _xFEClientRequester.StandardClientInstanceRequestDictionary = _standardClientInstanceRequestDictionary;
116 133 return _xFEClientRequester;
117 134 }