C# webapi接口传输byte[]数据,报错:415 Unsupported Media Type

最近需要做上传文件操作。 由于历史原因,以前的接口使用了这样的入参:

 代码如下:

/// <summary>
/// 上传文件
/// </summary>
[HttpPost]
public Result<UploadImageResult> UploadFile(byte[] bytes, string extName, string fromUri)
{
    //业务代码
}

这个接口是一个POST请求的接口,调用接口之前,需要先将文件转换成文件流,再转换成byte数组的进行上传。

上传时调用此接口,然后返回这个文件的线上地址。

第一个入参是byte[]数组,第二、第三个入参是string类型的。

之前通过包装一层转发调用的,所以没有调用的实例。

最近需要通过Http直接调用,于是想了各种办法,但是一直报错:

415 Unsupported Media Type

各种测试期间,还报错过:

Unable to translate bytes [FF] at index 35 from specified code page to Unicode

参考了

1.   c# - Post byte array to Web API server using HttpClient - Stack Overflow

2. 

asp.net - Unable to translate bytes [FC] at index 35 from specified code page to Unicode - Stack Overflow

这些里面的方法,但是也没有解决。

尝试了各种改动,包括:

Content-Type 改为 application/octet-stream

Content-Type 改为 application/bson

Content-Type 改为 multipart/form-data

上面的改动也对应这Parameters的各种改动,都失败了。

还有这样的(失败案例,不过这是multipart/form-data传数据的正确用法):

byte[] fileBytes = new byte[] { 1, 2 };
string extName = "jpg";
string fromUri = "test";
var uploadUrl = "http://localhost:8101/Upload/UploadFile";

try
{
    HttpClient InternalHttpClient = new HttpClient();
    var strBoundary = DateTime.Now.Ticks.ToString("x"); //分隔符
    var resultContent = new MultipartFormDataContent(strBoundary);

    var fileByteArrayContent = new ByteArrayContent(fileBytes);
    fileByteArrayContent.Headers.ContentType = new MediaTypeHeaderValue("application/x-jpg");
    fileByteArrayContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data") { Name = "bytes", FileName = "test.jpg" };
    resultContent.Add(fileByteArrayContent);

    var valueBytes1 = Encoding.UTF8.GetBytes(extName);
    var byteArray1 = new ByteArrayContent(valueBytes1);
    byteArray1.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data") { Name = "extName" };
    resultContent.Add(byteArray1);

    var valueBytes2 = Encoding.UTF8.GetBytes(fromUri);
    var byteArray2 = new ByteArrayContent(valueBytes2);
    byteArray2.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data") { Name = "fromUri" };
    resultContent.Add(byteArray2);

    var message = new HttpRequestMessage(HttpMethod.Post, uploadUrl);
    message.Content = resultContent;
    var responseMessage = InternalHttpClient.SendAsync(message).Result;
    using (HttpContent ResponseBytes = responseMessage.Content)
    {
        var content = ResponseBytes.ReadAsStringAsync().Result;
    }

}
catch (Exception ex)
{
    string exstr = ex.Message;
}

上面这个失败的原因是:

bytes虽然我传输的是文件,但是bytes本身不是文件,所以不能把含有文件数据的bytes当做文件看,而是要把它当做一个json来看,只不过这个json是一个纯数字的json数组。

然后问了公司大佬,给我一个postman的调用示例,才知道原来自己的方向一直是错的。

由于上面的接口定义了三个参数,都没有经过类封装,所以这个接口直接就是三个参数的,接口默认是将bytes这个参数作为body主体的。 所以bytes传值时其实是json格式的一个body。

而extName和fromUri两个参数因为没有定义是什么参数类型,也没有封装到封装到类里,所以就作为url传值了。

所以在postman这样的工具传值时,应该是这样的:

 这样传值,然后就成功了。

那么知道上面的原因之后,就比较好操作了

通过HttpClient请求是这样的:

byte[] fileBytes = new byte[] { 1, 2 };
string extName = "jpg";
string fromSource = "test";
var uploadUrl = "http://localhost:8101/Upload/UploadFile";
try
{
    var newUrl = $"{uploadUrl}?extName={extName}&fromUri={fromUri}";
    var client = new HttpClient();
    HttpContent content = new StringContent(JsonConvert.SerializeObject(fileBytes));
    content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
    HttpResponseMessage response = client.PostAsync(newUrl, content).Result;
    response.EnsureSuccessStatusCode();
    string con = response.Content.ReadAsStringAsync().Result;
}
catch (Exception ex)
{
    string exstr = ex.Message;
}

通过RestClient请求是这样的:(需要引用RestSharp.dll)

byte[] fileBytes = new byte[] { 1, 2 };
string extName = "jpg";
string fromSource = "test";
var uploadUrl = "http://localhost:8101/Upload/UploadFile";
try
{
    RestResponse Rsp;
    var newUrl = $"{uploadUrl}?extName={extName}&fromUri={fromUri}";
    using (var client = new RestClient(uploadUrl))
    {
        var Req = new RestRequest(newUrl, Method.Post);
        Req.AddHeader("Content-Type", "application/json");
        Req.AddBody(JsonConvert.SerializeObject(fileBytes));
        Rsp = client.ExecuteAsync(Req).Result;
    }
}
catch (Exception ex)
{
    string exstr = ex.Message;
}

然后传值就成功了。

没找准问题所在,连搜答案都是错的。

要向正确的人问正确的问题,才能得到正确的答案。

一把辛酸泪,在此做个记录

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

willgon123

谢谢打赏,我将再接再厉!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值