Search code examples
c#restasp.net-web-apihttpresponsehttp-get

How do I set a value for HttpResponseMessage.Content in C#


I have a Web API method that returns data in the HttpResponseMessage.Content property. Here is the code for the method:

[HttpGet]
public HttpResponseMessage MethodName()
{
    try
    {
        var response = new HttpResponseMessage(HttpStatusCode.OK);
        response.Content = new StringContent("Hello WORLD", Encoding.UTF8, "application/json");
        return response;
    }
    catch (Exception ex)
    {
        var response = new HttpResponseMessage(HttpStatusCode.InternalServerError);
        response.Content = new StringContent("{\"error\": \"" + ex.Message + "\"}", Encoding.UTF8, "application/json");
        return response;
    }
}

When I call this method from Postman, the response metadata shows that the response has a length of 11, which is correct for the "Hello WORLD" string. However, I cannot see the actual data in the response body.

What am I missing?

Here is the response:

{
    "version": "1.1",
    "content": {
        "headers": [
            {
                "key": "Content-Type",
                "value": [
                    "application/json; charset=utf-8"
                ]
            },
            {
                "key": "Content-Length",
                "value": [
                    "11"
                ]
            }
        ]
    },
    "statusCode": 200,
    "reasonPhrase": "OK",
    "headers": [],
    "trailingHeaders": [],
    "requestMessage": null,
    "isSuccessStatusCode": true
}

Solution

  • If you would use IActionResult as a return type of your method then you could take advantage of Ok and StatusCode methods of the base class. Your method could be rewritten like this:

    [HttpGet]
    public IActionResult MethodName()
    {
        try
        {
            return Ok("Hello WORLD");
        }
        catch (Exception ex)
        {
            return StatusCode((int)HttpStatusCode.InternalServerError, "{\"error\": \"" + ex.Message + "\"}") ;
        }
    }
    

    Quite frankly I don't trully understand the sole purpose of your try-catch block but I hope you get the point.


    UPDATE #1

    why I can't set HttpResponseMessage.Content correctly.

    The StringContent does have a single property called Headers. In other words the value is not exposed as a property. The popular serializers (like Json.NET or System.Text.Json) serializes only the properties by default.

    If you could use JsonContent instead of StringContent then the serialization will work correctly since it is exposing the Value as property.

    var response = new HttpResponseMessage(HttpStatusCode.OK);
    response.Content = JsonContent.Create("Hello WORLD");   
    var responseInJson = JsonConvert.SerializeObject(response, Formatting.Indented);
    responseInJson.Dump();
    
    {
       "Version":"1.1",
       "Content":{
          "ObjectType":"System.String, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
          "Value":"Hello WORLD",
          "Headers":[
             {
                "Key":"Content-Type",
                "Value":[
                   "application/json; charset=utf-8"
                ]
             }
          ]
       },
       "StatusCode":200,
       "ReasonPhrase":"OK",
       "Headers":[
          
       ],
       "TrailingHeaders":[
          
       ],
       "RequestMessage":null,
       "IsSuccessStatusCode":true
    }
    

    Related dotnet fiddle link: https://dotnetfiddle.net/NiM8lx