oro*_*nbz 8 asp.net json httpclient utf-8 asp.net-web-api
我有HttpClient.PostAsJsonAsync()的问题
除了"Content-Type"标题中的"application/json"之外,该方法还添加了"charset = utf-8"
所以标题看起来像这样:
Content-Type:application/json; 字符集= utf-8的
虽然ASP.NET WebAPI对此标头没有任何问题,但我发现我作为客户端使用的其他WebAPI不接受带有此标头的请求,除非它只是application/json.
无论如何在使用PostAsJsonAsync()时从Content-Type中删除"charset = utf-8",还是应该使用其他方法?
解决方案: Yishai的积分!
using System.Net.Http.Headers;
public class NoCharSetJsonMediaTypeFormatter : JsonMediaTypeFormatter
{
public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType)
{
base.SetDefaultContentHeaders(type, headers, mediaType);
headers.ContentType.CharSet = "";
}
}
public static class HttpClientExtensions
{
public static async Task<HttpResponseMessage> PostAsJsonWithNoCharSetAsync<T>(this HttpClient client, string requestUri, T value, CancellationToken cancellationToken)
{
return await client.PostAsync(requestUri, value, new NoCharSetJsonMediaTypeFormatter(), cancellationToken);
}
public static async Task<HttpResponseMessage> PostAsJsonWithNoCharSetAsync<T>(this HttpClient client, string requestUri, T value)
{
return await client.PostAsync(requestUri, value, new NoCharSetJsonMediaTypeFormatter());
}
}
Run Code Online (Sandbox Code Playgroud)
您可以从JsonMediaTypeFormatter派生并覆盖SetDefaultContentHeaders.
打电话base.SetDefaultContentHeaders()
然后清除headers.ContentType.CharSet
然后根据以下代码编写自己的扩展方法:
public static Task<HttpResponseMessage> PostAsJsonAsync<T>(this HttpClient client, string requestUri, T value, CancellationToken cancellationToken)
{
return client.PostAsync(requestUri, value,
new JsonMediaTypeFormatter(), cancellationToken);
}
Run Code Online (Sandbox Code Playgroud)
本质上是这样的:
public static Task<HttpResponseMessage> PostAsJsonWithNoCharSetAsync<T>(this HttpClient client, string requestUri, T value, CancellatioNToken cancellationToken)
{
return client.PostAsync(requestUri, value,
new NoCharSetJsonMediaTypeFormatter(), cancellationToken);
}
Run Code Online (Sandbox Code Playgroud)
为了更直接地控制您发送的有效负载,您可以创建派生的 HttpContent 类,而不是让您的对象传递给 ObjectContent 类,然后 ObjectContent 类将流委托给 Formatter 类。
一个同时支持读写的 JsonContent 类看起来像这样,
public class JsonContent : HttpContent
{
private readonly Stream _inboundStream;
private readonly JToken _value;
public JsonContent(JToken value)
{
_value = value;
Headers.ContentType = new MediaTypeHeaderValue("application/json");
}
public JsonContent(Stream inboundStream)
{
_inboundStream = inboundStream;
}
public async Task<JToken> ReadAsJTokenAsync()
{
return _value ?? JToken.Parse(await ReadAsStringAsync());
}
protected async override Task<Stream> CreateContentReadStreamAsync()
{
return _inboundStream;
}
protected override Task SerializeToStreamAsync(Stream stream, TransportContext context)
{
if (_value != null)
{
var jw = new JsonTextWriter(new StreamWriter(stream)) {Formatting = Formatting.Indented};
_value.WriteTo(jw);
jw.Flush();
} else if (_inboundStream != null)
{
return _inboundStream.CopyToAsync(stream);
}
return Task.FromResult<object>(null);
}
protected override bool TryComputeLength(out long length)
{
length = -1;
return false;
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
_inboundStream.Dispose();
}
base.Dispose(disposing);
}
}
Run Code Online (Sandbox Code Playgroud)
一旦你有了这门课,你就可以做,
var content = new JsonContent(myObject);
_httpClient.PostAsync(uri,content);
Run Code Online (Sandbox Code Playgroud)
如果您需要更改任何内容标题,您可以在发送请求之前手动执行此操作。如果您需要弄乱任何请求标头,那么您可以使用 SendAsync 重载,
var content = new JsonContent(myObject);
// Update Content headers here
var request = new HttpRequestMessage {RequestUri = uri, Content = content };
// Update request headers here
_httpClient.SendAsync(request);
Run Code Online (Sandbox Code Playgroud)
几乎可以为任何媒体类型或任何数据源轻松创建派生内容类。我创建了从 HttpContent 派生的各种类。例如 FileContent、EmbeddedResourceContent、CSVContent、XmlContent、ImageContent、HalContent、CollectionJsonContent、HomeContent、ProblemContent。
就我个人而言,我发现它可以让我更好地控制我的有效载荷。
归档时间: |
|
查看次数: |
5442 次 |
最近记录: |