2013-06-20 2 views
6

Мне нужно, чтобы HTTP POST сложный тип веб-службы (который я не контролирую). Я считаю, что веб-сервис был создан с использованием старой версии ASP.NET MVC. Эта модель связывает полезную нагрузку, отформатированную как form-url-encoded.Почтовый сложный тип, форматированный как форма-url-кодированный с использованием ASP.Net HttpClient

Если я стреляю в него, он отлично работает. Как вы можете видеть, я вручную создал коллекцию пар ключ/значение.

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<T> но это было понижено в пользу

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

Но я не хочу, чтобы отправить Json или XML Я хочу отправить form-url-ecncoded без хлопот преобразования сложных типов в коллекции пар ключ/значение.

По сути, я также хотел бы узнать ответ this question, который представляет Яанс (его второй комментарий ко второму вопросу).

Может кто-нибудь посоветуйте пожалуйста.

+0

Web API действительно есть 'FormUrlEncodedMediaTypeFormatter', но это форматировщик не может "писать", и только может "читать". Таким образом, для Web API не существует поддержки. –

+0

Это настоящий позор. Кто-нибудь знает о достойной работе? –

+1

Возможно, вы можете взглянуть на пользовательский форматировщик из Карлоса: http://code.msdn.microsoft.com/windowsdesktop/Converting-between-cda3c9a7, но это говорит о преобразовании из JObject в FormUrlEncoded. Мне не нравится предлагать это, но вы, вероятно, можете преобразовать свой complextype в JObject с помощью сериализатора Json.net, а затем преобразовать этот JObject в formurlencoded, как указано в ссылке. –

ответ

0

Поскольку у вас почти есть решение, которое действительно работает, я бы сказал, просто пойдите с ним. Организуйте свой код внутри метода расширения, так что вы не можете использовать это, что-то вроде:

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

Ваша реализация просто нужно сериализовать объект в виде кодированных значений, которые вы должны быть в состоянии легко сделать с отражением.

Тогда вы можете позвонить по этому коду именно так, как в случае с JSON или XML.

1

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 
-1

Вы можете сделать это:

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

var response = new HttpClient().PostAsync<ComplexType>(url, content, new FormUrlEncodedMediaTypeFormatter()).Result; 
+0

Это похоже на то, на что я надеялся. Я мог ошибаться, но я не думаю, что эта функция была доступна, когда я задавал вопрос изначально. Иначе зачем @ToddMenier написал свою библиотеку Flurl?Тем не менее, спасибо за ваш ответ, это может помочь другим двигаться вперед. –

+1

К сожалению, это не работает, поскольку 'FormUrlEncodedMediaTypeFormatter' не сериализует произвольные типы. Вы должны либо использовать другую библиотеку, либо FormUrlEncodedContent', либо использовать рефлексию – eddiegroves