C# web api和;网络api 2?

C# web api和;网络api 2?,c#,asp.net-web-api,download,large-files,C#,Asp.net Web Api,Download,Large Files,我创建了两个相同的web api项目,一个在VS 2012,另一个在VS 2013,都是针对4.5.net框架的。这些项目基于Filip W的视频下载教程,可在以下位置找到: 将教程中的代码复制粘贴到VS 2012项目中(使用web api 1?)不会产生错误(在我添加正确的“使用”语句之后) 然而,当我在VS 2013项目中遵循相同的步骤时,我会出现以下两个错误: 错误1 以下方法或属性之间的调用不明确: 'PushStreamContent(System.Func,MediaTypeHea

我创建了两个相同的web api项目,一个在VS 2012,另一个在VS 2013,都是针对4.5.net框架的。这些项目基于Filip W的视频下载教程,可在以下位置找到:

将教程中的代码复制粘贴到VS 2012项目中(使用web api 1?)不会产生错误(在我添加正确的“使用”语句之后)

然而,当我在VS 2013项目中遵循相同的步骤时,我会出现以下两个错误:

错误1
以下方法或属性之间的调用不明确: 'PushStreamContent(System.Func
,MediaTypeHeaderValue)' 及 'PushStreamContent(System.Action
,MediaTypeHeaderValue)'

错误2
“void video_stream.Controllers.VideoStream.WriteToStream(System.IO.stream,System.Net.Http.HttpContent,System.Net.TransportContext)”的返回类型错误

所以我猜错误2才是真正的问题,因为以下代码:

公共异步void WriteToStream(流输出流、HttpContent内容、TransportContext上下文){…}

在web api 1和2之间不再被标识为
??我在这里真的很困惑,因为我的目标是同一个框架,我似乎无法在如何修复它上做出直观的飞跃。我尝试更改WriteToStream签名都失败了


有没有人知道我需要什么才能让PushStreamContent接受web api 2或VS 2013或新的C#中的WriteToStream,或者这段代码的区别在哪里?

我不确定这是否是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();
    }
});

注意:我对代码做了另一个更改(删除了catch块),以允许异常传播。这是为了让您的客户知道服务中发生了一些错误,否则他们会认为一切都很顺利。

这是C#spec的已知问题。请查看此问题-

当我们引入这个返回任务的重载时,我们确实意识到这是一个破坏源代码级别的更改(尽管它不会破坏二进制兼容性)。我们仍然继续进行更改,因为不修复它会导致更多问题

关于如何修复它,你有两个选择-

  • 正如Kiran之前所建议的,您可以使用匿名方法语法,以便编译器为您选择正确的重载
  • 您可以使用显式强制转换,如下所示

    response.Content=new-PushStreamContent((Action)video.WriteToStream,new-MediaTypeHeaderValue(“video/”+ext))

  • 顺便说一句,请使用
    异步void
    方法。我建议你把它的签名改为

    public async Task WriteToStream(Stream outputStream, HttpContent content, TransportContext context)
    

    PushStreamContent构造函数的签名已更改。其onStreamAvailable参数是Action或Func泛型类型。问题是编译器不知道绑定到哪个类型

    因此,要解决此错误,请将streamAvailableHandler强制转换为操作:

    response.Content = new PushStreamContent((Action<Stream, HttpContent, TransportContext>)streamAvailableHandler);
    

    正如RaghuRam Nadiminti所说,通过将WriteToStream的返回类型从void更改为Task,编译将成功运行,而不需要显式强制转换


    公共异步任务WriteToStream(Stream outputStream、HttpContent内容、TransportContext上下文)

    这是我的解决方法:如果呼叫不明确,就直接将其转换为:

    response.Content = new PushStreamContent(
        (Action<Stream, HttpContent, TransportContext>) video.WriteToStream,
    new MediaTypeHeaderValue("video/" + ext));
    
    response.Content=新的PushStreamContent(
    (动作)video.WriteToStream,
    新的MediaTypeHeaderValue(“视频/”+ext));
    
    昨晚深夜,我在查看另一个PushStreamContent示例时,终于找到了您的确切解决方案。这促使我在第12节和第13节中“进入定义”,我想我应该从一开始就这样做。在12中,PSC有3个重载,但在13中,有6个重载。仔细观察,它似乎向外部方法传递了一个以前不需要的额外参数(任务)。我可以确认上述解决方案确实有效。如果您将“无效”更改为“任务”,则您的铸造也必须更改为(Func)
    response.Content = new PushStreamContent(
        (Action<Stream, HttpContent, TransportContext>) video.WriteToStream,
    new MediaTypeHeaderValue("video/" + ext));