9

I want to return JSON data back to the client, in my web service method. One way is to create SoapExtension and use it as attribute on my web method, etc. Another way is to simply add [ScriptService] attribute to the web service, and let .NET framework return the result as {"d": "something"} JSON, back to the user (d here being something out of my control). However, I want to return something like:

{"message": "action was successful!"}

The simplest approach could be writing a web method like:

[WebMethod]
public static void StopSite(int siteId)
{
    HttpResponse response = HttpContext.Current.Response;
    try
    {
        // Doing something here
        response.Write("{{\"message\": \"action was successful!\"}}");
    }
    catch (Exception ex)
    {
        response.StatusCode = 500;
        response.Write("{{\"message\": \"action failed!\"}}");
    }
}

This way, what I'll get at client is:

{ "message": "action was successful!"} { "d": null}

Which means that ASP.NET is appending its success result to my JSON result. If on the other hand I flush the response after writing the success message, (like response.Flush();), the exception happens that says:

Server cannot clear headers after HTTP headers have been sent.

So, what to do to just get my JSON result, without changing the approach?

Saeed Neamati
  • 35,341
  • 41
  • 136
  • 188

2 Answers2

14

This works for me:

[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public void ReturnExactValueFromWebMethod(string AuthCode)
{
    string r = "return my exact response without ASP.NET added junk";
    HttpContext.Current.Response.BufferOutput = true;
    HttpContext.Current.Response.Write(r);
    HttpContext.Current.Response.Flush();
}
Sevin7
  • 6,296
  • 4
  • 23
  • 31
  • 2
    this lines helped me, but for me I have added these lines to make it works Response.Flush(); Response.End(); – Firas Nizam May 11 '15 at 00:46
  • 2
    ResponseEnd() cause “Thread was being aborted” This works for me! HttpContext.Current.Response.Flush(); HttpContext.Current.Response.SuppressContent = true; HttpContext.Current.ApplicationInstance.CompleteRequest(); http://stackoverflow.com/questions/20988445/how-to-avoid-response-end-thread-was-being-aborted-exception-during-the-exce – Evilripper Jul 03 '15 at 13:14
2

Why don't you return an object and then in your client you can call as response.d?

I don't know how you are calling your Web Service but I made an example making some assumptions:

I made this example using jquery ajax

function Test(a) {

                $.ajax({
                    type: "POST",
                    contentType: "application/json; charset=utf-8",
                    url: "TestRW.asmx/HelloWorld",
                    data: "{'id':" + a + "}",
                    dataType: "json",
                    success: function (response) {
                        alert(JSON.stringify(response.d));

                    }
                });
            }

And your code could be like this (you need to allow the web service to be called from script first: '[System.Web.Script.Services.ScriptService]'):

    [WebMethod]
    public object HelloWorld(int id)
    {
        Dictionary<string, string> dic = new Dictionary<string, string>();
        dic.Add("message","success");

        return dic;
    }

In this example I used dictionary but you could use any object with a field "message" for example.

I'm sorry if I missunderstood what you meant but I don't really understand why you want to do a 'response.write' thing.

Hope I've helped at least. :)

Jenninha
  • 1,357
  • 2
  • 20
  • 42