3

Firstly, I have already tried to find this answer on my own. I found a couple of pages on the topic:

http://forums.asp.net/t/1934999.aspx?Convert+any+json+string+to+an+array+or+object+in+c+ (This one uses a JSON string, and all, but it is an object and not an array of objects, so it doesn't seem to apply here).

Convert json to a C# array? (Here, it seems to have relevant answers, but none of them have helped me [probably because I am not handling this correctly on the server-side]).

Now, I have the following simple $.ajax request in jQuery:

$("#savePageBtn").click(function () {
    $.ajax({
        url: "/AJAX Pages/Compute_Save_Edit_Page.cshtml",
        async: false,
        type: "POST",
        data: { "objectArr": jsonArr }, //more on exactly what jsonArr contains below...
        success: function (response) {
            console.log(response);
        },
        error: function (jqXHR, textStatus, error) {
            alert("Oops! It appears there has been an AJAX error.\n\nPlease check the page you were attempting to edit.\n\n Error: " + textStatus + ".\n\nError Type: " + error + ".");
        }
    });
});

I have also tried: data: JSON.stringify(jsonArr), for the data line, but they both give me internal server errors of the code 500 when I try to access a property of a given object. Reading these errors, I can tell that the data is in "string" format (with JSON syntax, I'm sure) so I am not able to access the data as I would like. Even after I try to use C#'s Json.Decode method.

Here is the server-side code I have so far (Compute_Save_Edit_Page.cshtml):

@{
    Layout = "";

    if (IsAjax)
    {
        var reader = new StreamReader(Request.InputStream);
        var json = reader.ReadToEnd();
        var objectArr = Json.Decode(json);

        for (var i = 0; i < objectArr.Length; i++)
        {
<!--      -->@:@objectArr[i].objectName;
<!--      --><br/>
        }
    }
    else
    {
        Context.RedirectLocal("~/");
    }
}

I think I know what I need, but I can't seem to get anything to convert the JSON string back into an array of objects, like I want.

In jQuery I have been accessing this exactly like you would expect. To get the object name of an object at the first index, for instance, I would type: jsonArr[0].objectName

I would like to be able to get this accessible in much the same way once I have it on the server-side, but nothing I try works.

Additional Info:

It's appropriate to mention that the array of objects contains objects that don't all have the same properties (which is why trying the top answer in the second link I provided won't work, if I'm even understanding it correctly).

Here is a sample of a few objects in the array of objects (in no real particular syntax):

Object { 
    caption: "", 
    fileName: "Okmulgee_Library.jpg",
    objectID: "176",
    objectName: "Image",
    pageOrder: "1",
    size: "medium"
}

Object {
    alignment: "center",
    bold: false,
    italic: false,
    objectID: "177",
    objectName: "Paragraph",
    pageOrder: "2",
    underline: false,
    value: "For more information about the Okmulgee Public Library, call (918)-756-1448."
}

Object {
    bold: false,
    italic: false,
    objectID: "179",
    objectName: "Text",
    pageOrder: "3",
    underline: false,
    value: "Or visit their website at"
}

UPDATE FROM CHROME'S Network > Headers

Request URL:http://localhost:10226/AJAX%20Pages/Compute_Save_Edit_Page.cshtml
Request Method:POST
Status Code:500 Internal Server Error
Request Headersview source
Accept:application/json, text/javascript, */*; q=0.01
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Content-Length:0
Cookie:.ASPXAUTH=AEBDE22DCB622D796F8897945434328CECAEB25BF5D24CBA9CB1C32A58D82BC5CF68F33EF2CA7012DECFE87F91C39E7471DE7C2903CE476DF8781E0B0CE862C8AF10A23CD1B52BDFBA9042290426BBD024663A2D95C02A54EBA9E98D3DE25A44415395F5CDAA1E65A0EDDC3D9598F2A7660E3376159D82986E3E4EFEB05F150D02DC788D8F0FC0D62FF8B80708D05A276789A3D54DC79F598D57D19990426F68
Host:localhost:10226
Origin:http://localhost:10226
Referer:http://localhost:10226/CMS%20Interface/EditPages/E-UtilityBilling.cshtml
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36
X-Requested-With:XMLHttpRequest
Response Headersview source
Cache-Control:private
Content-Length:5732
Content-Type:text/html; charset=utf-8
Date:Fri, 25 Oct 2013 19:00:34 GMT
Server:Microsoft-IIS/7.5
X-AspNet-Version:4.0.30319
X-Powered-By:ASP.NET
X-SourceFiles:=?UTF-8?B?QzpcVXNlcnNcY3JhZGViYXVnaFxEb2N1bWVudHNcTXkgV2ViIFNpdGVzXE9rbXVsZ2VlIE9ubGluZSA0LjBcQUpBWCBQYWdlc1xDb21wdXRlX1NhdmVfRWRpdF9QYWdlLmNzaHRtbA==?=
Community
  • 1
  • 1
VoidKing
  • 6,282
  • 9
  • 49
  • 81
  • Are you using a Web API or ASP.NET MVC controller on the server side to receive the data? It would help to see the server code you're trying to get to parse the array. – Dave Swersky Oct 25 '13 at 15:00
  • @DaveSwersky I stated in the title (and in a tag) that I am using Web-Pages (as opposed to Web-Forms or MVC). Also, I'm not sure what you mean by "server code you're trying to get to parse the array." I'm showing you the receiving .cshtml page on the server-side, if that's what you mean. Other than that, I have no other server-side code, as of yet, that is relevant to this process. – VoidKing Oct 25 '13 at 15:02
  • @DaveSwersky (On an unrelated note), thanks for the upvote/noticing the effort I put in on making this question and before posting this question. – VoidKing Oct 25 '13 at 15:04
  • Have you debugged and inspected the value? Here is a question that includes the proper use of the IsAjax property: http://stackoverflow.com/questions/14609031/is-it-possible-webmatrix-crud-in-same-page-using-ajax – Dave Swersky Oct 25 '13 at 15:08
  • @DaveSwersky I use `if (IsAjax)` all the time. I assure you it is not the problem. It simply takes the branch if it is an AJAX request (rather than some yahoo *'pathing'* to the file in the browser or something). It isn't however recognized if the old straight JavaScript AJAX process is used for a reason that isn't quite clear to me. – VoidKing Oct 25 '13 at 15:12

2 Answers2

2

I think you'll find your data in the Request.InputStream. Try the following:

var reader = new StreamReader(Request.InputStream);
var json = reader.ReadToEnd();
var objArray= Json.Decode(json);

You will need to convert your Javascript object to JSON first by using JSON.stringify on it:

 data: JSON.stringify(jsonArr),
Mike Brind
  • 28,238
  • 6
  • 56
  • 88
  • Hey, Mike, how are you? I haven't had a chance to try this yet, but just wanted to say thanks for the response and I will try this as soon as I get a chance. – VoidKing Oct 25 '13 at 17:00
  • Okay, got a chance to try this, and it is still giving me an internal server error. This time it is on this line: `for (var i = 0; i – VoidKing Oct 25 '13 at 18:14
  • That suggests that the data is not available where I thought it was. Use the developer tools in IE or Chrome (just press F12) to examine the POST request and see what is being sent to the server. – Mike Brind Oct 25 '13 at 18:50
  • I can use developer tools (what I know of it), but I'm not sure if I'm getting what you are asking for or not, but I do see this: `send b.extend.ajax (anonymous function) b.event.dispatch v.handle` – VoidKing Oct 25 '13 at 18:58
  • In Chrome, you should go to Network > Headers > Request Payload. See if anything that looks like your JSON is there. – Mike Brind Oct 25 '13 at 19:12
  • I went to Chrome's "Network" > "Headers" But I did not see anything that said "Request Payload". I have updated my post again to show everything in the "Network" > "Headers" space. – VoidKing Oct 25 '13 at 19:17
  • I also tried adding `contentType: "json"` to the jquery ajax call, but to no avail. – VoidKing Oct 25 '13 at 19:20
  • I would say based off of the line `Content-Length:0` and the fact that writing back the response as both `@:@Request.InputStream` and `@:@Request["jsonArr"]` yielded what seemed like a couple of spaces, that what I expected I sent to the server wasn't what I thought it was. I know that jsonArr is populated with several objects when sent, so are you sure I am sending the data correctly? I just used `data: { "objectArr": jsonArr }`. – VoidKing Oct 25 '13 at 20:02
  • Actually scratch that, I made a small mistake. When I use `@:@Request.InputStream` I get `System.Web.HttpInputStream` as a response. – VoidKing Oct 25 '13 at 20:03
  • Hey Mike, thanks for the help. It seemed we were missing (JSON.stringify) on the client-side AJAX request (see my posted answer below). P.S. If you add this to your answer, I'll accept. +1 for your answer on how to receive this data either way. – VoidKing Oct 25 '13 at 21:18
  • Hey, Mike, sorry to bug you again on this question, but I really want to accept an answer here and I'd rather not accept my own. It was, after all, with your help that I got this done, and I'd rather you have the rep., but adding the `JSON.stringify()` to the json array in the jQuery code was pivotal here, and should be added to an acceptable answer. I know, you probably aren't worried about the few points or anything, I just feel like it's the least I can do for you helping me out here (I was really stuck). Anyway, just thought I'd remind you that you can gain a few easy points here. – VoidKing Oct 29 '13 at 13:50
0

Okay, I think I've finally got it.

I decided to try something I had tried previous to posting this question: JSON.stringify in the AJAX call (apparently jQuery doesn't automatically format the data based on contentType nor simply detecting the kind of data that it is).

The problem before was that I had NO idea that I would be able to find my data on the server-side with Request.InputStream. In fact, I am still not clear as to why or when data could be found in this manner or even what determines that it should be stored there as opposed to something that could be called by, say, Request.Form["objectArr"], etc.

So, when I tried to use JSON.stringify this time, I combined that with what Mike had posted in his answer for how to retrieve this server-side (i.e., using the Request.InputStream method).

Once I used both (as well as, removing the identifier in the data: portion of the ajax call), I started to see and even return relevant data.

In short, here is what I have now that works...

The jQuery AJAX code:

$.ajax({
    url: "/AJAX Pages/Compute_Save_Edit_Page.cshtml",
    async: false,
    type: "POST",
    data: JSON.stringify(jsonArr),
    success: function (response) {
        console.log(response);
    },
    error: function (jqXHR, textStatus, error) {
        alert("Oops! It appears there has been an AJAX error.\n\nPlease check the page you were attempting to edit.\n\nError Type: " + error + ".");
    }
});

And here is the server-side (C#) code that simply returns two properties of each object in the array:

@{
   Layout = "";

    if (IsAjax)
    {
        var reader = new StreamReader(Request.InputStream);
        var json = reader.ReadToEnd();
        var objectArr = Json.Decode(json);

        for (var i = 0; i < objectArr.Length; i++)
        {
@:@objectArr[i].objectName - @objectArr[i].objectID
        }
    }
    else
    {
        Context.RedirectLocal("~/");
    }
}

So, if I understand it correctly (and PLEASE correct me if I'm wrong), you CAN'T just send an array of objects to the server with AJAX. In fact, I wouldn't be surprised if you couldn't even send a array, at all. But you CAN send a simple variable like string or int. So, using JSON.stringify, I am using a function that translates the array of objects into one large JSON string, reading the input stream on the other side with C#, and then using another C# method to parse the JSON string back into an array of objects, which was how I wanted the data.

Thanks to all who helped me through this one, and for what it's worth, I really feel like I even learned something about the very purpose of JSON in the web environment today.

VoidKing
  • 6,282
  • 9
  • 49
  • 81
  • You can actually post plain JSON objects including arrays. Arrays will appear on the server as a comma-separated values. Plain object gets serialised to name/value pairs. I will blog about it shortly. – Mike Brind Oct 29 '13 at 20:22