使用VS 2012,ASP.NET Web API 4.0,适用于4.0的Web API客户端库 我创建了一个“hello world”控制器,并且得到了简单的get / post工作。但是,我无法发布文件。
我正在通过HttpClient客户端访问该服务,但无论我尝试了什么,我都无法获得一个简单的HTML页面(发布文件)。但是,这有它自己的问题(并且内容总是遇到IsMimeMultipartContent,而我的HttpClient没有);我想让HttpClient现在正常工作。客户端流在文件中很好(我可以看到长度很好),但在服务器上,ReadAsStreamAsync内的流的长度为0.此外,HttpContext.Current.Request.Files计数为0(即使是这样的情况)从HTML文件帖子中点击。)
这是控制器:
public class ImportController : ApiController
{
public HttpResponseMessage Post()
{
WriteFile( HttpContext.Current.Server.MapPath( "~/killme.xml" ) );
return new HttpResponseMessage( HttpStatusCode.Accepted );
}
private void WriteFile( string filePath )
{
Request.Content.ReadAsStreamAsync().ContinueWith( task =>
{
try
{
var requestStream = task.Result;
var fileStream = File.Create( filePath );
requestStream.CopyTo( fileStream );
fileStream.Close();
requestStream.Close();
}
catch
{
; // TBD
}
} );
}
}
这是客户:
var client = new HttpClient();
client.PostAsync( "http://localhost:52800/api/Import", ReadFile() ).ContinueWith( ( task ) =>
{
Console.WriteLine( task.Result.StatusCode.ToString() );
client.Dispose();
} );
private static StreamContent ReadFile()
{
var fileBytes = File.ReadAllBytes( @"C:\temp\killme.xml" );
var ms = new MemoryStream( fileBytes.Length );
ms.Write( fileBytes, 0, fileBytes.Length );
// Can't put this in using; don't know how to dispose
return new StreamContent( ms );
}
答案 0 :(得分:1)
我认为你唯一的错误就是忘记在将内存流传递给StreamContent之前重置内存流的位置。但是,我更喜欢创建一个新的派生HttpContent类,专门用于处理发送文件。
使用此类,您的代码看起来像
var client = new HttpClient();
var content = new FileContent(@"C:\temp\killme.xml");
client.PostAsync( "http://localhost:52800/api/Import", content ).ContinueWith( ( task ) =>
{
Console.WriteLine( task.Result.StatusCode.ToString() );
client.Dispose();
} );
E.g。
public class FileContent : HttpContent
{
private const int DefaultBufferSize = 1024 * 64;
private readonly string _fileName;
private readonly FileInfo _fileInfo;
public FileContent(string fileName)
{
if (string.IsNullOrWhiteSpace(fileName))
{
throw new ArgumentNullException("fileName");
}
_fileInfo = new FileInfo(fileName);
if (!_fileInfo.Exists)
{
throw new FileNotFoundException(string.Empty, fileName);
}
_fileName = fileName;
}
protected override bool TryComputeLength(out long length)
{
length = _fileInfo.Length;
return true;
}
private FileStream _FileStream;
protected override Task SerializeToStreamAsync(Stream stream, TransportContext context)
{
_FileStream = new FileStream(_fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite,
DefaultBufferSize,
FileOptions.Asynchronous | FileOptions.SequentialScan);
_FileStream.CopyTo(stream);
var tcs = new TaskCompletionSource<object>();
tcs.SetResult(null);
return tcs.Task;
}
protected override void Dispose(bool disposing)
{
if (_FileStream != null)
{
_FileStream.Dispose();
_FileStream = null;
}
base.Dispose(disposing);
}
}
}