.NET Core HttpClient调用腾讯云对象存储Web API的"ERROR_CGI_PARAM_NO_SUCH_OP"问题
开门见山地说一下问题的原因:调用 web api 时请求头中多了双引号,请求体中少了双引号。
腾讯云提供的对象存储(COS)C# SDK 是基于 .NET Framework 用 WebRequest 实现的,我们直接将这个实现迁移到 .NET Core 是可以正常调用,但后来我们基于 HttpClient 实现,调用 web api 时总是返回 "ERROR_CGI_PARAM_NO_SUCH_OP" 错误。
用 Wireshark 抓包后发现,基于 WebRequest 的实现的请求包开头比基于 HttpClient 的实现多了个 "Preamble: 0d0a"。
1)基于 WebRequest 的实现

2)基于 HttpClient 的实现

检查代码后发现,在构建 multipart/form-data 时,腾讯云官方基于 WebRequest 的实现是这样构建数据包的开头的:
var boundary = "---------------" + DateTime.Now.Ticks.ToString("x");
var beginBoundary = Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");
我们基于 HttpClient 的实现用的是 MultipartFormDataContent :
var boundary = "---------------" + DateTime.Now.Ticks.ToString("x");
var data = new MultipartFormDataContent(boundary);
前者构建的 Multipart 数据包比后者多出了 \r\n (回车换行),而 0d0a 正是 \r\n 的 ASCII 码。根据 Multipart Content-Type 规范,这个多出来的 \r\n 是多余的,所以被解析为 "Preamble: 0d0a" 。
于是修改基于 HttpClient 的实现,也加上这个额外的 \r\n :
var ms = new MemoryStream();
var bytes = Encoding.UTF8.GetBytes("\r\n");
ms.Write(bytes, , bytes.Length);
(await data.ReadAsStreamAsync()).CopyTo(ms);
ms.Position = ;
var sc = new StreamContent(ms);
sc.Headers.ContentType = data.Headers.ContentType;
request.Content = sc;
但加上后依然是"ERROR_CGI_PARAM_NO_SUCH_OP"错误(实际上不加开头的 \r\n 也没关系,问题与这个无关)。
继续仔细对比抓包,发现 HttpClient 的实现中 form-data 部署少了双引号,比如 name=op ,基于 WebRequest 的实现用的是 name="op"

但加上后依旧是"ERROR_CGI_PARAM_NO_SUCH_OP"错误。
再继续对比抓包,发现 HttpClient 的实现这 Content-Type 中比 WebRequest 的实现多了2个双引号
1) Content-Type: multipart/form-data; boundary="---------------8d5289300ea3a0d"
2) Content-Type: multipart/form-data; boundary=---------------8d527aeed341201
去找这2个双引号之后,问题终于解决了。
最终基于 .NET Core HttpClient 的实现代码如下("Preamble: 0d0a"没有影响,不需要加):
var request = new HttpRequestMessage(HttpMethod.Post, url);
request.Headers.Authorization = new AuthenticationHeaderValue("Authorization", signature); var boundary = "---------------" + DateTime.Now.Ticks.ToString("x");
var data = new MultipartFormDataContent(boundary);
data.Add(new ByteArrayContent(Encoding.UTF8.GetBytes("upload")), "\"op\""); var streamContent = new StreamContent(uploadStream);
streamContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
Name = "\"fileContent\"",
FileName = "\"" + fileName + "\""
};
streamContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
data.Add(streamContent); data.Headers.Remove("Content-Type");
data.Headers.Add("Content-Type", "multipart/form-data; boundary=" + boundary);
request.Content = data;
var response = await _httpClient.SendAsync(request);
var json = await response.Content.ReadAsStringAsync();
.NET Core HttpClient调用腾讯云对象存储Web API的"ERROR_CGI_PARAM_NO_SUCH_OP"问题的更多相关文章
- php 腾讯云 对象存储V5版本 获取返回的上传文件的链接方法
腾讯云 对象存储V5版本 文档地址:https://github.com/tencentyun/cos-php-sdk-v5 调用简单文件上传方法: 返回数据如下 Array ( [data:prot ...
- Laravel项目使用腾讯云对象存储上传图片(cos-php-sdk-v5版本)
为了加快网站访问速度.降低网站负载,现在越来越多的网站选择把图片等静态文件放在云上,这里介绍一下腾讯云对象存储在Laravel项目中的使用 1.申请腾讯云对象存储.创建Bucket.获取APPID等参 ...
- 微信小程序基于腾讯云对象存储的图片上传
在使用腾讯云对象存储之前,公司一直使用的是传统的FTP的上传模式,而随着用户量的不断增加,FTP所暴露出来的问题也越来越多,1.传输效率低,上传速度慢.2.时常有上传其他文件来攻击服务器,安全上得不到 ...
- Docsify+腾讯云对象存储 COS,一键搭建云上静态博客
最近一直在想如何利用 COS 简化静态博客的搭建过程.搜了很多的静态博客搭建过程,发现大部分的静态博客都要通过编译才能生成静态页面.功夫不负有心人,终于让我找到了一个超简洁博客的搭建方法. 效果预览 ...
- 腾讯云--对象存储cos绑定自定义域名
1.登录腾讯云控制台,找到对象存储一栏 2.选择一个你想绑定域名的存储桶 3.进入你选择的存储桶,点击域名管理 4.选择自定义源站域名.在域名处填写你要设置的自定义域名,在源站类型处选择静态网站源站, ...
- 腾讯云对象存储COS新品发布——智能分层存储,自动优化您的存储成本
近日,腾讯云正式发布对象存储新品--智能分层存储,能够根据用户数据的访问模式,自动地转换数据的冷热层级,为用户提供与标准存储一致的低延迟和高吞吐的产品体验,同时具有更低的存储成本. 熟悉数据存储的用户 ...
- Python调用腾讯云API,实现人脸年龄变化
网上看到了一个教程,调用腾讯云的人脸识别api和修改年龄api来实现模拟人物不同年龄的面貌 但是大多数教程的代码都是想同的,估计是抄袭哪个人的关键是执行不了 刚好周杰伦马上要发新专辑了,小改一下,拿杰 ...
- 谈谈调用腾讯云【OCR-通用印刷体识别】Api踩的坑
一.写在前面 最近做项目需要用到识别图片中文字的功能,本来用的Tesseract这个写的,不过效果不是很理想. 随后上网搜了一下OCR接口,就准备使用腾讯云.百度的OCR接口试一下效果.不过这个腾讯云 ...
- C# 调用腾讯云接口获取视频基本信息
做项目需要上传视频,获取时长,上传教程很多,获取信息很少,官方只有一条请求地址. 找了好久,都没有说这个请求地址怎么用.最后发现需要调用腾讯云SDK 官方地址:https://github.com/Q ...
随机推荐
- OpenCV 学习笔记 04 深度估计与分割——GrabCut算法与分水岭算法
1 使用普通摄像头进行深度估计 1.1 深度估计原理 这里会用到几何学中的极几何(Epipolar Geometry),它属于立体视觉(stereo vision)几何学,立体视觉是计算机视觉的一个分 ...
- Effective Java 第三版——56. 为所有已公开的API元素编写文档注释
Tips 书中的源代码地址:https://github.com/jbloch/effective-java-3e-source-code 注意,书中的有些代码里方法是基于Java 9 API中的,所 ...
- 第三部分:Android 应用程序接口指南---第三节:应用程序资源---第一章 资源提供
第1章 资源提供 你应该经常外部化你应用程序代码中的资源,比如图片.字符串等,这样有利于你独立处理这些资源.你也应该根据特定的设备配置提供一些可替代的资源,并且把他们分组保存在指定的路径名下.运行时, ...
- [docker]docker网络-直接路由模式
linux namespace连接参考: http://www.cnblogs.com/iiiiher/p/8057922.html docker网络-直接路由模式 参考: https://www.y ...
- KVM上如何让虚拟机支持虚拟化(kvm虚拟化的嵌套)
http://blog.csdn.net/swimming_in_it_/article/details/53320141http://blog.csdn.net/wickedglory/articl ...
- 读取Excel二进制写入DB,并从DB中读取生成Excel文件
namespace SendMailSMSService { class Program { static void Main(string[] args) { var connString = Sq ...
- Python测试DB2连通性
Python测试数据库连通性: #!/usr/bin/python27 #encoding: utf-8 import ibm_db import os import sys def find_db( ...
- PHP优化——从语言到业务
经常有人说php速度慢,其实语言层面的速度差异和实际的业务相比,不在一个数量级. 业务的瓶颈往往在于io,而不是CPU. 0x0 语言 语法 单引号和双引号 单引号不解析字符串里的变量,而双引号会解析 ...
- Repeater数据控件的两个重要事件ItemDataBound 和 ItemCommand
1 ItemDataBound:数据绑定的时候(正在进行时)发生. 2 ItemCommand :用来响应Item模板中的控件的事件. 如下代码 aspx代码: [html] view plain c ...
- 不平衡学习 Learning from Imbalanced Data
问题: ICC警情数据分类不均,30+分类,最多的分类数据数量1w+条,只有10个类别数量超过1k,大部分分类数量少于100条. 解决办法: 下采样:通过非监督学习,找出每个分类中的异常点,减少数据. ...