Asp.net web api Can';t从HttpClient向ASP.NET Web API发布文件
使用VS 2012、ASP.NET Web API 4.0、适用于4.0的Web API客户端库。Asp.net web api Can';t从HttpClient向ASP.NET Web API发布文件,asp.net-web-api,Asp.net Web Api,使用VS 2012、ASP.NET Web API 4.0、适用于4.0的Web API客户端库。 我创建了一个“hello world”控制器,并实现了简单的get/post工作。但是,我不能发布文件 我正在通过HttpClient客户端访问该服务,但无论我尝试了什么,我都无法使用简单的HTML页面(发布文件)。然而,这也有它自己的一系列问题(内容总是遇到IsMimeMultipartContent,而我的HttpClient没有);我现在只想让一个HttpClient工作。文件中的客户端流很
我创建了一个“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 );
}
我认为您唯一的错误是在将内存流传递给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();
} );
例如
公共类FileContent:HttpContent
{
private const int DefaultBufferSize=1024*64;
私有只读字符串\u文件名;
私有只读文件信息_FileInfo;
公共文件内容(字符串文件名)
{
if(string.IsNullOrWhiteSpace(文件名))
{
抛出新的ArgumentNullException(“文件名”);
}
_fileInfo=新的fileInfo(文件名);
如果(!\u fileInfo.Exists)
{
抛出新的FileNotFoundException(string.Empty,fileName);
}
_fileName=文件名;
}
受保护的覆盖布尔TryComputeLength(out long length)
{
长度=_fileInfo.length;
返回true;
}
私有文件流\u文件流;
受保护的重写任务SerializeToStreamAsync(流、TransportContext上下文)
{
_FileStream=新FileStream(_fileName,FileMode.Open,FileAccess.Read,FileShare.ReadWrite,
默认缓冲区大小,
FileOptions.Asynchronous | FileOptions.SequentialScan);
_CopyTo(流);
var tcs=new TaskCompletionSource();
tcs.SetResult(空);
返回tcs.Task;
}
受保护的覆盖无效处置(布尔处置)
{
如果(_FileStream!=null)
{
_Dispose();
_FileStream=null;
}
基地。处置(处置);
}
}
}
我认为您唯一的错误是在将内存流传递给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();
} );
例如
公共类FileContent:HttpContent
{
private const int DefaultBufferSize=1024*64;
私有只读字符串\u文件名;
私有只读文件信息_FileInfo;
公共文件内容(字符串文件名)
{
if(string.IsNullOrWhiteSpace(文件名))
{
抛出新的ArgumentNullException(“文件名”);
}
_fileInfo=新的fileInfo(文件名);
如果(!\u fileInfo.Exists)
{
抛出新的FileNotFoundException(string.Empty,fileName);
}
_fileName=文件名;
}
受保护的覆盖布尔TryComputeLength(out long length)
{
长度=_fileInfo.length;
返回true;
}
私有文件流\u文件流;
受保护的重写任务SerializeToStreamAsync(流、TransportContext上下文)
{
_FileStream=新FileStream(_fileName,FileMode.Open,FileAccess.Read,FileShare.ReadWrite,
默认缓冲区大小,
FileOptions.Asynchronous | FileOptions.SequentialScan);
_CopyTo(流);
var tcs=new TaskCompletionSource();
tcs.SetResult(空);
返回tcs.Task;
}
受保护的覆盖无效处置(布尔处置)
{
如果(_FileStream!=null)
{
_Dispose();
_FileStream=null;
}
基地。处置(处置);
}
}
}
将我的流重置为0不起作用,但您的代码起作用;小提示:结尾有额外的卷曲。重置我的流确实有效,我很困惑,因为我不能多次运行这两个方法(除非我重新启动IIS Express)。(在您的代码中)没有任何内容未被屏蔽;不知道第二次运行时请求流长度为0的原因…将我的流重置为0不起作用,但您的代码起作用;小提示:结尾有额外的卷曲。重置我的流确实有效,我很困惑,因为我不能多次运行这两个方法(除非我重新启动IIS Express)。(在您的代码中)没有任何内容未被屏蔽;不知道第二次运行时请求流长度为0的原因。。。