XFEExtension.NetCore.ServerInteractive
[DLL] Server interaction extension, including user identity verification and querying in conjunction with AutoConfig
关注
0
Fork
0
Star
0
返回提交历史
Modified
XFEExtension.NetCore.ServerInteractive/Utilities/Requester/XFEClientRequester.cs
+57
-0
Modified
XFEExtension.NetCore.ServerInteractive/Utilities/Requester/XFEClientRequesterBuilder.cs
+23
-6
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
代码差异
2 个文件
+80
-6
@@ -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
}
@@ -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
}