【问题标题】:Post complex type formatted as form-url-encoded using ASP.Net HttpClient使用 ASP.Net HttpClient 将复杂类型格式化为 form-url-encoded
【发布时间】:2013-06-17 13:15:02
【问题描述】:

我需要HTTP POST 一个复杂类型到一个网络服务(我无法控制)。我相信 Web 服务是使用旧版本的 ASP.NET MVC 构建的。它模型绑定格式为form-url-encoded的有效载荷。

如果我向它发射以下内容,它会完美运行。如您所见,我手动创建了一组键/值对。

    var values = new List<KeyValuePair<string, string>>
    {
        new KeyValuePair<string, string>("Username", "some-username"),
        new KeyValuePair<string, string>("Password", "some-password"),
        new KeyValuePair<string, string>("Product", "some-product")
    };

    var content = new FormUrlEncodedContent(values);

    var response = new HttpClient().PostAsync(url, content).Result;

但我不想这样做,我只想尽可能发送复杂类型。

var content = new ComplexType("some-username", "some-password", "some-product");

var response = new HttpClient().PostAsync(url, content).Result;

我相信曾经有一个HttpRequestMessage&lt;T&gt;,但它已经被放弃了

HttpClient.PostAsJsonAsync<T>(T value) sends “application/json” HttpClient.PostAsXmlAsync<T>(T value) sends “application/xml”

但我不想发送JsonXML 我想发送form-url-ecncoded,而无需将复杂类型转换为键/值对集合。

基本上我也想知道 Jaans 对this question 的回答(他是对第二个回答的第二个评论)。

谁能给点建议。

【问题讨论】:

  • Web API 确实有一个FormUrlEncodedMediaTypeFormatter,但是这个格式化程序不能“写”,只能“读”。因此,Web API 对此没有开箱即用的支持。
  • 那真是太可惜了。有人知道体面的工作吗?
  • 您可能可以看一下来自 Carlos 的自定义格式化程序:code.msdn.microsoft.com/windowsdesktop/…,但这涉及从 JObject 转换为 FormUrlEncoded。我不喜欢这样建议,但您可以使用 Json.net 序列化程序将您的复杂类型转换为 JObject,然后按照链接中的建议将此 JObject 转换为 formurlencoded。
  • 这可能是要走的路。谢谢基兰

标签: c# asp.net-web-api


【解决方案1】:

既然您几乎已经找到了一个可行的解决方案,我会说随它去吧。在扩展方法中组织您的代码,以便您可以使用它进行发布,例如:

public static async Task<HttpResponseMessage> PostAsFormUrlEncodedAsync<T>(
    this HttpClient httpClient, T value)
{
    // Implementation
}

您的实现只需要将对象序列化为表单编码值,您应该可以通过反射轻松完成。

然后您可以像调用 JSON 或 XML 一样调用代码。

【讨论】:

    【解决方案2】:

    Flurl [披露:我是作者] 提供了一种似乎正是您正在寻找的方法:

    using Flurl.Http;
    
    var resp = await url.PostUrlEncodedAsync(new {
        Username = "some-username",
        Password = "some-password",
        Product = "some-product",
    });
    

    Flurl 小巧便携,在后台使用HttpClient。它可以通过 NuGet 获得:

    PM> Install-Package Flurl.Http
    

    【讨论】:

      【解决方案3】:

      你可以这样做:

      var content = new ComplexType("some-username", "some-password", "some-product");
      
      var response = new HttpClient().PostAsync<ComplexType>(url, content, new FormUrlEncodedMediaTypeFormatter()).Result;
      

      【讨论】:

      • 这看起来和我希望的完全一样。我可能是错的,但是当我最初提出问题时,我认为此功能不可用。否则为什么@ToddMenier 会编写他的 Flurl 库?也就是说,感谢您的回答,它可能会帮助其他人继续前进。
      • 不幸的是,这不起作用,因为FormUrlEncodedMediaTypeFormatter 不会序列化任意类型。您必须使用另一个库 FormUrlEncodedContent 或使用反射
      猜你喜欢
      • 1970-01-01
      • 2015-03-05
      • 1970-01-01
      • 1970-01-01
      • 2017-08-18
      • 1970-01-01
      • 2019-08-25
      • 2018-09-15
      • 1970-01-01
      相关资源
      最近更新 更多