显示来自 HttpResponseMessage 的内容字符串

Display content string from HttpResponseMessage

我在 MVC 应用程序中有一个 post 控制器返回此响应:

return new HttpResponseMessage(HttpStatusCode.Accepted)
{
    Content = new StringContent("test")
};

当我使用此代码点击 post URL 时:

using (WebClient client = new WebClient())
{
    string result = client.UploadString(url, content);
}

结果包含此响应:

StatusCode: 202, ReasonPhrase: 'Accepted', Version: 1.1, Content: System.Net.Http.StringContent, Headers: { Content-Type: text/plain; charset=utf-8 }

为什么 "test" 没有出现在 Content: 之后?

谢谢!

您不应该 return HttpResponseMessage 来自 ASP.NET MVC 操作。在这种情况下,您会得到像这样的混乱响应:

HTTP/1.1 200 OK
Cache-Control: private
Content-Type: text/html; charset=utf-8
Vary: Accept-Encoding
Server: Microsoft-IIS/10.0
X-AspNetMvc-Version: 5.2
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?RDpcRHJvcGJveFxwcm9nXFN0YWNrT3ZlcmZsb3dcZG90TmV0XE12Y0FwcGxpY2F0aW9u?=
X-Powered-By: ASP.NET
Date: Sun, 04 Feb 2018 10:18:38 GMT
Content-Length: 154

StatusCode: 202, ReasonPhrase: 'Accepted', Version: 1.1, Content: System.Net.Http.StringContent, Headers:
{
  Content-Type: text/plain; charset=utf-8
}

如您所见,您实际上获得了 200 个 HTTP 响应,响应正文中包含 HttpResponseMessage 详细信息。这个乱七八糟的正文内容就是你反序列化到 result 变量中的内容。

ASP.NET MVC 操作应该 return 派生自 System.Web.Mvc.ActionResult 的 class 实例。不幸的是,没有允许同时设置 return 状态代码和正文内容的内置操作结果。 有 ContentResult class 允许设置 return 状态码为 200 的字符串内容。还有 HttpStatusCodeResult 允许设置任意状态码但响应主体将为空.

但是您可以使用可设置的状态代码和响应正文来实现您的自定义操作结果。为简单起见,您可以将其基于 ContentResult class。这是一个示例:

public class ContentResultEx : ContentResult
{
    private readonly HttpStatusCode statusCode;

    public ContentResultEx(HttpStatusCode statusCode, string message)
    {
        this.statusCode = statusCode;
        Content = message;
    }

    public override void ExecuteResult(ControllerContext context)
    {
        if (context == null)
        {
            throw new ArgumentNullException(nameof(context));
        }

        base.ExecuteResult(context);
        HttpResponseBase response = context.HttpContext.Response;
        response.StatusCode = (int)statusCode;
    }
}

操作看起来像:

public ActionResult SomeAction()
{
    return new ContentResultEx(HttpStatusCode.Accepted, "test");
}

另一个可能的修复方法是将控制器从 MVC 更改为 WEB API 控制器。为此 - 只需将控制器的基数 class 从 System.Web.Mvc.Controller 更改为 System.Web.Http.ApiController。在这种情况下,您可以 return HttpResponseMessage 作为您的答案。

在这两种情况下,您都将获得正确的 HTTP 响应,其中包含 202 状态代码和正文中的字符串:

HTTP/1.1 202 Accepted
Cache-Control: private
Content-Type: text/html; charset=utf-8
Server: Microsoft-IIS/10.0
X-AspNetMvc-Version: 5.2
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?RDpcRHJvcGJveFxwcm9nXFN0YWNrT3ZlcmZsb3dcZG90TmV0XE12Y0FwcGxpY2F0aW9u?=
X-Powered-By: ASP.NET
Date: Sun, 04 Feb 2018 10:35:24 GMT
Content-Length: 4

test