hux*_*ley 10 c# download large-files asp.net-web-api
我创建了两个相同的web api项目,一个在VS 2012中,另一个在VS 2013中,两者都针对4.5 .net框架.这些项目基于Filip W的视频下载教程:http: //www.strathweb.com/2013/01/asynchronously-streaming-video-with-asp-net-web-api/
将教程中的代码复制并粘贴到VS 2012项目中(使用web api 1?)不会产生错误(在我添加正确的'using'语句之后).
但是,当我在VS 2013项目中执行相同的步骤时,我会收到以下两个错误:
错误1
以下方法或属性之间的调用不明确:'PushStreamContent(System.Func<Stream,HttpContent,TransportContext,Task>
,MediaTypeHeaderValue)'和'PushStreamContent(System.Action<System.IO.Stream,HttpContent,TransportContext>
,MediaTypeHeaderValue)'错误
2'void video_stream.Controllers.VideoStream.WriteToStream(System.IO.Stream,System.Net.Http.HttpContent,System.Net.TransportContext)'具有错误的返回类型
所以我的猜测是错误2是真正的问题,因为这段代码:
public async void WriteToStream(Stream outputStream,HttpContent content,TransportContext context){...}
<action>
在web api 1和2之间不再被识别为?? 我真的很困惑,因为我的目标是相同的框架,我似乎无法在如何解决它方面做出直观的飞跃.我尝试更改WriteToStream签名都失败了.
有没有人知道我需要什么才能让PushStreamContent接受web api 2或VS 2013中的WriteToStream或新的C#或者这段代码的差异在哪里?
Bil*_*man 14
PushStreamContent构造函数的签名已更改.其onStreamAvailable参数是Action或Func泛型类型.问题是编译器不知道要绑定哪种类型.
因此,要解决错误,请将streamAvailableHandler强制转换为Action:
response.Content = new PushStreamContent((Action<Stream, HttpContent, TransportContext>)streamAvailableHandler);
Run Code Online (Sandbox Code Playgroud)
处理程序方法将是:
private void streamAvailableHandler(Stream stream, HttpContent content, TransportContext context) {
...write to stream
}
Run Code Online (Sandbox Code Playgroud)
我不确定这是否是Web API中的错误,我们将对其进行调查.同时您可以尝试以下解决方法:
response.Content = new PushStreamContent(async (Stream outputStream, HttpContent content, TransportContext context) =>
{
try
{
var buffer = new byte[65536];
using (var video = File.Open(filename, FileMode.Open, FileAccess.Read))
{
var length = (int)video.Length;
var bytesRead = 1;
while (length > 0 && bytesRead > 0)
{
bytesRead = video.Read(buffer, 0, Math.Min(length, buffer.Length));
await outputStream.WriteAsync(buffer, 0, bytesRead);
length -= bytesRead;
}
}
}
finally
{
outputStream.Close();
}
});
Run Code Online (Sandbox Code Playgroud)
注意:我对代码进行了另一次更改(删除了catch块)以允许传播异常.这是为了让您的客户知道服务中发生了一些错误,否则他们会认为一切顺利.
这是 C# 规范的一个已知问题。看看这个SO问题 - Compiler Ambigeous incalling error - Anonymous method and method group with Func<> or Action
当我们引入这个返回任务的重载时,我们确实意识到这是一个源代码级别的破坏性更改(尽管它不会破坏二进制兼容性)。我们仍然继续进行更改,因为不修复它会导致更多问题。
关于如何修复它,您有两种选择 -
您可以使用显式强制转换,如下所示,
response.Content = new PushStreamContent((Action)video.WriteToStream, new MediaTypeHeaderValue("video/"+ext));
顺便说一句,请小心使用该async void
方法。我建议你将其签名更改为
public async Task WriteToStream(Stream outputStream, HttpContent content, TransportContext context)
Run Code Online (Sandbox Code Playgroud)