c#从HttpClient的模型对象构建URL编码查询

Ran*_*nju 3 c# dotnet-httpclient

需要从HttpClient的模型对象构建URL编码查询

我的模型是

class SaveProfileRequest
{
    public string gName { get; set; }
    public string gEmail { get; set; }
    public long gContact { get; set; }
    public string gCompany { get; set; }
    public string gDeviceID { get; set; }
    public string Organization { get; set; }
    public string profileImage { get; set; }
    public string documentImagefront { get; set; }
    public string documentImageback { get; set; }
}

SaveProfileRequest request = new SaveProfileRequest() { gName = name, gEmail = email, gContact = phonenumber, gCompany = company,
            gDeviceID = deviceId, Organization = "", profileImage = "", documentImageback = "", documentImagefront = "" };

string response = await RequestProvider.PostAsync<string, SaveProfileRequest>(uri, request);
Run Code Online (Sandbox Code Playgroud)

我有一个内容类型为JSON的工作代码

content = new StringContent(JsonConvert.SerializeObject(data));

content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
Run Code Online (Sandbox Code Playgroud)

数据类型为TInput的位置

试着

content = new StringContent(System.Net.WebUtility.UrlEncode(JsonConvert.SerializeObject(data)));

content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
Run Code Online (Sandbox Code Playgroud)

但没锻炼

Abb*_*bba 9

您可以使用这个简化版本

public static class URLExtensions
{
    public static string ToKeyValueURL(this object obj)
    {
        var keyvalues = obj.GetType().GetProperties()
            .ToList()
            .Select(p => $"{p.Name} = {p.GetValue(obj)}")
            .ToArray();

        return string.Join('&',keyvalues);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 注意:这不适用于具有复杂属性的对象,例如对象或集合。 (2认同)

Cod*_*ler 8

JsonConvert只生成json内容.对于urlencoded查询,您应该构造实例FormUrlEncodedContent.作为构造函数参数,它需要收集KeyValuePair<string, string>.所以主要的技巧是为模型对象构建这个集合.

您可以将反射用于此目的.但是有一个基于Json.net的简单解决方案.这里描述以下ToKeyValue()扩展方法是从该博客文章复制/粘贴:

public static class ObjectExtensions
{
    public static IDictionary<string, string> ToKeyValue(this object metaToken)
    {
        if (metaToken == null)
        {
            return null;
        }

        JToken token = metaToken as JToken;
        if (token == null)
        {
            return ToKeyValue(JObject.FromObject(metaToken));
        }

        if (token.HasValues)
        {
            var contentData = new Dictionary<string, string>();
            foreach (var child in token.Children().ToList())
            {
                var childContent = child.ToKeyValue();
                if (childContent != null)
                {
                    contentData = contentData.Concat(childContent)
                        .ToDictionary(k => k.Key, v => v.Value);
                }
            }

            return contentData;
        }

        var jValue = token as JValue;
        if (jValue?.Value == null)
        {
            return null;
        }

        var value = jValue?.Type == JTokenType.Date ?
            jValue?.ToString("o", CultureInfo.InvariantCulture) :
            jValue?.ToString(CultureInfo.InvariantCulture);

        return new Dictionary<string, string> { { token.Path, value } };
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,您可以像以下一样简单地构建网址编码的内容:

var keyValues = data.ToKeyValue();
var content = new FormUrlEncodedContent(keyValues);
Run Code Online (Sandbox Code Playgroud)


Tod*_*ier 5

这可以使用Flurl毫不费力地完成(免责声明:我是作者),因为这个确切的场景 - 将 .NET 对象的属性解析为 URL 编码的键值对 - 支持开箱即用:

using Flurl.Http;

var resp = await url.PostUrlEncodedAsync(data);
Run Code Online (Sandbox Code Playgroud)

FlurlHttpClient在幕后使用,所以在上面的例子中,resp是 的一个实例HttpResponseMessage,就像调用是HttpClient直接使用一样。.ReceiveString()如果您只需要响应正文,或者.ReceiveJson<T>()如果您需要一个 JSON 响应并需要一个匹配的 .NET 类型的对象,您也可以附加到调用中T