C# 使用Microsoft.HttpClient和HttpContentExtensions的一般POST请求

C# 使用Microsoft.HttpClient和HttpContentExtensions的一般POST请求,c#,wcf,rest,httpclient,C#,Wcf,Rest,Httpclient,我使用的是WCF REST初学者工具包中提供的非常棒的HttpClient。我有以下针对HelloText API的方法: public UserValidateResponse Validate() { HttpClient client = new HttpClient(baseUrl); HttpMultipartMimeForm form = new HttpMultipartMimeForm(); form.Add("app_key", this.AppKey

我使用的是WCF REST初学者工具包中提供的非常棒的HttpClient。我有以下针对HelloText 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>();
}
public UserValidateResponse Validate()
{
HttpClient=新的HttpClient(baseUrl);
HttpMultipartMimeForm form=新的HttpMultipartMimeForm();
添加(“应用程序密钥”,this.AppKey);
添加(“用户密钥”,this.UserKey);
HttpResponseMessage response=client.Post(“user.validate”,form.CreateHttpContent());
返回response.Content.ReadAsXmlSerializable();
}
我有一个很好的通用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;
}
UserValidateResponse response = PostRequest<UserValidateRequest, UserValidateResponse>("user.validate", new UserValidateRequest(this.AppKey, this.UserKey));
publictgetrequest(字符串查询)
{
HttpClient=新的HttpClient(baseUrl);
client.DefaultHeaders.UserAgent.AddString(@)http://www.simply-watches.co.uk/");
HttpResponseMessage response=client.Get(查询);
response.EnsureStatusIsSuccessful();
T数据=默认值(T);
尝试
{
data=response.Content.ReadAsXmlSerializable();
返回数据;
}
捕获(例外情况除外)
{
Write(String.Format(“{0}:{1}”,例如Message,例如InnerException.Message));
}
返回数据;
}
这样做的好处是,您可以根据以下随机示例将其作为响应类型传递:

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);
}
public List GetUsers(intdeptid)
{
string query=string.Format(“department.getUsers?api_key={0}&dept_id={1}”,this.APIKey,deptId);
返回GetRequest(查询);
}
现在,我希望使用相同的通用样式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;
}
publictpostRequest(字符串查询,K请求)
{
HttpClient=新的HttpClient(baseUrl);
//下面这行不行!有什么建议吗?
HttpContent content=HttpContentExtensions.CreateDataContract(请求,Encoding.UTF8,“application/x-www-form-urlencoded”,typeof(HttpMultipartMimeForm));
HttpResponseMessage response=client.Post(查询,内容);
response.EnsureStatusIsSuccessful();
T数据=默认值(T);
尝试
{
data=response.Content.ReadAsXmlSerializable();
返回数据;
}
捕获(例外情况除外)
{
Write(String.Format(“{0}:{1}”,例如Message,例如InnerException.Message));
}
返回数据;
}
可以这样称呼:

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;
}
UserValidateResponse response = PostRequest<UserValidateRequest, UserValidateResponse>("user.validate", new UserValidateRequest(this.AppKey, this.UserKey));
UserValidateResponse-response=PostRequest(“user.validate”,newuservalidateRequest(this.AppKey,this.UserKey));

无法针对此API工作:。欢迎提出任何建议!我可以为每个帖子定义一个不同的表单,但一般来说这样做会很好。

我回答了自己的问题。代码可以在my中看到,根据我上面的评论,使用反射来计算请求对象属性,并用值填充
HttpMultipartMimeForm()
,同时检查类属性上的
必需的
数据注释

有关守则是:

/// <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;
}
//
///一般邮政请求。
/// 
///请求类型
///响应类型
///例如,user.validate
///请求
/// 
公共T PostRequest(字符串查询,K请求)
{
使用(var client=GetDefaultClient())
{
//构建表单数据发布
HttpMultipartMimeForm form=CreateMimeForm(请求);
//调用方法
使用(HttpResponseMessage response=client.Post(查询,form.CreateHttpContent()))
{
response.EnsureStatusIsSuccessful();
返回response.Content.ReadAsXmlSerializable();
}
}
}
/// 
///从请求对象生成HttpMultipartMimeForm
/// 
/// 
/// 
/// 
公共HttpMultipartMimeForm CreateMimeForm(T请求)
{
HttpMultipartMimeForm form=新的HttpMultipartMimeForm();
Type Type=request.GetType();
PropertyInfo[]properties=type.GetProperties();
foreach(属性中的PropertyInfo属性)
{
foreach(property.GetCustomAttributes中的属性(true))
{
RequiredAttribute RequiredAttribute=属性作为RequiredAttribute;
if(requiredAttribute!=null)
{
如果(!requiredAttribute.IsValid(property.GetValue(request,null)))
{
//WriteLine(“{0}[type={1}][value={2}]”,property.Name,property.PropertyType,property.GetValue(property,null));
抛出新的ValidationException(String.Format(“{0}[type={1}]需要一个有效值”、property.Name、property.PropertyType));
}
}
}
if(property.PropertyType==typeof(FileInfo))
{
FileInfo fi=(FileInfo)property.GetValue(请求,null);
HttpFormFile文件=新的HttpFormFile();
file.Content=HttpContent.Create(fi,“应用程序/八位字节流”);
file.FileName=fi.Name;
file.Name=“image”;
form.Files.Add(文件);
}
其他的
{
Add(property.Name,String.Format(“{0}”,property.GetValue(request,null));
}
}
申报表;
}

我觉得唯一的方法是使用反射并基于类的简单属性构建HttpMultipartMimeForm,或者序列化对象,然后获取根XML节点下的第一个子节点。您提供的github链接已断开。