.NET 4.7 web api 在包含 NetStandard 2.0 包时返回 HttpResponseMessage 对象信息而不是 StringContent

.NET 4.7 web api returning HttpResponseMessage object info instead of StringContent when including a NetStandard 2.0 package

我创建了一个 .net 4.7 web api 项目,其中包含一个 returns 字符串

的简单操作
[System.Web.Http.Route("api/GetData")]
[System.Web.Http.HttpGet]
public async Task<System.Net.Http.HttpResponseMessage> GetData()
{
    string result = await Task.FromResult("test data");
    var content = new System.Net.Http.StringContent(result);
    return new System.Net.Http.HttpResponseMessage() { Content = content };
}

查询这条路线时,我得到 "test data" 的结果。 一旦我添加了 NetStandard 2.0 包(例如 "System.Threading.Tasks.Extensions")并重新查询路由,我的结果看起来完全不同

{
    "Version": {
        "_Major": 1,
        "_Minor": 1,
        "_Build": -1,
        "_Revision": -1
    },
    "Content": {
        "Headers": [{
            "Key": "Content-Type",
            "Value": ["text/plain; charset=utf-8"]
        }]
    },
    "StatusCode": 200,
    "ReasonPhrase": "OK",
    "Headers": [],
    "RequestMessage": null,
    "IsSuccessStatusCode": true
}

奇怪的是在 NuGet 引用 System.Net.Http 之前 v4.0.0.0 位置 "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.7\System.Net.Http.dll" 添加引用后,版本更改为 v4.2.0.0 位置 "C:\Program Files (x86)\Microsoft Visual Studio17\Community\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Net.Http.dll"

有没有人知道这是为什么以及如何解决它?

我遇到了这个问题,整天都在与它作斗争,但多亏了这个 post 通过 Nkosi 我已经能够解决它:

How to return a file (FileContentResult) in ASP.NET WebAPI

所以我按照 Nkosi 的建议将其更改为 return 带有自定义响应的 IHttpActionResult 这样我的代码看起来像(您也可以按照其他人的建议创建自定义 IHttpActionResult):

[HttpGet]
public IHttpActionResult GenerateReport(int reportId)
{
    var reportMemoryStream = _reportService.GenerateStream(reportId)
    var result = new HttpResponseMessage(HttpStatusCode.OK)
    {
        Content = new ByteArrayContent(reportMemoryStream.ToArray())
    };

    result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
    {
        FileName = "ExecutiveReport.docx"
    };

    result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");

    return ResponseMessage(result);
}

然而,这给了我另一个问题如下:

Method not found: 'System.Web.Http.Results.ResponseMessageResult'

为了解决这个问题,我遵循了 和 运行

中的建议
Update-Package Microsoft.AspNet.WebApi -reinstall

然后一切都很有魅力。希望对您和任何其他遇到这个问题但没有找到我找到的其他答案的人有所帮助。

对于遇到此问题的任何人 post,我能找到的最佳解决方案是这个答案 Is there a way to force ASP.NET Web API to return plain text?

基本上你实现了

public class TextPlainFormatter : MediaTypeFormatter
{
    public TextPlainFormatter()
    {
        this.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/plain"));
    }

    public override bool CanWriteType(Type type)
    {
        return type == typeof(string);
    }

    public override bool CanReadType(Type type)
    {
        return type == typeof(string);
    }

    public override Task WriteToStreamAsync(Type type, object value, Stream stream, HttpContentHeaders contentHeaders, TransportContext transportContext)
    {
        return Task.Factory.StartNew(() => {
            StreamWriter writer = new StreamWriter(stream);
            writer.Write(value);
            writer.Flush();
        });
    }

    public override Task<object> ReadFromStreamAsync(Type type, Stream stream, HttpContentHeaders contentHeaders, IFormatterLogger formatterLogger)
    {
        return Task.Factory.StartNew(() => {
            StreamReader reader = new StreamReader(stream);
            return (object)reader.ReadToEnd();
        });
    }
}

然后在 webapi 配置中注册格式化程序

config.Formatters.Add(new TextPlainFormatter());

那么return你的操作结果如下

this.Request.CreateResponse(HttpStatusCode.OK, "some text", "text/plain");

运行 我自己解决了这个问题并提出了一个可行的解决方案!

有趣的是,您关于 System.Net.Http.dll 引用更改的说明是促使我找到解决方案的原因。

在我的例子中,它适用于本地调试,但在实时部署时会失败。

因此,我将以下绑定重定向添加到我的 web.config 以强制它使用我选择的版本:

<dependentAssembly>
        <assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>

这对我有用!

这些数字很不稳定(v 5.0.0.0 甚至都不是问题)但它完成了工作。根据需要随意修改。