引用 NET Standard 1.6 项目时,ASP.NET Web API 2 无法返回流 [英] ASP.NET Web API 2 cannot return stream when NET Standard 1.6 project is referenced

查看:20
本文介绍了引用 NET Standard 1.6 项目时,ASP.NET Web API 2 无法返回流的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我见过的奇怪问题之一,以下是重现的步骤

This is one of the weird issue I have seen and here are the steps to reproduce

1> 在 VS 2017 中使用 Target Framework 4.6.2 创建新的 Web API 项目

Create new ASP.NET Web Application -> Select Empty -> Check Web API -> Click OK  

2> 添加返回流的控制器

    public class ReportController : ApiController
    {
        [HttpGet]
        public HttpResponseMessage Download()
        {
            var filePath = "C:\Report.xlsx";
            var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
            var result = new HttpResponseMessage(HttpStatusCode.OK)
            {
                Content = new StreamContent(fs)
            };
            result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            return result;
        }
    }

3> 运行应用程序并在 IE 11 中调用 api(使用正确的端口号)
http://localhost:40005/api/report/download

浏览器应该下载一个EXCEL文件,你应该可以打开EXCEL文件.

The browser should download a EXCEL file and you should be able to open EXCEL file.

5> 停止 Visual Studio

5> 在同一个解决方案中创建一个具有目标框架 .NET Standard 1.6

6> 在 Web API 项目中,添加对新创建的 NET Standard 库项目的项目引用

7> 在 IE 11 中运行应用程序并调用 api
http://localhost:40005/api/report/download

请注意,浏览器将返回 json 而不是 excel 文件.

Notice that browser will get json back instead of excel file.

{"Version":{"_Major":1,"_Minor":1,"_Build":-1,"_Revision":-1},"Content":{"Headers":[{"Key":"Content-Type","Value":["application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"]}]},"StatusCode":200,"ReasonPhrase":"OK","Headers":[],"RequestMessage":null,"IsSuccessStatusCode":true}

如果你尝试使用谷歌浏览器,那么我得到的不是json而是异常

If you try with google chrome then instead of json I get exception

类型System.Net.Http.StreamContent"无法序列化.考虑用 DataContractAttribute 属性标记它,并标记所有您想要使用 DataMemberAttribute 序列化的成员属性.如果类型是集合,请考虑使用集合数据合同属性.请参阅 Microsoft .NET 框架其他受支持类型的文档.

Type 'System.Net.Http.StreamContent' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute. If the type is a collection, consider marking it with the CollectionDataContractAttribute. See the Microsoft .NET Framework documentation for other supported types.

我不知道为什么仅仅通过引用 .NET Standard 1.6 项目就改变了行为.如果我删除对 .NET Standard 1.6 项目的引用,则一切正常.

I don't know why just by referencing .NET Standard 1.6 project changes the behavior. If I remove the reference to .NET Standard 1.6 project then everything works fine.

这是 .NET 的错误吗?

Is this a bug .NET?

解决办法是什么?因为我想创建一个可以在经典 .NET 4.6.2 和 .NET Core 项目之间共享的库.我认为 .NET Standard 1.6 是可行的方法

What is the solution? Because i wanted to create a library that can be shared between classic .NET 4.6.2 and .NET Core projects. and i thought .NET Standard 1.6 is way to go

更新 1

当我尝试@Nkosi 建议时,我得到以下异常

When i tried @Nkosi suggestion i get the exception below

HTTP/1.1 500 内部服务器错误缓存控制:无缓存编译指示:无缓存内容类型:应用程序/json;字符集=utf-8过期时间:-1服务器:Microsoft-IIS/10.0X-AspNet 版本:4.0.30319X-SourceFiles: =?UTF-8?B?QzpcTXlQcm9qZWN0c1xXZWJBcHBsaWNhdGlvbjFcV2ViQXBwbGljYXRpb24xXGFwaVxyZXBvcnRcZG93bmxvYWQ=?=X-Powered-By: ASP.NET日期:2018 年 2 月 10 日星期六 02:02:47 GMT内容长度:1937

HTTP/1.1 500 Internal Server Error Cache-Control: no-cache Pragma: no-cache Content-Type: application/json; charset=utf-8 Expires: -1 Server: Microsoft-IIS/10.0 X-AspNet-Version: 4.0.30319 X-SourceFiles: =?UTF-8?B?QzpcTXlQcm9qZWN0c1xXZWJBcHBsaWNhdGlvbjFcV2ViQXBwbGljYXRpb24xXGFwaVxyZXBvcnRcZG93bmxvYWQ=?= X-Powered-By: ASP.NET Date: Sat, 10 Feb 2018 02:02:47 GMT Content-Length: 1937

{"Message":"发生错误.","ExceptionMessage":"方法未找到:'System.Web.Http.Results.ResponseMessageResult System.Web.Http.ApiController.ResponseMessage(System.Net.Http.Results.ResponseMessageResult.HttpResponseMessage)'.","ExceptionType":"System.MissingMethodException","StackTrace":" 在 WebApplication1.Controllers.ReportController.Download() 在 lambda_method(Closure , Object , Object[] ) 在 System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass10.b__9(Object instance, Object[] methodParameters) 在 System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(Object instance), Object[] 参数) 在 System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancelationToken) --- 上一个位置的堆栈跟踪结束,其中异常被抛出 --- 在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Controllers.ApiControllerActionInvoker.d__0.MoveNext() ---从上一个抛出异常的位置结束堆栈跟踪 --- 在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 在 System.Web.Http.Controllers.ActionFilterResult.d__2.MoveNext() --- 从上一个抛出异常的位置开始的堆栈跟踪结束 --- 在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Dispatcher.HttpControllerDispatcher.d__1.MoveNext()"}

{"Message":"An error has occurred.","ExceptionMessage":"Method not found: 'System.Web.Http.Results.ResponseMessageResult System.Web.Http.ApiController.ResponseMessage(System.Net.Http.HttpResponseMessage)'.","ExceptionType":"System.MissingMethodException","StackTrace":" at WebApplication1.Controllers.ReportController.Download() at lambda_method(Closure , Object , Object[] ) at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass10.b__9(Object instance, Object[] methodParameters) at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(Object instance, Object[] arguments) at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken) --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Controllers.ApiControllerActionInvoker.d__0.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Controllers.ActionFilterResult.d__2.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Dispatcher.HttpControllerDispatcher.d__1.MoveNext()"}

更新 2
我将 NET Standard 版本降低到 1.4 并且它起作用了.但是后来我将 Web Api 项目的包管理格式从 package.config 更改为 PackageReference 并恢复了所有包.( 为什么?缺少依赖项问题)API 再次开始返回 JSON

Update 2
I lowered down NET Standard version to 1.4 and it worked. However then I changed Web Api project's package management format from package.config to PackageReference and restored all the packages. ( Why? missing dependencies issue) and again API started returning JSON

推荐答案

如果你看看 .NET Standard 兼容性图表,具体说明:

If you take a look at the .NET Standard compatibility chart, it specifically states:

  • .NET 框架(带有 .NET Core 1.x SDK)
  • .NET Framework(使用 .NET Core 2.0 SDK) - 我也在某处读到这也需要 VS 2017 才能工作
  • .NET Framework (with .NET Core 1.x SDK)
  • .NET Framework (with .NET Core 2.0 SDK) - I have also read somewhere this also requires VS 2017 to work

这些依赖项必须存在于使用 .NET Standard 库的开发系统上,以便它们与 .NET Framework 兼容.

These are dependencies that must be present on the development system that consumes the .NET Standard libraries in order for them to be compatible with .NET Framework.

请注意 .NET Framework 4.7.1 修补了此行为,因此它本机支持 .NET Standard,没有依赖项(至少它会修补此错误时).

Do note that .NET Framework 4.7.1 patches this behavior so it supports .NET Standard natively, without dependencies (at least it will when this bug is patched).

这篇关于引用 NET Standard 1.6 项目时,ASP.NET Web API 2 无法返回流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆