使用后的字节数组的Web API服务器的HttpClient [英] Post byte array to Web API server using HttpClient

查看:931
本文介绍了使用后的字节数组的Web API服务器的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 )。



既然有字节阵,我不想序列化的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆