Как да направите XML POST с FlUrl

FlUrl върши страхотна работа при справяне с Json/UrlEncoded заявки. Документацията обаче всъщност не посочва как да се справят с други типове заявки като text/xml.

Кой е най-добрият начин да направите XML POST с помощта на FlUrl?

Това (достъп до базов HttpClient) донякъде проваля целта на използването на FlUrl, тъй като трябва да изградите URI и съдържанието отново:

var result = await "http://someUrl"
                   .AppendPathSegment(pathSegment)
                   .SetQueryParam("name", name)
                   .WithBasicAuth(_userName, _apiToken)
                   .HttpClient
                   .PostAsync(<uri>, <content>);

person Mrchief    schedule 10.03.2015    source източник


Отговори (5)


Поддръжката на XML все още не е въведена, но това е регистрирано и е едно от малкото оставащи функции, които бих искал да има за Flurl.Http 1.0. (Изненадващо, никой не го е поискал досега.)

Междувременно Flurl е доста лесен за разширяване и можете сами да добавите тази поддръжка чрез методи за разширение. Това трябва да е всичко, от което се нуждаете, за да публикувате плавно XML низ:

public static class FlurlXmlExtensions
{
    // chain off an existing FlurlClient:
    public static async Task<HttpResponseMessage> PostXmlAsync(this FlurlClient fc, string xml) {
        try {
            var content = new CapturedStringContent(xml, Encoding.UTF8, "application/xml");
            return await fc.HttpClient.PostAsync(fc.Url, content);
        }
        finally {
            if (AutoDispose)
                Dispose();
        }
    }

    // chain off a Url object:
    public static Task<HttpResponseMessage> PostXmlAsync(this Url url, string xml) {
        return new FlurlClient(url, true).PostXmlAsync(xml);
    }

    // chain off a url string:
    public static Task<HttpResponseMessage> PostXmlAsync(this string url, string xml) {
        return new FlurlClient(url, true).PostXmlAsync(xml);
    }
}

АКТУАЛИЗАЦИЯ:

Реших да не включвам XML поддръжка във Flurl, до голяма степен защото член на общността се засили и създаде страхотна библиотека с разширения за него:

https://github.com/lvermeulen/Flurl.Http.Xml

person Todd Menier    schedule 10.03.2015
comment
Има ли начин да посочите Content-Type на text/xml, когато използвате тази библиотека с разширения? Извън кутията изглежда, че всички заявки са маркирани с application/xml. - person Matt Koch; 17.03.2017
comment
@user2710915 .WithHeader("Content-Type", "text/xml")... - person Todd Menier; 17.03.2017

Ровейки се в източника, изглежда, че SendAsync е в процес на работа. Тъй като последният пакет все още не го поддържа, реших да добавя свой собствен:

public static class FlurlHttpExtensions
{
    /// <summary>
    /// Sends an asynchronous POST request of specified data (usually an anonymous object or dictionary) formatted as XML.
    /// </summary>
    /// <param name="client">The FlurlClient</param>
    /// <param name="serializedXml">Data to be serialized and posted.</param>
    /// <returns>A Task whose result is the received HttpResponseMessage.</returns>
    public static Task<HttpResponseMessage> PostXmlAsync(this FlurlClient client, string serializedXml)
    {
        var request = new HttpRequestMessage(HttpMethod.Post, client.Url.ToString())
        {
            Content = new CapturedStringContent(serializedXml, Encoding.UTF8, "text/xml"),
            Method = HttpMethod.Post
        };
        return client.HttpClient.SendAsync(request);
    }
}

Да, използвах някои преки пътища като приемане на сериализиран XML, вместо да се сериализирам. В момента това работи за мен.

Ако има по-добър подход, направо съм на уши!

person Mrchief    schedule 10.03.2015
comment
Добро обаждане на CapturedStringContent, забравих за това. Открих, че си заслужава (обикновено) малкия отпечатък от паметта, за да мога да проверя оригиналния послеслов на тялото на заявката, ако нещо се обърка. - person Todd Menier; 11.03.2015
comment
И да, SendAsync е в процес на работа. Това ще промени модела за разширяване само малко, така че няма да се налага да правите пробната/накрая/изхвърлящата част сами. Ще се върна и ще актуализирам отговора си, когато е готов, но това няма да доведе до прекъсване на тази реализация. - person Todd Menier; 11.03.2015

Малко закъснях с това, но успях да използвам Flurl естествено, с Xml (имах проблеми с xml разширението)

Първо вземете своя xml низ от данни, преобразувайте го в Html съдържание

var httpContent = new StringContent(xmlDateString, Encoding.UTF8, "text/xml");

след това използвайте това съдържание в нормално postsync повикване.

var response = await "http://localhost/Notices/webservices/importer.asmx"
        .WithHeader("Authorization", "Basic ssssserrrrr")
        .WithHeader("Content-Type", "text/xml")
        .WithHeader("SOAPAction", "\"http://tempuri.org/ImportData\"")
        .PostAsync(httpContent);

В това обаждане аз задавам типа съдържание. Аз също настройвам действието на сапуна (това е уеб методът, който извиквам).

След това работи нормално.

person Ashley Jackson    schedule 05.12.2017
comment
Трябва ли да зададете заглавка Content-Type, когато полезният товар е Encoding.UTF8, text/xml? - person Pepster; 04.06.2019

Ревизия за FlurlRequest

public static class FlurlXmlExtensions
{
    // chain off an existing FlurlRequest:
    public static async Task<HttpResponseMessage> PostXmlAsync(this IFlurlRequest fr, string xml)
    {
        var content = new CapturedStringContent(xml, Encoding.UTF8, "application/xml");
        return await fr.PostAsync(content);
    }

    // chain off a Url object:
    public static Task<HttpResponseMessage> PostXmlAsync(this Url url, string xml)
    {
        return new FlurlRequest(url.Path).PostXmlAsync(xml);
    }

    // chain off a url string:
    public static Task<HttpResponseMessage> PostXmlAsync(this string url, string xml)
    {
        return new FlurlRequest(url).PostXmlAsync(xml);
    }
}
person codepen    schedule 21.08.2020

За моя сценарий просто трябваше да ПУБЛИКУВАМ представяне на низ на моя XML, като в същото време мога да задам Content-Type на text/xml и кодирането на utf-8. Не съм сигурен дали има по-прост начин да направя това, просто не виждам, но ето метод за разширение, който ме отведе там:

public static class FlurlXmlExtensions
    {
        /// <summary>
        /// Sends an asynchronous POST request that contains an XML string.
        /// </summary>
        /// <param name="client">The IFlurlClient instance.</param>
        /// <param name="data">Contents of the request body.</param>
        /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation. Optional.</param>
        /// <param name="completionOption">The HttpCompletionOption used in the request. Optional.</param>
        /// <returns>A Task whose result is the received HttpResponseMessage.</returns>
        public static Task<HttpResponseMessage> PostXmlStringAsync(this IFlurlClient client, string data, CancellationToken cancellationToken = default(CancellationToken), HttpCompletionOption completionOption = HttpCompletionOption.ResponseContentRead)
        {
            var content = new CapturedStringContent(data, Encoding.UTF8, "text/xml");

            return client.SendAsync(HttpMethod.Post, content: content, cancellationToken: cancellationToken, completionOption: completionOption);
        }

    }
person Matt Koch    schedule 17.03.2017