我想在API服务器之间模拟传输文件。 首先,我创建了一个接收上传文件的API。 并使用Postman成功上传文件。 这是接收的代码。
[AllowAnonymous]
[HttpPost]
[Route("api/data/UploadFile")]
public IHttpActionResult UploadFile()
{
if (HttpContext.Current.Request.Files.AllKeys.Any())
{
var httpPostedFile = HttpContext.Current.Request.Files["UploadedImage"];
if (httpPostedFile != null)
{
var fileSavePath = Path.Combine(HttpContext.Current.Server.MapPath("~/images"), "Capture1.PNG");
httpPostedFile.SaveAs(fileSavePath);
}
}
return Ok("SUCCESS");
}
现在,我想使用此代码从另一个API使用WebRequest上传文件。
[AllowAnonymous]
[HttpGet]
[Route("api/data/TestUpload")]
public IHttpActionResult TestUpload()
{
string formdataTemplate = "Content-Disposition: form-data; filename=\"{0}\";\r\nContent-Type: image/png\r\n\r\n";
string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
byte[] boundarybytes = Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://localhost/iisapi/api/data/UploadFile");
request.ServicePoint.Expect100Continue = false;
request.Method = "POST";
request.ContentType = "multipart/form-data; boundary=" + boundary;
string filePath = Path.Combine(HttpContext.Current.Server.MapPath("~/images"), "Capture2.PNG");
using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
{
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(boundarybytes, 0, boundarybytes.Length);
string formitem = string.Format(formdataTemplate, "UploadedImage");
byte[] formbytes = Encoding.UTF8.GetBytes(formitem);
requestStream.Write(formbytes, 0, formbytes.Length);
byte[] buffer = new byte[fileStream.Length];
int bytesLeft = 0;
while ((bytesLeft = fileStream.Read(buffer, 0, buffer.Length)) > 0)
{
requestStream.Write(buffer, 0, bytesLeft);
}
}
}
try
{
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) { }
return Ok("SUCCESS");
}
catch (Exception ex)
{
throw;
}
}
如果我拨打TestUpload
API,则会成功进入UploadFile
功能。但是,在使用此代码HttpContext.Current.Request.Files.AllKeys.Any()
检查请求中是否存在文件时,它将返回false。请求中没有文件。我在这里缺少什么?
谢谢。
答案 0 :(得分:0)
public virtual async Task<TResponse> PostFileAsync<TResponse>(string url, Dictionary<string, string> headers, FileResponse fileData, IProgress<ProgressCompleted> progress, CancellationToken token)
{
using (var request = new HttpRequestMessage(HttpMethod.Post, url))
{
List<byte> byteData = new List<byte>();
Action<double> actionProgress = null;
if (progress != null)
{
actionProgress = (progressValue) => progress.Report(new ProgressCompleted(progressValue));
}
var boundary = string.Format("----------{0:N}", Guid.NewGuid());
var multiContent = new MultipartFormDataContent(boundary);
foreach (var customHeader in headers)
{
request.Headers.Add(customHeader.Key, customHeader.Value);
}
var content = new ByteArrayContent(fileData.FileData);
content.Headers.TryAddWithoutValidation("Content-Type", fileData.FileType);
multiContent.Add(content, "file", fileData.FileName);
request.Content = multiContent;
using (var response = await Client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, token).ConfigureAwait(false))
{
var total = response.Content.Headers.ContentLength.HasValue ? response.Content.Headers.ContentLength.Value : -1L;
var canReportProgress = total != -1 && progress != null;
if (!response.IsSuccessStatusCode)
RestExceptionHandlerService.Handle(response.StatusCode);
using (var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false))
{
var totalRead = 0L;
var buffer = new byte[BufferSize];
var isMoreToRead = true;
do
{
token.ThrowIfCancellationRequested();
var read = await stream.ReadAsync(buffer, 0, buffer.Length, token).ConfigureAwait(false);
if (read == 0)
{
isMoreToRead = false;
}
else
{
if (read != buffer.Length)
{
byte[] cpArray = new byte[read];
Array.Copy(buffer, cpArray, read);
byteData.AddRange(cpArray);
}
else {
byteData.AddRange(buffer);
}
totalRead += read;
if (canReportProgress)
{
progress.Report(new ProgressCompleted((double)totalRead / total * 100));
}
}
} while (isMoreToRead);
}
//TODO: server returns just string NOT Json
return (TResponse)(object) Encoding.UTF8.GetString(byteData.ToArray(), 0, byteData.Count);
}
}
}