Why is the entire HttpResponseMessage serialized?

徘徊边缘 提交于 2021-02-05 03:23:09

问题


Why does this Web API implementation

[HttpGet("hello")]
public HttpResponseMessage Hello()
{
    var res = new HttpResponseMessage(HttpStatusCode.OK);
    res.Content = new StringContent("hello", Encoding.UTF8, "text/plain");
    return res;
}

return

{
  "Version":{
    "Major":1,
    "Minor":1,
    "Build":-1,
    "Revision":-1,
    "MajorRevision":-1,
    "MinorRevision":-1
  },
  "Content":{
    "Headers":[{
      "Key":"Content-Type",
      "Value":["text/plain; charset=utf-8"]
    }]
  },
  "StatusCode":200,
  "ReasonPhrase":"OK",
  "Headers":[],
  "RequestMessage":null,
  "IsSuccessStatusCode":true
}

instead of

hello

?

How can I make the Web API return an HTTP response like below?

200 OK
Content-Type: text/plain

hello

What I want to do finally is return JSON and other formats with various status codes, so the following code wouldn't help me as an answer.

[HttpGet("hello")]
public string Hello()
{
    return "hello";
}

(I'm new to ASP.NET and other Microsoft technologies.)


回答1:


Intriguing, if I try your code on ASP.NET 4

public HttpResponseMessage Hello()
{
    var res = new HttpResponseMessage(HttpStatusCode.OK);
    res.Content = new StringContent("hello", Encoding.UTF8, "text/plain");
    return res;
}

I get response, what I expect.


Header:

HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 5
Content-Type: text/plain; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
...
X-Powered-By: ASP.NET
Date: ...

Body

hello

Depending on the situation, you can either rely on client to specify what it can accept or you can specify server to always throw json.

I usually have custom request/response objects which I throw back to client. For instance

public CustomResponse Get()
{
    CustomResponse response = new CustomResponse();

    // some work
    response.TestProperty1 = "Test Value 1";
    response.TestProperty2 = "Test value 2";

    return response;
}

Now if your API would respect what your client accepts. So if client set request header "Accept: application/xml" then it would return xml or json if its json. Refer to screenshot of fiddler request below.

From memory, I think you can also specify on server as well say to always send json.

Hope this helps!




回答2:


ASP.net Web Api uses something called Content Negotiation where the client specifies that content to be returned.

In your case, you could specify that you want text/plain returned and the built-in content negotiation should provide what you want.

You've not specified how you are making the request - manually in a browser (which browser) / via jquery $.ajax / .net client code / etc - and how you make the request determines how you add the accept header to that request, eg:

GET http://[url] HTTP/1.1
Accept: text/plain

It's possible to override the content negotiation and always return a specific type (eg JSON) and there are many questions on SO on how to do this - mostly because they want JSON but get xml and don't know how to request JSON. If you're creating a reusable Web API then you should leave this up to the client to request what they want, which is why it's built that way into the framework.




回答3:


(Self-answering) Hmm... The reason might be that I had chosen

ASP.NET 5 Preview Templates

instead of

ASP.NET 4.5.2 Templates

when I tried to create a Web API.

I guess it might be a bug of ASP.NET 5 Preview or ASP.NET 5 has introduced another new mechanism that supersedes HttpResponseMessage.




回答4:


I had the same happen to me recently. The reason was that, for some reason, there was two references to the System.Net.Http.dll assembly: one from the GAC and one local copy from my project.

It results in an interesting case where the type of HttpResponseMessage you send isn't the same type of HttpResponseMessage ASP.NET expects, and that's why instead on processing the message, it just serializes it as JSON.

The solution I found for this is to install the System.Net.Http package from NuGet, and ensure that the binding redirect is generated correctly on the Web.config, so that only one copy of the dependency is used.



来源:https://stackoverflow.com/questions/32665773/why-is-the-entire-httpresponsemessage-serialized

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!