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

svick
  • 236,525
  • 50
  • 385
  • 514
larzz11
  • 1,022
  • 2
  • 11
  • 24
  • http://stackoverflow.com/questions/35749928/mvc6-web-api-return-plain-text, http://stackoverflow.com/questions/34853072/how-to-return-file-from-asp-net-5-web-api – CodeCaster May 25 '16 at 16:27

3 Answers3

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?}");
    });
    
svick
  • 236,525
  • 50
  • 385
  • 514
  • @Iarzz11, this answer should be accepted. It worked well for me. – big_water Dec 15 '16 at 20:09
  • 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. – Hasan A Yousef Dec 22 '16 at 09:43
  • @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.) – svick Dec 22 '16 at 13:40
  • 2
    Setting up routes is not required if all you need is to be able to return an `HttpRequestMessage` – galdin Jan 09 '17 at 21:52
  • Microsoft have since documented this in detail: https://learn.microsoft.com/en-us/aspnet/core/migration/webapi?view=aspnetcore-2.0#microsoftaspnetcoremvcwebapicompatshim – Alex Angas May 16 '18 at 21:34
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";
}
adem caglin
  • 22,700
  • 10
  • 58
  • 78
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);
}
Alex Angas
  • 59,219
  • 41
  • 137
  • 210