1

I have a simple ASP.NET Core 7 Web API method:

[HttpPost("processPiece")]
public async Task<ActionResult<string>> ProcessPiece([FromBody] PieceModel piece)
{
    return _processingService.ProcessPiece(piece.Piece);
} 

The ProcessPiece method returns a string value. It contains multiple lines.

I'm trying to display this value in a Blazor component on the UI.

_httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var response = await _httpClient.PostAsync($"api/Piece/processPiece", new StringContent("{\"piece\":\"" + piece + "\"}", Encoding.UTF8, "application/json"));
return await response.Content.ReadAsStringAsync();

The view markup is very simple for now:

<p>@outputValue</p>

I found out that response.Content.ReadAsStringAsync(); returns the string wrapped in extra quotes, and instead of rendering a new line it shows "\r\n".

It seems the output is somehow escaped during transport or decoding.

I've looked for solutions here, but all the threads I found on the topic seem to be at least 10 years old and the provided solutions don't seem to work.

Regardless, I've tried implementing one of the suggested solutions, by switching the type the endpoint returns to plaintext:

[HttpPost("processPiece")]
public async Task<ActionResult<HttpResponseMessage>> ProcessPiece([FromBody] PieceModel piece)
{
     var  a =  _processingService.ProcessPiece(piece.Piece);
     var resp = new HttpResponseMessage(HttpStatusCode.OK);
     resp.Content = new StringContent(a, System.Text.Encoding.UTF8, "text/plain");
     return resp;
}

Client side:

_httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/plain"));
    var response = await _httpClient.PostAsync($"api/Piece/processPiece", new StringContent("{\"piece\":\"" + piece + "\"}", Encoding.UTF8, "application/plaintext"));
    var a = await response.Content.ReadAsStringAsync();
    return a;

This didn't work at all. Now all I get from the endpoint is a bunch of metadata:

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

Can anyone help?

3
  • Does this answer your question? Why is .NET 6 minimal API returning JSON as a string and not as JSON? Commented Oct 31, 2023 at 19:22
  • "instead of rendering a new line it shows \r\n" is expected in the debugger view and html mostly ignores \r\n . So maybe your first attempt was correct all along, just not the simple @outputValue. Commented Oct 31, 2023 at 19:58
  • @h-h it renders "\r\n" on the web page itself. I'm dumb, but not that dumb :) I originally wrote "\r\n" in my question to indicate this, the genius that edited my question took the quotes out. Commented Oct 31, 2023 at 20:15

1 Answer 1

2

ASP.NET Core does not handle HttpResponseMessage as a special type, so you result will be serialized to JSON (so if you return just a string it will be encoded as JSON, hence the extra quotes). Just use one of the Content options. For example:

public async Task<IActionResult> ProcessPiece([FromBody] PieceModel piece)
{
    return Content("somestring", "text/plain", System.Text.Encoding.UTF8);
}

Or via Results/TypedResults (depending on the use case).

Sign up to request clarification or add additional context in comments.

3 Comments

return Content(a, "text/plain", System.Text.Encoding.UTF8); <- here VS tells me Content is not recognized, and it doesn't offer to add any "using" statement. So I assume this code is from some different version of asp.net?
I tried "return Results.Content..., I get this: Cannot implicitly convert type 'Microsoft.AspNetCore.Http.IResult' to 'Microsoft.AspNetCore.Mvc.ActionResult'. An explicit conversion exists (are you missing a cast?)
@Shaggydog this method is present in ASP.NET Core since 1.0 - check it yourself. I assume you are using it (based on tags). Do you have a minimal reproducible example? Can you post it somewhere (github for example)?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.