如何使用 FlUrl XML POST
How to do XML POST with FlUrl
FlUrl 在处理 Json/UrlEncoded 请求方面做得很好。但是,文档并没有真正指出如何处理其他请求类型,例如 text/xml
.
使用 FlUrl 执行 XML POST 的最佳方法是什么?
这(访问底层 HttpClient
)有点违背了使用 FlUrl 的目的,因为您需要再次构建 URI 和内容:
var result = await "http://someUrl"
.AppendPathSegment(pathSegment)
.SetQueryParam("name", name)
.WithBasicAuth(_userName, _apiToken)
.HttpClient
.PostAsync(<uri>, <content>);
XML 支持尚未内置,但这是 logged 并且是我希望为 Flurl.Http 1.0 提供的少数剩余功能之一。 (令人惊讶的是,直到现在还没有人提出要求。)
同时,Flurl is pretty easy to extend,您可以通过扩展方法自行添加此支持。这应该是您流利 post 一个 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);
}
}
更新:
我决定不在 Flurl 中包含 XML 支持,主要是因为一位社区成员站出来为它创建了一个很棒的扩展库:
通过源代码挖掘,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 而不是序列化自己。目前,这对我有用。
如果有更好的方法,我洗耳恭听!
对于我的场景,我只需要 POST 我的 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);
}
}
我来晚了一点,但是,我已经设法通过 Xml 自然地使用 Flurl(在 xml 扩展时遇到问题)
首先,把你的xml数据字符串,转换成Html内容
var httpContent = new StringContent(xmlDateString, Encoding.UTF8, "text/xml");
然后,在正常的后异步调用中使用该内容。
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);
在这个调用中,我正在设置内容类型。我也在设置 soap 操作(这是我正在调用的网络方法)。
然后就可以正常使用了。
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);
}
}
FlUrl 在处理 Json/UrlEncoded 请求方面做得很好。但是,文档并没有真正指出如何处理其他请求类型,例如 text/xml
.
使用 FlUrl 执行 XML POST 的最佳方法是什么?
这(访问底层 HttpClient
)有点违背了使用 FlUrl 的目的,因为您需要再次构建 URI 和内容:
var result = await "http://someUrl"
.AppendPathSegment(pathSegment)
.SetQueryParam("name", name)
.WithBasicAuth(_userName, _apiToken)
.HttpClient
.PostAsync(<uri>, <content>);
XML 支持尚未内置,但这是 logged 并且是我希望为 Flurl.Http 1.0 提供的少数剩余功能之一。 (令人惊讶的是,直到现在还没有人提出要求。)
同时,Flurl is pretty easy to extend,您可以通过扩展方法自行添加此支持。这应该是您流利 post 一个 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);
}
}
更新:
我决定不在 Flurl 中包含 XML 支持,主要是因为一位社区成员站出来为它创建了一个很棒的扩展库:
通过源代码挖掘,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 而不是序列化自己。目前,这对我有用。
如果有更好的方法,我洗耳恭听!
对于我的场景,我只需要 POST 我的 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);
}
}
我来晚了一点,但是,我已经设法通过 Xml 自然地使用 Flurl(在 xml 扩展时遇到问题)
首先,把你的xml数据字符串,转换成Html内容
var httpContent = new StringContent(xmlDateString, Encoding.UTF8, "text/xml");
然后,在正常的后异步调用中使用该内容。
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);
在这个调用中,我正在设置内容类型。我也在设置 soap 操作(这是我正在调用的网络方法)。
然后就可以正常使用了。
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);
}
}