0

I have a web service method that gets an escaped json string from an external source that I want to allow my users to download as a file by hitting a web service URL. I don't want to save the file on my local web server, just hand a file to the client.

IService

[OperationContract]
    [WebInvoke(Method = "GET", 
        BodyStyle = WebMessageBodyStyle.WrappedRequest,
        ResponseFormat = WebMessageFormat.Json,
        RequestFormat = WebMessageFormat.Json)]
    string GetEscapedStringFromOutsideSource();

Service

public string SendUserAFile()
{
    string s = GetEscapedStringFromOutsideSource();

    WebOperationContext.Current.OutgoingResponse.Headers.Add("Content-Disposition", "attachment; filename=" + Effectivity + ".json");
    WebOperationContext.Current.OutgoingResponse.ContentType = "application/json; charset=utf-8";

    return s;
}

If I do this then when the user hits service URL with their browser a file is downloaded, but it contains an escaped JSON string rather than valid JSON.

What I get in the file: "{\"Layout\":{\"Children\":[{\"AftSTA\":928.0}]}}"

What I want in the file: {"Layout":{"Children":[{"AftSTA":928.0}]}}

Any idea how to escape the resulting string?

nickvans
  • 898
  • 13
  • 24
  • What do you mean by *I have a web service method that gets an escaped json string from an external source*? Do you mean that `s` contains the string `"{\"Layout\":{\"Children\":[{\"AftSTA\":928.0}]}}"`? Or does `s` contain `{"Layout":{"Children":[{"AftSTA":928.0}]}}` and it is somehow getting escaped when you do `return s`? – dbc Feb 09 '21 at 17:10
  • If the former, that looks to be double-serialized JSON. You can use your preferred JSON serializer to deserialize that string and get the original JSON, e.g. `JsonConvert.DeserializeObject(s)`. (Or you could request that the service fix the JSON...) – dbc Feb 09 '21 at 17:15
  • If the latter, you should be able to use `WebOperationContext.Current.CreateTextResponse` to return raw JSON, see [this answer](https://stackoverflow.com/a/3131413/3744182) to [How to set Json.Net as the default serializer for WCF REST service](https://stackoverflow.com/q/3118504/3744182) by [Oleg](https://stackoverflow.com/users/315935/oleg) for details. – dbc Feb 09 '21 at 17:17
  • @dbc I think s is not double-serialized. I can, for instance, use Newtonsoft to parse it like this `JObject j = JObject.Parse(s);` and I get a valid JObject out of it. My problem is the resulting json file is still escaped when I open it in a text editor. – nickvans Feb 09 '21 at 17:20
  • 2
    OK, then the web service isn't returning an escaped JSON string, rather your code is escaping it somehow when you return it. In that case try using the `WebOperationContext.Current.CreateTextResponse` answer to see if that helps you. ... another similar Q&A is here: [How can I return json from my WCF rest service (.NET 4), using Json.Net, without it being a string, wrapped in quotes?](https://stackoverflow.com/a/3027880/3744182). – dbc Feb 09 '21 at 17:22

1 Answers1

1

Thanks to @dbc for setting me in the right direction. My final solution for returning a non-escaped json file was simply

public Stream SendUserAFile()
{
    string s = GetEscapedStringFromOutsideSource();
    WebOperationContext.Current.OutgoingResponse.Headers.Add("Content-Disposition", "attachment; filename=" + Effectivity + ".json");
    WebOperationContext.Current.OutgoingResponse.ContentType = "application/json; charset=utf-8";
    return new MemoryStream(System.Text.Encoding.UTF8.GetBytes(s));
}
nickvans
  • 898
  • 13
  • 24