52

I want to build my own JSON, and have the service return a string, here is the code

[OperationContract]
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json)]
public string GetCurrentCart()
{
    //Code ommited
    string jsonClient = null;
    var j = new { Content = response.Content, Display=response.Display, SubTotal=response.SubTotal};
    var s = new JavaScriptSerializer();
    jsonClient = s.Serialize(j);
    return jsonClient;
}

The response I am getting contains the \" used to create "'s in strings in c#.

The following is the response.

"{\"Content\":\"\\r\\n\\u003cdiv\\u003e\\r\\n\\u003cinput type=\\\"hidden\\\" name=\\\"__VIEWSTATE\\\" id=\\\"__VIEWSTATE\\\" value=\\\"\/wEPDwUBMA9kFgJmD2QWAmYPZBYGAgMPFgIeBFRleHQFKFlvdSBoYXZlIG5vIGl0ZW1zIGluIHlvdXIgc2hvcHBpbmcgY2FydC5kAgUPFgIeB1Zpc2libGVoZAIHDxQrAAIPFgIfAWhkZGQYAQUMY3RsMDEkbHZDYXJ0D2dkoWijqBUJaUxmDgFrkGdWUM0mLpgQmTOe8R8hc8bZco4=\\\" \/\\u003e\\r\\n\\u003c\/div\\u003e\\r\\n\\r\\n\\u003cdiv class=\\\"block block-shoppingcart\\\"\\u003e\\r\\n    \\u003cdiv class=\\\"title\\\"\\u003e\\r\\n        \\u003cspan\\u003eShopping Cart\\u003c\/span\\u003e\\r\\n    \\u003c\/div\\u003e\\r\\n    \\u003cdiv class=\\\"clear\\\"\\u003e\\r\\n    \\u003c\/div\\u003e\\r\\n    \\u003cdiv class=\\\"listbox\\\"\\u003e\\r\\n        You have no items in your shopping cart.\\r\\n        \\r\\n        \\r\\n    \\u003c\/div\\u003e\\r\\n\\u003c\/div\\u003e\\r\\n\",\"Display\":\"You have no items in your shopping cart.\",\"SubTotal\":null}"

The values are being correctly encoded, but the json itself is not properly formatted. These \'s cause it to go out of wack.

How do I return a string without the \'s in front of the "'s?

mihai
  • 2,746
  • 3
  • 35
  • 56
Paul Knopf
  • 9,568
  • 23
  • 77
  • 142
  • when I set ResponseFormat=WebMessageFormat.Xml, the \'s are gone, but of couse the root xml node is there (which I don't want). – Paul Knopf Jun 20 '10 at 06:18

4 Answers4

119

Currently your web method returns a String together with ResponseFormat = WebMessageFormat.Json. It follows that your code will use the JSON encoding of the string. Corresponding to json.org, this means all double quotes in the string will be escaped using backslashes. So you currently have double JSON encoding.

The easiest way to return any kind of data is to change the output type of the GetCurrentCart() web method to Stream or Message (from System.ServiceModel.Channels) instead of String.

For code examples, see also...

Because you don't include in your question which version of .NET you use, I suggest you to use a universal (and the easiest) way:

public Stream GetCurrentCart()
{
    //Code ommitted
    var j = new { Content = response.Content, Display=response.Display,
                  SubTotal=response.SubTotal};
    var s = new JavaScriptSerializer();
    string jsonClient = s.Serialize(j);
    WebOperationContext.Current.OutgoingResponse.ContentType =
        "application/json; charset=utf-8";
    return new MemoryStream(Encoding.UTF8.GetBytes(jsonClient));
}
ruffin
  • 16,507
  • 9
  • 88
  • 138
Oleg
  • 220,925
  • 34
  • 403
  • 798
  • 11
    I have wasted hours on this. Thanks! – Paul Knopf Jun 20 '10 at 19:46
  • Hi Oleg thank you so..much i waste the so much of time for this at finally i found this link..Really i thanks to you... – Victor Aug 30 '11 at 13:46
  • @Victor: I am glad to hear (to read) that I could help you. You are welcome! – Oleg Aug 30 '11 at 13:48
  • Hi i have one more issue that when i return the json string at last showing the null can u refer this link once please http://restaurantmanager.testshell.net/api/Account/GetSetting(0825CA34-CEFF-11E0-84C1-2F0C4824019B,Operation%20Times) – Victor Aug 30 '11 at 14:31
  • 2
    How can i solve this end the array it append the – Victor Aug 30 '11 at 14:32
  • @Victor: sorry, but the url which you posted return `

    Service

    Endpoint not found.

    ` error with the HTTP status cod "HTTP/1.1 404 Not Found". Do you have a question where you describes your probel? Could you post correct URL?
    – Oleg Aug 30 '11 at 15:23
  • Hi Oleg can you test that link in Online Json valid tester in that it showing some errors and when check the view source page it showing the all data. – Victor Aug 31 '11 at 04:56
  • when i run this in Fiddler it showing like this [{"AccountId":1,"AccountNumber":"AC001","AccountType":"Restaurant","BusinessName":"Red Spice Inc","PrimaryContactFirstName":"Varma","PrimaryContactLastName":"Bhupatiraju","PrimaryContactPhone":"(949) 374 2114","PrimaryContactEmail":"redspice@mybusinessapp.com","AccountGuid":"918D3E66-CEFE-11E0-8C2F-0C0B4824019B","EntityState":1,"EntityKey":null}]. – Victor Aug 31 '11 at 04:58
  • @Victor: I wrote you before that the link http://restaurantmanager.testshell.net/api/Account/GetSetting(0825CA34-CEFF-11E0-84C1-2F0C4824019B,Operation%20Times which you posted is wrong and return only the error "Endpoint not found." So I can't test anything. – Oleg Aug 31 '11 at 07:15
  • @Oleg let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/3019/discussion-between-victor-and-oleg) – Victor Aug 31 '11 at 07:17
  • Thanks ,its really alos help me to get out to this problem that i am facing .Thanks a lot. – Vikram SE Jun 19 '13 at 21:17
  • @VikramSE: You are welcome! I'm glad to know that I could help you. – Oleg Jun 20 '13 at 05:20
  • Do we need to close the memorystream? – Pilouk Sep 18 '14 at 17:32
  • @Pilouk: No, it's not needed. – Oleg Sep 18 '14 at 17:34
  • Your first link was EXACTLY what I was looking for. return string as json. done. Thanks – Adam Hey May 15 '15 at 10:50
  • @AdamHey: You are welcome! I'm glad that the old answer still helps. – Oleg May 15 '15 at 11:03
6

I tried the method suggested by Oleg but found that when i used this method for a large amount of data null key word was appended at the end of the JSON string.

Example: for json with lots of data {"JsonExample":"xxxxx"}null

found a solution to address this problem at : http://wcf.codeplex.com/workitem/67 Wrote the following function which will accept a object and return a Pure Json output. So before returning my object in the main method i make a call to the below method.

  public HttpResponseMessage ReturnPureJson(object responseModel)
    {
        HttpResponseMessage response = new HttpResponseMessage();

        string jsonClient = Json.Encode(responseModel);
        byte[] resultBytes = Encoding.UTF8.GetBytes(jsonClient);
        response.Content = new StreamContent(new MemoryStream(resultBytes));
        response.Content.Headers.ContentType = new MediaTypeHeaderValue("text/plain");

        return response;
    }
CostaIvo
  • 1,029
  • 13
  • 19
3

I recommend to use Jil library to Serialize your JSON object or dynamic(ExpandoObject).

In my case, It will avoid some null value problem, like always get "{}" from JsonConvert.SerializeXXX and extend {aa:bb} to {key:aa, value:bb} from JavaScriptSerializer

full sample here as below.

Interface:

[OperationContract]
[WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare, UriTemplate = "json/GetCurrentCart")]
Stream GetCurrentCart(MyRequestParam Param);

Implementation:

public Stream GetCurrentCart(MyRequestParam Param)
{
    //code omitted
    dynamic j = new System.Dynamic.ExpandoObject();
    j.Content = response.Content;
    j.Display = response.Display; 
    j.SubTotal = response.SubTotal;
    string s = Jil.JSON.SerializeDynamic(j);
    WebOperationContext.Current.OutgoingResponse.ContentType = "application/json; charset=utf-8";
    return new MemoryStream(Encoding.UTF8.GetBytes(s));
} 
John Jang
  • 2,567
  • 24
  • 28
2

That was great (Oleg Response) and all make sure that you add the line WebOperationContext.Current.OutgoingResponse.ContentType = "application/json; charset=utf-8";

if you removed it result will be downloaded as file .

Ahmed Samir
  • 117
  • 4