使用后的字节数组的Web API服务器的HttpClient [英] Post byte array to Web API server using HttpClient
问题描述
我要发布这个数据的Web API服务器:
公共密封类SomePostRequest
{
酒店的公共INT标识{搞定;组; }
公众的byte []内容{搞定;组; }
}
使用此代码服务器:
[路线(传入)]
[ValidateModel]
公共异步任务< IHttpActionResult> PostIncomingData(SomePostRequest的RequestData)
{这里
// POST逻辑
}
和本 - 客户端:
VAR的客户=新的HttpClient();
client.BaseAddress =新的URI(HTTP://本地主机:25001 /);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
新MediaTypeWithQualityHeaderValue(应用/ JSON));
变种内容=新FormUrlEncodedContent(新字典<字符串,字符串>
{
{ID,1},
{内容, 123}
});
VAR的结果=等待client.PostAsync(API / SomeData /来电,内容);
result.EnsureSuccessStatusCode();
一切正常(至少,调试器停在 PostIncomingData 断点code>)。
既然有字节
阵,我不想序列化的JSON,并要发布它作为二进制数据,以减少网络流量(类似应用程序/八位字节流
)。
这可怎么实现?
我试着 MultipartFormDataContent
玩,不过貌似我只是不明白,怎么 MultipartFormDataContent
将匹配控制器的方法的签名
例如,更换内容是:
VAR内容=新MultipartFormDataContent();
content.Add(新FormUrlEncodedContent(新字典<字符串,字符串> {{ID,1}}));
变种binaryContent =新ByteArrayContent(新字节[] {1,2,3});
binaryContent.Headers.ContentType =新MediaTypeHeaderValue(应用程序/八位字节流);
content.Add(binaryContent,内容);
VAR的结果=等待client.PostAsync(API / SomeData /来电,内容);
result.EnsureSuccessStatusCode();
导致错误415(不支持的媒体类型)。
< DIV CLASS =h2_lin>解决方案
的WebAPI 2.1及以后的支持BSON(二进制JSON)开箱,甚至有一个 MediaTypeFormatter
包含它。这意味着你可以以二进制格式发布您的整个邮件。
如果你想使用它,你需要将其设置为 WebApiConfig
:
公共静态类WebApiConfig
{
公共静态无效的注册(HttpConfiguration配置)
{
config.Formatters.Add(新BsonMediaTypeFormatter());
}
}
现在,您的使用相同的 BsonMediaTypeFormatter
在客户端序列化您的要求:
公共异步任务SendRequestAsync()
{
VAR的客户=新的HttpClient
{
BaseAddress =新的URI(http://www.yourserviceaddress.com);
};
//设置BSON Accept头。
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
新MediaTypeWithQualityHeaderValue(应用程序/ BSON));
变种要求=新SomePostRequest
{
n = 20,
含量=新的字节[] {2,5,7,10}
} ;
// POST使用BSON格式。
MediaTypeFormatter bsonFormatter =新BsonMediaTypeFormatter();
VAR的结果=等待client.PostAsync(API / SomeData /来电,请求bsonFormatter);
result.EnsureSuccessStatusCode();
}
或者,您可以使用Json.NET序列化你的类BSON。然后,指定要使用的应用程序/ BSON作为内容类型:
公共异步任务SendRequestAsync()
{
使用(VAR流=新的MemoryStream())
使用(VAR BSON =新BsonWriter(流))
{
变种jsonSerializer =新jsonSerializer() ;
变种要求=新SomePostRequest
{
n = 20,
含量=新的字节[] {2,5,7,10}
} ;
jsonSerializer.Serialize(BSON,请求);
VAR的客户=新的HttpClient
{
BaseAddress =新的URI(http://www.yourservicelocation.com)
};
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
新MediaTypeWithQualityHeaderValue(应用程序/ BSON));
变种byteArrayContent =新ByteArrayContent(stream.ToArray());
byteArrayContent.Headers.ContentType =新MediaTypeHeaderValue(应用程序/ BSON);
VAR的结果=等待client.PostAsync(
API / SomeData /来电,byteArrayContent);
result.EnsureSuccessStatusCode();
}
}
I want to post this data to Web API server:
public sealed class SomePostRequest
{
public int Id { get; set; }
public byte[] Content { get; set; }
}
Using this code for server:
[Route("Incoming")]
[ValidateModel]
public async Task<IHttpActionResult> PostIncomingData(SomePostRequest requestData)
{
// POST logic here
}
and this - for client:
var client = new HttpClient();
client.BaseAddress = new Uri("http://localhost:25001/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
var content = new FormUrlEncodedContent(new Dictionary<string, string>
{
{ "id", "1" },
{ "content", "123" }
});
var result = await client.PostAsync("api/SomeData/Incoming", content);
result.EnsureSuccessStatusCode();
everything works fine (at least, debugger stops at breakpoint in PostIncomingData
).
Since there is a byte
array, I don't want to serialize it as JSON, and want to post it as binary data to decrease network traffic (something like application/octet-stream
).
How this can be achieved?
I've tried to play with MultipartFormDataContent
, but looks like I just can't understand, how MultipartFormDataContent
will match signature of controller's method.
E.g., replacing content to this:
var content = new MultipartFormDataContent();
content.Add(new FormUrlEncodedContent(new Dictionary<string, string> { { "id", "1" } }));
var binaryContent = new ByteArrayContent(new byte[] { 1, 2, 3 });
binaryContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
content.Add(binaryContent, "content");
var result = await client.PostAsync("api/SomeData/Incoming", content);
result.EnsureSuccessStatusCode();
leads to error 415 ("Unsupported media type").
WebAPI v2.1 and beyond supports BSON (Binary JSON) out of the box, and even has a MediaTypeFormatter
included for it. This means you can post your entire message in binary format.
If you want to use it, you'll need to set it in WebApiConfig
:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Formatters.Add(new BsonMediaTypeFormatter());
}
}
Now, you an use the same BsonMediaTypeFormatter
at the client side to serialize your request:
public async Task SendRequestAsync()
{
var client = new HttpClient
{
BaseAddress = new Uri("http://www.yourserviceaddress.com");
};
// Set the Accept header for BSON.
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/bson"));
var request = new SomePostRequest
{
Id = 20,
Content = new byte[] { 2, 5, 7, 10 }
};
// POST using the BSON formatter.
MediaTypeFormatter bsonFormatter = new BsonMediaTypeFormatter();
var result = await client.PostAsync("api/SomeData/Incoming", request, bsonFormatter);
result.EnsureSuccessStatusCode();
}
Or, you can use Json.NET to serialize your class to BSON. Then, specify you want to use "application/bson" as your "Content-Type":
public async Task SendRequestAsync()
{
using (var stream = new MemoryStream())
using (var bson = new BsonWriter(stream))
{
var jsonSerializer = new JsonSerializer();
var request = new SomePostRequest
{
Id = 20,
Content = new byte[] { 2, 5, 7, 10 }
};
jsonSerializer.Serialize(bson, request);
var client = new HttpClient
{
BaseAddress = new Uri("http://www.yourservicelocation.com")
};
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/bson"));
var byteArrayContent = new ByteArrayContent(stream.ToArray());
byteArrayContent.Headers.ContentType = new MediaTypeHeaderValue("application/bson");
var result = await client.PostAsync(
"api/SomeData/Incoming", byteArrayContent);
result.EnsureSuccessStatusCode();
}
}
这篇关于使用后的字节数组的Web API服务器的HttpClient的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!