ASP.NET Core HTTPRequestMessage returns strange JSON message
Asked Answered
H

3

17

I am currently working with ASP.NET Core RC2 and I am running into some strange results. So I have an MVC controller with the following function:

public HttpResponseMessage Tunnel() {
    var message = new HttpResponseMessage(HttpStatusCode.OK);
    message.Content = new StringContent("blablabla", Encoding.UTF8);
    message.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("text/plain");
    message.Headers.CacheControl = new System.Net.Http.Headers.CacheControlHeaderValue {
        NoCache = true
    };

    return message;
}

If I call this with postman with an Accept header set to text plain I get this response:

{
  "Version": {
    "Major": 1,
    "Minor": 1,
    "Build": -1,
    "Revision": -1,
    "MajorRevision": -1,
    "MinorRevision": -1
  },
  "Content": {
    "Headers": [
      {
        "Key": "Content-Type",
        "Value": [
          "text/plain"
        ]
      }
    ]
  },
  "StatusCode": 200,
  "ReasonPhrase": "OK",
  "Headers": [
    {
      "Key": "Cache-Control",
      "Value": [
        "no-cache"
      ]
    }
  ],
  "RequestMessage": null,
  "IsSuccessStatusCode": true
}

I really do not understand how this is the generated reponse to the above controller. It is basically a JSON serialization of the entire message itself and does in no way contain the "blablabla" I intended to send.

The only way I have gotten the desired result is by making my controller function return string instead of HttpResponse, but that way I am unable to set headers like CacheControl

So my question is: why do I get this strange response? It seems like very weird behaviour to me

Hopple answered 25/5, 2016 at 6:20 Comment(1)
#35750428, #34853572Kink
S
14

According to this article, ASP.NET Core MVC does not support HttpResponseMessage-returning methods by default.

If you want to keep using it, you can, by using WebApiCompatShim:

  1. Add reference to Microsoft.AspNetCore.Mvc.WebApiCompatShim to your project.
  2. Configure it in ConfigureServices(): services.AddMvc().AddWebApiConventions();
  3. Set up route for it in Configure():

    app.UseMvc(routes =>
    {
        routes.MapWebApiRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });
    
Selenaselenate answered 25/5, 2016 at 16:24 Comment(5)
@Iarzz11, this answer should be accepted. It worked well for me.Etruria
I added the "Microsoft.AspNetCore.Mvc.WebApiCompatShim":"1.1.0" to my project.json but got this error: Package Microsoft.AspNet.WebApi.Client 5.2.2 is not compatible with netcoreapp1.1 (.NETCoreApp,Version=v1.1) i used all other version numbers, still getting the same error.Cora
@HasanAYousef I think you need to add something like "imports": [ "portable-net45+win8" ] under the "netcoreapp1.1" node in your project.json. (But I haven't tested this.)Selenaselenate
Setting up routes is not required if all you need is to be able to return an HttpRequestMessageKamalakamaria
Microsoft have since documented this in detail: learn.microsoft.com/en-us/aspnet/core/migration/…Tetrasyllable
P
1

If you want to set Cache-Control header with string content, try this:

[Produces("text/plain")]
public string Tunnel()
{
    Response.Headers.Add("Cache-Control", "no-cache");
    return "blablabla";
}
Pasturage answered 25/5, 2016 at 15:29 Comment(0)
T
1

In ASP.NET Core, modify the response as it travels through the pipeline. So for headers, set them directly as in this answer. (I've tested this for setting cookies.) You can also set the HTTP status code this way.

To set content, and therefore use a specific formatter, follow the documentation Format response data in ASP.NET Core Web API. This enables you to use helpers such as JsonResult() and ContentResult().

A complete example translating your code might be:

[HttpGet("tunnel")]
public ContentResult Tunnel() {
    var response = HttpContext.Response;
    response.StatusCode = (int) HttpStatusCode.OK;
    response.Headers[HeaderNames.CacheControl] = CacheControlHeaderValue.NoCacheString;
    return ContentResult("blablabla", "text/plain", Encoding.UTF8);
}
Tetrasyllable answered 16/5, 2018 at 21:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.