服务器装了D盾。部署了上传文件的接口。用PostMan工具调用可以正常调用。用C#调用提示403被拦截。
于是只能用Fiddler进行抓包比较两个请求的差距
PostMan的请求
C#的请求
找到问题点就是引号有问题。进行处理跟PostMan一致即可完成文件上传
1.封装方法
/// <summary>
/// 使用multipart/form-data方式上传文件及其他数据
/// </summary>
/// <param name="hea eders">请求头参数</param>
/// <param name="nameValueCollection">键值对参数</param>
/// <param name="fileCollection">文件参数:参数名,文件路径</param>
/// <returns>接口返回结果</returns>
public static object PostMultipartFormData(string url, Dictionary<string, string> headers, NameValueCollection nameValueCollection, NameValueCollection fileCollection)
{
using (var httpClient = new HttpClient())
{
foreach (var item in headers)
{
httpClient.DefaultRequestHeaders.Add(item.Key, item.Value);
}
var boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
var contentType = "multipart/form-data; boundary=" + boundary;
var content = new MultipartFormDataContent(boundary);
//处理文件内容
string[] fileKeys = fileCollection.AllKeys;
foreach (string key in fileKeys)
{
byte[] bmpBytes = File.ReadAllBytes(fileCollection[key]);
var fileContent = new ByteArrayContent(bmpBytes);//填充文件字节
fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
Name = "\"" + key + "\"",
FileName = "\"" + Path.GetFileName(fileCollection[key]) + "\""
};
fileContent.Headers.ContentType = new MediaTypeHeaderValue("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
content.Add(fileContent);
}
// 键值对参数
string[] allKeys = nameValueCollection.AllKeys;
foreach (string key in allKeys)
{
var dataContent = new ByteArrayContent(Encoding.UTF8.GetBytes(nameValueCollection[key]));
dataContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
Name = "\"" + key + "\""
};
content.Add(dataContent);
}
httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", contentType);
var boundaryValue = content.Headers.ContentType.Parameters.Single(p => p.Name == "boundary");
boundaryValue.Value = boundaryValue.Value.Replace("\"", String.Empty);
var result = httpClient.PostAsync(url, content).Result;//post请求
string data = result.Content.ReadAsStringAsync().Result;
return data;//返回操作结果
}
}
2.方法调用
using var httpClient = new HttpClient();
Dictionary<string, string> headers = new Dictionary<string, string>();
//键值对参数
NameValueCollection nameValueCollection = new NameValueCollection();
//文件参数
NameValueCollection fileCollection = new NameValueCollection();
fileCollection.Add("file", "C:\\Users\\Admin\\Desktop\\aaa\\150321.xlsx");//文件
//除file文件外的其他参数
nameValueCollection.Add("savePath", "xxxx");
object result = PostMultipartFormData("url", headers, nameValueCollection, fileCollection);