这是我见过的一个奇怪的问题,这里是重现的步骤
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文件。
5个停止Visual Studio
5个在同一解决方案中,使用目标框架.NET Standard 1.6
6个在Web API项目中,将项目引用添加到新创建的NET标准库项目
7个运行应用程序并在IE 11中调用api
http://localhost:40005/api/report/download
请注意,浏览器将返回json而不是excel文件。
{"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}
如果您尝试使用google chrome而不是json,我会获得异常
类型'System.Net.Http.StreamContent'无法序列化。考虑 使用DataContractAttribute属性标记它,并标记所有 要使用DataMemberAttribute序列化的成员数 属性。如果类型是集合,请考虑使用 CollectionDataContractAttribute。请参阅Microsoft .NET Framework 其他支持类型的文档。
我不知道为什么仅通过引用.NET Standard 1.6
项目来改变行为。如果我删除对.NET Standard 1.6
项目的引用,那么一切正常。
这是一个.NET吗?
解决方案是什么?因为我想创建一个可以在经典.NET 4.6.2和.NET Core项目之间共享的库。我认为.NET Standard 1.6是可行的方式
Update1
当我尝试@Nkosi建议时,我得到以下例外
HTTP / 1.1 500内部服务器错误 缓存控制:无缓存 Pragma:没有缓存 Content-Type:application / json;字符集= utf-8的 到期:-1 服务器:Microsoft-IIS / 10.0 X-AspNet-Version:4.0.30319 X-SourceFiles:=?UTF-8?B?QzpcTXlQcm9qZWN0c1xXZWJBcHBsaWNhdGlvbjFcV2ViQXBwbGljYXRpb24xXGFwaVxyZXBvcnRcZG93bmxvYWQ =?= X-Powered-By:ASP.NET 日期:星期六,2018年2月10日02:02:47 GMT 内容长度: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 \在System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor。&lt;&gt; c__DisplayClass10.b__9(Object instance,Object [] methodParameters)\ r \ n在System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(Object实例,Object [] arguments)\ r \ n在System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext,IDictionary`2 arguments,CancellationToken cancellationToken)\ r \ n ---从上一个位置开始的堆栈跟踪抛出异常--- \ r \ n在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSu ccess(任务任务)\ r \ n在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)\ r \ n在System.Web.Http.Controllers.ApiControllerActionInvoker.d__0.MoveNext()\ r \ n ---从抛出异常的先前位置开始的堆栈跟踪结束---在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)\ r \ n处于System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)中的\ r \ n \ 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>
更新2
我将NET Standard版本降低到1.4并且有效。然而,我将Web Api项目的包管理格式从package.config
更改为PackageReference
并恢复了所有包。 (Why? missing dependencies issue)
API再次开始返回JSON
答案 0 :(得分:0)
如果您查看.NET Standard compatibility chart,请具体说明:
这些依赖项必须存在于使用.NET标准库的开发系统上,以便它们与.NET Framework兼容。
请注意,.NET Framework 4.7.1修补了此行为,因此它supports .NET Standard natively,没有依赖项(至少它会when this bug is patched)。