- 今天接到个需求就是客户端上传文件到Aliyun_oss,因为之前已经使用使用过OSS的sdk 上传过文件本以为是件很容易的事。(本以为。。淦)
- 这里 我贴上一个Aliyun_oss的介绍网站。里面有阿里云Oss对接的详细说明。https://help.aliyun.com/document_detail/32006.html
- OK!事情是这样的。我首先去网络上百度了下C#客户端通过上传文件的各种代码,试了好多他一直在报一个错误: MalformedPOSTRequest
- 服务层直接返回400
- 错误消息:The body of your POST request is not well-formed multipart/form-data.
错误原因:PostObject请求中表单域格式不符合要求。
解决方案:遵循表单域格式要求
然后就到Aliyun_OSS错误码对照哪里找相关的错误解决方案
以上是老马给出的解释。细心的我发现了马哥给提供了个c#demo
OK!看demo,上demo
var boundary = "9431149156168";
var webRequest = (HttpWebRequest)WebRequest.Create(requestUri);
webRequest.Timeout = -1;
webRequest.Method = "POST";
webRequest.ContentType = "multipart/form-data; boundary=" + boundary;
var objectName = "xxx";
var signature = ComputeSignature(accessKeySecret, encPolicy);
var fileContent = "这是一行简单的测试文本";
var requestBody = "--" + boundary + "\r\n"
+ "Content-Disposition: form-data; name=\"key\"\r\n"
+ "\r\n" + "user/eric/${filename}" + "\r\n"
+ "--" + boundary + "\r\n"
+ "Content-Disposition: form-data; name=\"bucket\"\r\n"
+ "\r\n" + bucketName + "\r\n"
+ "--" + boundary + "\r\n"
+ "Content-Disposition: form-data; name=\"x-oss-meta-tag\"\r\n"
+ "\r\n" + "dummy_etag_xxx" + "\r\n"
+ "--" + boundary + "\r\n"
+ "Content-Disposition: form-data; name=\"OSSAccessKeyId\"\r\n"
+ "\r\n" + accessKeyId + "\r\n"
+ "--" + boundary + "\r\n"
+ "Content-Disposition: form-data; name=\"policy\"\r\n"
+ "\r\n" + encPolicy + "\r\n"
+ "--" + boundary + "\r\n"
+ "Content-Disposition: form-data; name=\"Signature\"\r\n"
+ "\r\n" + signature + "\r\n"
+ "--" + boundary + "\r\n"
+ "Content-Disposition: form-data; name=\"file\"; filename=\"" + objectName + "\"\r\n\r\n"
+ fileContent + "\r\n"
+ "--" + boundary + "\r\n"
+ "Content-Disposition: form-data; name=\"submit\"\r\n\r\nUpload to OSS\r\n"
+ "--" + boundary + "--\r\n";
webRequest.ContentLength = requestBody.Length;
using (var ms = new MemoryStream())
{
var writer = new StreamWriter(ms, new UTF8Encoding());
try
{
writer.Write(requestBody);
writer.Flush();
ms.Seek(0, SeekOrigin.Begin);
webRequest.ContentLength = ms.Length;
using (var requestStream = webRequest.GetRequestStream())
{
ms.WriteTo(requestStream);
}
}
finally
{
writer.Dispose();
}
}
var response = webRequest.GetResponse() as HttpWebResponse;
if (response.StatusCode == HttpStatusCode.NoContent)
{
Console.WriteLine("Post object succeed!");
}
以上是马哥给提供的demo实例。但是这demo。没有具体上传文件的模块。他的文件就是这一句话,当时内心就EMO…
然后就开始参考网上的代码,看看他们是怎么传输文件的。但是还是一直报
MalformedPOSTRequest 。。400错误。很长时间都没有找到原因。然后我就只能找下场外求助了。在这里我要特别感谢下我的Friend(小海)。
这些都要仔细排查,如果你们也遇到了我这样的问题。
好了,我也贴一下我的代码
/// <summary>
/// 请求上传图片到阿里云
/// </summary>
/// <param name="url">上传地址</param>
/// <param name="filepath">本地文件路径</param>
/// <param name="dic">上传的数据信息</param>
/// <returns></returns>
public static bool UploadFilesToRemoteUrl(string url, string filepath, Dictionary<string, string> dic)
{
try
{
string boundary = DateTime.Now.Ticks.ToString("x");
byte[] boundarybytes = System.Text.Encoding.UTF8.GetBytes("--" + boundary + "\r\n");
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
request.ContentType = "multipart/form-data; boundary=" + boundary;
Stream rs = request.GetRequestStream();
var endBoundaryBytes = System.Text.Encoding.UTF8.GetBytes("--" + boundary + "--\r\n");
string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"\r\n" + "\r\n" + "{1}" + "\r\n";
if (dic != null)
{
foreach (string key in dic.Keys)
{
rs.Write(boundarybytes, 0, boundarybytes.Length);
string formitem = string.Format(formdataTemplate, key, dic[key]);
byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem);
rs.Write(formitembytes, 0, formitembytes.Length);
}
}
string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n\r\n";
{
rs.Write(boundarybytes, 0, boundarybytes.Length);
var header = string.Format(headerTemplate, "file", Path.GetFileName(filepath));
var headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
rs.Write(headerbytes, 0, headerbytes.Length);
using (var fileStream = new FileStream(filepath, FileMode.Open, FileAccess.Read))
{
var buffer = new byte[1024];
var bytesRead = 0;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
{
rs.Write(buffer, 0, bytesRead);
}
}
var cr = Encoding.UTF8.GetBytes("\r\n");
rs.Write(cr, 0, cr.Length);
}
rs.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);
var response = request.GetResponse() as HttpWebResponse;
if (response.StatusCode == HttpStatusCode.OK)
{
return true;
}
}
catch (Exception e)
{
LogHelper.Error("文件上传Aliyun异常,淦", e);
}
return false;
}
别问我为什么写完文件还要加个换行符,问的话你就去掉试试(试试就试试emo…)
加油西红柿!!!
版权声明:本文为qq_36222985原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。