引用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

查看:120
本文介绍了引用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>使用Target Framework 4.6.2在VS 2017中创建新的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

5> In the same solution create a new project with target framework .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序列化的成员的数量 属性.如果类型是集合,请考虑将其标记为 CollectionDataContractAttribute.请参阅Microsoft .NET Framework 其他受支持类型的文档.

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错误吗?

解决方案是什么?因为我想创建一个可以在经典.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

Update1

当我尝试@Nkosi建议时,出现以下异常

When i tried @Nkosi suggestion i get the exception below

HTTP/1.1 500内部服务器错误 缓存控制:无缓存 语法:无快取 内容类型:application/json;字符集= utf-8 过期:-1 服务器:Microsoft-IIS/10.0 X-AspNet版本:4.0.30319 X源文件:=?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 .HttpResponseMessage)'.," ExceptionType:" System.MissingMethodException," StackTrace:"在WebApplication1.Controllers.ReportController.Download()\ r \ n在lambda_method(Closure,Object,Object [])\ r \ n> System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<> c__DisplayClass10.b__9(对象实例,Object [] methodParameters)\ r \ n System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(对象实例) ,Object []参数)\ r \ n位于System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext,IDictionary`2参数,CancellationToken cancelToken)\ r \ n--从上一个异常发生的位置开始的堆栈跟踪被抛出--- \ r \ n在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSucce ss(任务任务)\ r \ n在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)\ r \ n在System.Web.Http.Controllers.ApiControllerActionInvoker.d__0.MoveNext()\ r \ n--从上一个引发异常的位置开始的堆栈结束跟踪--- \ r \ n在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)\ r \ n在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务) \ r \ n在System.Web.Http.Controllers.ActionFilterResult.d__2.MoveNext()\ r \ n ---从上一个引发异常的位置开始的堆栈跟踪--- \ r \ n在System.Runtime. CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)\ r \ n在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)\ r \ n在System.Web.Http.Dispatcher.HttpControllerDispatcher.d__1.MoveNext()"/p>

{"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()\r\n at lambda_method(Closure , Object , Object[] )\r\n at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass10.b__9(Object instance, Object[] methodParameters)\r\n at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(Object instance, Object[] arguments)\r\n at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken)\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Controllers.ApiControllerActionInvoker.d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Controllers.ActionFilterResult.d__2.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n 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

推荐答案

如果您查看

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

  • .NET Framework(带有.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天全站免登陆