gpt4 book ai didi

c# - 使用 Microsoft.HttpClient 和 HttpContentExtensions 的通用 POST 请求

转载 作者:太空狗 更新时间:2023-10-29 21:55:45 25 4
gpt4 key购买 nike

我正在使用 WCF REST 初学者工具包中提供的非常棒的 HttpClient。我有以下针对 HelloTxt API 的方法:

public UserValidateResponse Validate()
{
HttpClient client = new HttpClient(baseUrl);

HttpMultipartMimeForm form = new HttpMultipartMimeForm();
form.Add("app_key", this.AppKey);
form.Add("user_key", this.UserKey);
HttpResponseMessage response = client.Post("user.validate", form.CreateHttpContent());

return response.Content.ReadAsXmlSerializable<UserValidateResponse>();
}

我有一个很好的通用 GetRequest 方法,如下所示:

public T GetRequest<T>(string query)
{
HttpClient client = new HttpClient(baseUrl);
client.DefaultHeaders.UserAgent.AddString(@"http://www.simply-watches.co.uk/");

HttpResponseMessage response = client.Get(query);
response.EnsureStatusIsSuccessful();

T data = default(T);
try
{
data = response.Content.ReadAsXmlSerializable<T>();
return data;
}
catch (Exception ex)
{
Console.Write(String.Format("{0}: {1}", ex.Message, ex.InnerException.Message));
}

return data;
}

这样做的好处是您可以按照这个随机示例将 T 作为响应类型传递给它:

public List<User> GetUsers(int deptid)
{
string query = String.Format("department.getUsers?api_key={0}&dept_id={1}", this.APIKey, deptId);

return GetRequest<List<User>>(query);
}

我现在想要相同的通用样式 POST 方法,而不是 GET,我确信我可以使用 HttpContentExtensions,但我不知道如何将请求转换为 HttpMultipartMimeForm。这是我到目前为止所拥有的:

public T PostRequest<K, T>(string query, K request)
{
HttpClient client = new HttpClient(baseUrl);
// the following line doesn't work! Any suggestions?
HttpContent content = HttpContentExtensions.CreateDataContract<K>(request, Encoding.UTF8, "application/x-www-form-urlencoded", typeof(HttpMultipartMimeForm));

HttpResponseMessage response = client.Post(query, content);
response.EnsureStatusIsSuccessful();

T data = default(T);
try
{
data = response.Content.ReadAsXmlSerializable<T>();
return data;
}
catch (Exception ex)
{
Console.Write(String.Format("{0}: {1}", ex.Message, ex.InnerException.Message));
}

return data;
}

它会这样称呼:

UserValidateResponse response = PostRequest<UserValidateRequest, UserValidateResponse>("user.validate", new UserValidateRequest(this.AppKey, this.UserKey));

它是针对这个 API 工作的:http://hellotxt.com/developers/documentation .非常欢迎任何建议!我可以为每个 POST 定义不同的表单,但最好是通用地执行此操作。

最佳答案

我就此回答了我自己的问题。代码可以在我的.NET wrapper for the HelloTxt API - HelloTxt.NET中看到,并且根据我上面的评论,使用反射来计算请求对象属性,并使用值填充 HttpMultipartMimeForm(),同时检查 Required 上的数据注释类属性。

有问题的代码是:

/// <summary>
/// Generic post request.
/// </summary>
/// <typeparam name="K">Request Type</typeparam>
/// <typeparam name="T">Response Type</typeparam>
/// <param name="query">e.g. user.validate</param>
/// <param name="request">The Request</param>
/// <returns></returns>
public T PostRequest<K, T>(string query, K request)
{
using (var client = GetDefaultClient())
{
// build form data post
HttpMultipartMimeForm form = CreateMimeForm<K>(request);

// call method
using (HttpResponseMessage response = client.Post(query, form.CreateHttpContent()))
{
response.EnsureStatusIsSuccessful();
return response.Content.ReadAsXmlSerializable<T>();
}
}
}

/// <summary>
/// Builds a HttpMultipartMimeForm from a request object
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="request"></param>
/// <returns></returns>
public HttpMultipartMimeForm CreateMimeForm<T>(T request)
{
HttpMultipartMimeForm form = new HttpMultipartMimeForm();

Type type = request.GetType();
PropertyInfo[] properties = type.GetProperties();
foreach (PropertyInfo property in properties)
{
foreach (Attribute attribute in property.GetCustomAttributes(true))
{
RequiredAttribute requiredAttribute = attribute as RequiredAttribute;
if (requiredAttribute != null)
{
if (!requiredAttribute.IsValid(property.GetValue(request, null)))
{
//Console.WriteLine("{0} [type = {1}] [value = {2}]", property.Name, property.PropertyType, property.GetValue(property, null));
throw new ValidationException(String.Format("{0} [type = {1}] requires a valid value", property.Name, property.PropertyType));
}
}
}

if (property.PropertyType == typeof(FileInfo))
{
FileInfo fi = (FileInfo)property.GetValue(request, null);
HttpFormFile file = new HttpFormFile();
file.Content = HttpContent.Create(fi, "application/octet-stream");
file.FileName = fi.Name;
file.Name = "image";

form.Files.Add(file);
}
else
{
form.Add(property.Name, String.Format("{0}", property.GetValue(request, null)));
}
}

return form;
}

关于c# - 使用 Microsoft.HttpClient 和 HttpContentExtensions 的通用 POST 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4749982/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com