You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通用提取RestRequest的原始请求体(兼容多种构造方式)

RestSharp 通用提取请求体方案(适配JSON与表单类型)

要统一提取RestSharp请求中无论哪种方式添加的请求体,核心是利用RestRequest.Parameters集合,结合请求的Content-Type模拟RestSharp内部的序列化逻辑,生成和实际发送一致的原始请求体内容。

通用提取方法实现

以下方法覆盖了JSON(AddJsonBody/RequestBody参数)和x-www-form-urlencoded(AddParameter(GetOrPost))两种常见场景:

using RestSharp;
using RestSharp.Serializers.Json;
using System.Net;
using System.Text;

public static class RestRequestExtensions
{
    public static string GetRawRequestBody(this RestRequest request)
    {
        // 获取请求Content-Type头
        var contentTypeHeader = request.Parameters
            .FirstOrDefault(p => p.Type == ParameterType.HttpHeader 
                                && p.Name.Equals("Content-Type", StringComparison.OrdinalIgnoreCase));
        var contentType = contentTypeHeader?.Value?.ToString() ?? string.Empty;

        // 处理JSON请求体
        if (contentType.Contains("application/json", StringComparison.OrdinalIgnoreCase))
        {
            var bodyParam = request.Parameters.FirstOrDefault(p => p.Type == ParameterType.RequestBody);
            if (bodyParam == null) return string.Empty;

            // 若参数值是对象,用RestSharp默认序列化器生成JSON(和实际发送内容一致)
            if (bodyParam.Value != null && bodyParam.Value.GetType() != typeof(string))
            {
                var serializer = new SystemTextJsonSerializer();
                return serializer.Serialize(bodyParam.Value);
            }
            return bodyParam.Value?.ToString() ?? string.Empty;
        }

        // 处理x-www-form-urlencoded表单请求体
        if (contentType.Contains("application/x-www-form-urlencoded", StringComparison.OrdinalIgnoreCase))
        {
            var formParams = request.Parameters
                .Where(p => p.Type == ParameterType.GetOrPost)
                .ToList();

            var formBuilder = new StringBuilder();
            foreach (var param in formParams)
            {
                if (formBuilder.Length > 0) formBuilder.Append('&');
                // 用WebUtility做URL编码,和RestSharp内部处理逻辑对齐
                var encodedKey = WebUtility.UrlEncode(param.Name);
                var encodedValue = WebUtility.UrlEncode(param.Value?.ToString() ?? string.Empty);
                formBuilder.Append($"{encodedKey}={encodedValue}");
            }
            return formBuilder.ToString();
        }

        // 其他请求体类型(如multipart/form-data)可按需扩展
        return string.Empty;
    }
}

方法逻辑说明

  1. Content-Type判断:先从请求头中获取Content-Type,以此区分要处理的请求体类型
  2. JSON请求体处理:找到RequestBody类型的参数,若参数是对象则用RestSharp自带的序列化器生成JSON(确保和实际发送的内容完全一致),若已是字符串则直接返回
  3. 表单请求体处理:收集所有GetOrPost类型的参数,对键值对做URL编码后拼接成标准的表单格式字符串

在认证器中使用

实现IAuthenticator接口时,调用上述方法获取原始请求体,再计算SHA256哈希并添加到Authorization头:

using RestSharp;
using System.Security.Cryptography;

public class Sha256RequestAuthenticator : IAuthenticator
{
    private readonly string _apiKey;
    private readonly string _secret;

    public Sha256RequestAuthenticator(string apiKey, string secret)
    {
        _apiKey = apiKey;
        _secret = secret;
    }

    public void Authenticate(IRestClient client, IRestRequest request)
    {
        var rawBody = request.GetRawRequestBody();
        using var sha256 = SHA256.Create();
        var hashBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(rawBody));
        // 转换为十六进制字符串(或Base64,根据接口要求调整)
        var hashHex = BitConverter.ToString(hashBytes).Replace("-", string.Empty).ToLowerInvariant();

        request.AddHeader("Authorization", $"Signature {_apiKey}:{hashHex}");
    }
}

注意事项

  • 若项目使用自定义JSON序列化器(如Newtonsoft.Json),需替换代码中的SystemTextJsonSerializer为对应序列化器,保证生成的JSON与RestSharp实际发送内容一致
  • 对于手动设置Content-Type的场景,需确保头信息正确,否则无法匹配处理逻辑
  • 如需支持multipart/form-data类型请求体,需额外处理边界符和参数的序列化逻辑,可参考RestSharp内部的MultipartFormDataSerializer实现

内容的提问来源于stack exchange,提问作者holdenmcgrohen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 01:43:16