7

I know I can achieve this with a ASHX handler, but i really need it from a page webmethod.

I'm calling a page webmethod from in page javascript using this code:

        $.ajax({ type: 'POST', url: '<%= ResolveUrl("~/teste-datatables.aspx/getdata") %>',data: '{ a: ' + id + '}', contentType: 'application/json; charset=utf-8', dataType: 'json',
                success: function (response) {
                        console.log( response);
                    },
                    error: function(XMLHttpRequest, textStatus, errorThrown) {
                        console.log('textStatus:' + textStatus);
                        console.log('errorThrown:' + errorThrown);
                        console.log(XMLHttpRequest);
                    }
            });

I have a JSON file teste.json (just to keep put database interactions and facilitate tests from you guys):

{
  "draw": 1,
  "recordsTotal": 57,
  "recordsFiltered": 57,
  "data": [
    [
      "Airi",
      "Satou",
      "Accountant",
      "Tokyo",
      "28th Nov 08",
      "$162,700"
    ],
    [
      "Angelica",
      "Ramos",
      "Chief Executive Officer (CEO)",
      "London",
      "9th Oct 09",
      "$1,200,000"
    ],
    [
      "Ashton",
      "Cox",
      "Junior Technical Author",
      "San Francisco",
      "12th Jan 09",
      "$86,000"
    ],
    [
      "Bradley",
      "Greer",
      "Software Engineer",
      "London",
      "13th Oct 12",
      "$132,000"
    ],
    [
      "Brenden",
      "Wagner",
      "Software Engineer",
      "San Francisco",
      "7th Jun 11",
      "$206,850"
    ],
    [
      "Brielle",
      "Williamson",
      "Integration Specialist",
      "New York",
      "2nd Dec 12",
      "$372,000"
    ],
    [
      "Bruno",
      "Nash",
      "Software Engineer",
      "London",
      "3rd May 11",
      "$163,500"
    ],
    [
      "Caesar",
      "Vance",
      "Pre-Sales Support",
      "New York",
      "12th Dec 11",
      "$106,450"
    ],
    [
      "Cara",
      "Stevens",
      "Sales Assistant",
      "New York",
      "6th Dec 11",
      "$145,600"
    ],
    [
      "Cedric",
      "Kelly",
      "Senior Javascript Developer",
      "Edinburgh",
      "29th Mar 12",
      "$433,060"
    ]
  ]
}

And tried several variations in webmethod...

Test1 Load JSON from file to string and then return it

<System.Web.Script.Services.ScriptMethod(ResponseFormat:=ResponseFormat.Json), System.Web.Services.WebMethod(True)>
Public Shared Function getdata(a As Integer) As String
    Dim path As String = HttpContext.Current.Server.MapPath("/teste.json")
    Dim jsonString As String = File.ReadAllText(path)
    Return jsonString.Replace(vbCr, "").Replace(vbLf, "")
End Function

The result is:

{d: "{  "draw": 1,  "recordsTotal": 57,  "recordsFilter ... gh",      "29th Mar 12",      "$433,060"    ]  ]}"}

Test2 Load JSON from file to string, convert it to datablesnet object and then serealize it and write to current context

<System.Web.Script.Services.ScriptMethod(ResponseFormat:=ResponseFormat.Json), System.Web.Services.WebMethod(True)>
Public Shared Sub getdata6(a As Integer)
    Dim path As String = HttpContext.Current.Server.MapPath("/teste.json")
    Dim jsonString As String = File.ReadAllText(path)
    Dim mytable As datatablesnet = Newtonsoft.Json.JsonConvert.DeserializeObject(Of datatablesnet)(jsonString)
    Dim serializer As New JavaScriptSerializer
    HttpContext.Current.Response.ContentType = "application/json"
    HttpContext.Current.Response.Write(serializer.Serialize(mytable))
End Sub

I get an error and analising the response i see that it was (was added in the end {"d":null}:

{"draw":1,"recordsTotal":57,"recordsFiltered":57,"data":[["Airi","Satou","Accountant","Tokyo","28th Nov 08","$162,700"],["Angelica","Ramos","Chief Executive Officer (CEO)","London","9th Oct 09","$1,200,000"],["Ashton","Cox","Junior Technical Author","San Francisco","12th Jan 09","$86,000"],["Bradley","Greer","Software Engineer","London","13th Oct 12","$132,000"],["Brenden","Wagner","Software Engineer","San Francisco","7th Jun 11","$206,850"],["Brielle","Williamson","Integration Specialist","New York","2nd Dec 12","$372,000"],["Bruno","Nash","Software Engineer","London","3rd May 11","$163,500"],["Caesar","Vance","Pre-Sales Support","New York","12th Dec 11","$106,450"],["Cara","Stevens","Sales Assistant","New York","6th Dec 11","$145,600"],["Cedric","Kelly","Senior Javascript Developer","Edinburgh","29th Mar 12","$433,060"]]}{"d":null}

Test3 Load JSON from file to string, convert it to datablesnet object and then serealize it and return it

<System.Web.Script.Services.ScriptMethod(ResponseFormat:=ResponseFormat.Json), System.Web.Services.WebMethod(True)>
Public Shared Function getdata5(a As Integer) As String
    Dim path As String = HttpContext.Current.Server.MapPath("/teste.json")
    Dim jsonString As String = File.ReadAllText(path)
    Dim mytable As datatablesnet = Newtonsoft.Json.JsonConvert.DeserializeObject(Of datatablesnet)(jsonString)
    Dim serializer As New JavaScriptSerializer

    Return serializer.Serialize(mytable)
End Function

The result is the same from Test1:

{d: "{  "draw": 1,  "recordsTotal": 57,  "recordsFilter ... gh",      "29th Mar 12",      "$433,060"    ]  ]}"}

I really need to get rid of the .d node, receiving the JSON directly from response and not from response.d. Is there any way I can achieve this from page webmethod ?

José Matos
  • 569
  • 4
  • 13
  • 2
    Have a look here: https://stackoverflow.com/questions/7227427/what-does-d-means-in-asp-net-webservice-response. It's a security hardening mechanism, so you probably don't want to change this. – Bluesight Aug 10 '18 at 10:51
  • You can write a wrapper javascript method to get proper JSON – Lali Aug 16 '18 at 14:10

2 Answers2

4

I really need to get rid of the .d node, receiving the JSON directly from response and not from response.d. Is there any way I can achieve this from page WebMethod?

Yes, there is. You can write the result directly to response:

<System.Web.Services.WebMethod(True)>
Public Shared Sub getdata(a As Integer)
    Dim path As String = HttpContext.Current.Server.MapPath("/teste.json")
    Dim jsonString As String = System.IO.File.ReadAllText(path)
    HttpContext.Current.Response.Clear()
    HttpContext.Current.Response.ContentType = "application/json; charset=utf-8"
    HttpContext.Current.Response.Write(jsonString)
    HttpContext.Current.Response.Flush()
    HttpContext.Current.Response.End()
End Sub

In case that you need to do it in multiple classes in your code, you can easily create a shared Sub WriteJsonToResponse(obj as Object) and in the body of the method, first serialize the obj to json using JavaScriptSerializer or Newtonsoft.JsonConvert, then write it to the response like above method.

Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
  • 2
    off-topic, but you also can switch to Web API and host Web API in your site, side by side of Web Forms. – Reza Aghaei Aug 12 '18 at 06:14
  • The answer is tested with the same file which you provided, without any problem. Let me know if you have any question about the answer. – Reza Aghaei Aug 17 '18 at 07:20
0

Mandarory use:

HttpContext.Current.Response.Flush()
HttpContext.Current.Response.End()

That solved my problem.

10 Rep
  • 2,217
  • 7
  • 19
  • 33
  • Isn't this advice already provided by Reza's answer (which actually attempts to educate researchers instead of simply dumping a snippet)? – mickmackusa Oct 09 '20 at 03:39