如何兼容ServiceStack v8.1.0移除Authenticate类oauth_token的变更?
解决ServiceStack v8.1.0后客户端继续使用oauth_token的C#方案
以下几种方案可以让客户端无需全面改造,继续向/authenticate端点发送oauth_token参数:
方案一:服务端全局请求过滤器映射参数
在服务端添加全局请求过滤器,自动将请求中的oauth_token参数值赋值给Authenticate DTO的AccessToken属性,无需修改客户端代码:
// 在ServiceStack AppHost配置中添加全局过滤器 public override void Configure(Container container) { GlobalRequestFilters.Add((req, res, dto) => { if (dto is Authenticate authDto) { // 自动从QueryString、POST表单、JSON请求体中提取oauth_token参数 var oauthToken = req.GetParam("oauth_token"); if (!string.IsNullOrWhiteSpace(oauthToken)) { authDto.AccessToken = oauthToken; } } }); }
方案二:客户端请求拦截器自动转换参数
如果无法修改服务端代码,可以在客户端添加请求拦截器,发送请求前自动将oauth_token替换为AccessToken参数:
处理Form表单请求
var client = new JsonServiceClient("https://your-api-domain"); client.RequestFilter += async (request) => { if (request.RequestUri.AbsolutePath.EndsWith("/authenticate", StringComparison.OrdinalIgnoreCase)) { if (request.Content is FormUrlEncodedContent formContent) { // 解析原有表单参数 var formData = await formContent.ReadAsStringAsync(); var paramDict = formData.Split('&') .Select(kv => kv.Split('=')) .ToDictionary(kv => kv[0], kv => Uri.UnescapeDataString(kv[1])); // 替换参数键名 if (paramDict.Remove("oauth_token", out var tokenValue)) { paramDict["AccessToken"] = tokenValue; request.Content = new FormUrlEncodedContent(paramDict); } } } };
处理JSON格式请求
如果客户端发送JSON请求,调整拦截器逻辑处理JSON内容:
client.RequestFilter += async (request) => { if (request.RequestUri.AbsolutePath.EndsWith("/authenticate", StringComparison.OrdinalIgnoreCase) && request.ContentType?.Contains("application/json") == true) { var jsonContent = await request.Content.ReadAsStringAsync(); var authRequest = JsonSerializer.Deserialize<Dictionary<string, object>>(jsonContent); if (authRequest.Remove("oauth_token", out var tokenValue)) { authRequest["AccessToken"] = tokenValue; var newJson = JsonSerializer.Serialize(authRequest); request.Content = new StringContent(newJson, Encoding.UTF8, "application/json"); } } };
方案三:扩展Authenticate DTO(可选)
通过继承原Authenticate类并添加oauth_token属性,利用序列化回调自动映射到AccessToken:
public class LegacyAuthenticate : Authenticate { public string oauth_token { get; set; } public override void OnDeserialized() { base.OnDeserialized(); if (!string.IsNullOrWhiteSpace(oauth_token)) { AccessToken = oauth_token; } } }
之后需要将自定义DTO注册为/authenticate端点的请求类型,替换默认的Authenticate DTO:
public override void Configure(Container container) { Routes.Add<LegacyAuthenticate>("/authenticate"); }
内容的提问来源于stack exchange,提问作者MADCookie
相关产品推荐
相关产品推荐

