Question

I am trying to map the coordinates of the following JSON text on a Mapquest Map by calling an ASP.net method that returns this string, but I am unable to figure out how to extract the latitude and longitude from it.

{"d":"{\"results\":[{\"fullName\":\"Albert Pinto\",\"callType\":\"Other - See Comments\",\"comments\":\"He was not happy with our dealer\u0027 s service. Had to be pacified.\",\"geolatitude\":38.9661791,\"geolongitude\":-94.7185354,\"geolocation\":\"{\\\"places\\\":[{\\\"street1\\\":\\\"Bond St\\\",\\\"postalCode\\\":\\\"66214\\\",\\\"address\\\":\\\"8951 Bond St, Overland Park, KS 66214, , United States\\\",\\\"displayAddress\\\":\\\"8951 Bond St, Overland Park, KS 66214, , United States\\\",\\\"street\\\":\\\"Bond St\\\",\\\"countryCode\\\":\\\"US\\\",\\\"region2\\\":\\\"\\\",\\\"longitude\\\":\\\"-94.718535\\\",\\\"region1\\\":\\\"\\\",\\\"latitude\\\":\\\"38.966179\\\",\\\"country_code\\\":\\\"US\\\",\\\"country\\\":\\\"United States\\\",\\\"city\\\":\\\"Overland Park\\\"}],\\\"source\\\":{\\\"locationServicesEnabled\\\":true,\\\"hasCompass\\\":true,\\\"purpose\\\":\\\"Get Current Location\\\"},\\\"success\\\":true}\",\"address\":\"8951 Bond St, Overland Park, KS 66214, , United States\",\"createdAt\":\"2012-01-18T05:57:58.923Z\",\"updatedAt\":\"2012-01-18T05:57:58.923Z\",\"objectId\":\"cqJK1nF1sB\"}]}"}

I have googled for hours and tried several different approach (trying to return just a Lat/Long array from asp.net, trying to parse JSON using JQuery) but my limited knowledge of JavaScript seems to hinder any progress.

Any help or pointers will be greatly appreciated. Here is how my JavaScript looks like so far....

    <script type="text/javascript">

            MQA.EventUtil.observe(window, 'load', function () {

                $.ajax({
                    url: "Default.aspx/SendAnSMSMessage",   // This method returns the JSON string
                    type: "POST", // data has to be POSTed
                    contentType: "application/json", // posting JSON content    
                    dataType: "text",
                    //dataType: "JSON",  // type of data is JSON (must be upper case!)
                    timeout: 10000,    // AJAX timeout
                    success: function (result) {
                        console.log(result.toString()); //The JSON string is copied from the console here..
                        alert(result);

//NOT SURE WHAT TO DO NEXT HERE TO EXTRACT LAT/LONG.

                        /*Create a new POI collection.*/
                        var sc = new MQA.ShapeCollection(), poi, latlng = { lat: 39.0, lng: -82.0 }, i;

                        /*Create additional POIs and add them to the shape collection.*/
                        for (i = 0; i < 5; i++) {
                            latlng.lat = latlng.lat + 0.01;
                            latlng.lng = latlng.lng - 0.01;

                            poi = new MQA.Poi(latlng);
                            sc.add(poi);
                        }

                        /*Construct an instance of MQA.TileMap with the shape collection in the map constructor.*/
                        window.map = new MQA.TileMap({
                            elt: document.getElementById('map'),
                            collection: sc,
                            bestFitMargin: 100
                        });


                    },
                    error: function (xhr, status) {
                        alert(status + " - " + xhr.responseText);
                    }
                });

            });

        </script>

Here is the ASP.Net code that calls the REST API.

[WebMethod] public static string SendAnSMSMessage() 
{ 
var httpWebRequest = (HttpWebRequest)WebRequest.Create("//myurl"); 
httpWebRequest.ContentType = "application/json";
httpWebRequest.Credentials = new NetworkCredential("name", "pwd"); 
httpWebRequest.Method = "GET"; 
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse(); 
using (var streamReader = new StreamReader(httpResponse.GetResponseStream())) 
{
var responseText = streamReader.ReadToEnd(); 
return responseText;} 
}
Was it helpful?

Solution

After trying several different ways to figure out why my JavaScript was not able to traverse the result array for lat/long details, I gave up and moved the entire mapping logic to server side using the Reimers asp.net control.

This SO post was especially useful... Here is how my asp.net page looks like..

<body>
    <form id="form2" runat="server">

    <asp:Button ID="Button1" runat="server" onclick="Button1_Click" 
        Text="Update Locations" />
    <br /> 

    <asp:ScriptManager ID="ScriptManager1" runat="server">
    </asp:ScriptManager>
    <asp:UpdatePanel ID="UpdatePanel1" runat="server">
        <ContentTemplate>
            <Reimers:Map ID="Map1" runat="server" Width="800" Height="600" DefaultMapType="Normal" Zoom="7">            
            <Center Latitude="51.477" Longitude="0.0" /> 
            </Reimers:Map>
                <asp:GridView ID="GridView1" runat="server" CellPadding="4" ForeColor="#333333" 
                    GridLines="None">
                    <AlternatingRowStyle BackColor="White" ForeColor="#284775" />
                    <EditRowStyle BackColor="#999999" />
                    <FooterStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
                    <HeaderStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
                    <PagerStyle BackColor="#284775" ForeColor="White" HorizontalAlign="Center" />
                    <RowStyle BackColor="#F7F6F3" ForeColor="#333333" />
                    <SelectedRowStyle BackColor="#E2DED6" Font-Bold="True" ForeColor="#333333" />
                    <SortedAscendingCellStyle BackColor="#E9E7E2" />
                    <SortedAscendingHeaderStyle BackColor="#506C8C" />
                    <SortedDescendingCellStyle BackColor="#FFFDF8" />
                    <SortedDescendingHeaderStyle BackColor="#6F8DAE" />
                </asp:GridView>  
                <br />
        </ContentTemplate>

    </asp:UpdatePanel>
    </form>
</body>

and here is how the codebehind works...

 public void ParseJson(string jsonText)
    {
        JObject o = JObject.Parse(jsonText);
        JArray result = (JArray)o["results"];
        GridView1.DataSource = result;
        GridView1.DataBind();

        Double[,] strLocation = new Double[result.Count, 3];
        Reimers.Google.Map.Marker[] markers = new Reimers.Google.Map.Marker[result.Count];

        var centerLatLng = new Reimers.Google.Map.LatLng();

        for (int i = 0; i < result.Count; i++)
        {
            centerLatLng.Latitude = Convert.ToDouble(result[i]["geolatitude"].ToString());
            centerLatLng.Longitude = Convert.ToDouble(result[i]["geolongitude"].ToString());
            markers[i] = new Reimers.Google.Map.Marker(centerLatLng);
            markers[i].Title = result[i]["fullName"].ToString() + " - " + result[i]["callType"].ToString() +" : " + result[i]["comments"];
            Map1.Overlays.Add(markers[i]);

        }
        Map1.Center = markers[0].Point;
        var centerLatLng = new Reimers.Google.Map.LatLng();
        centerLatLng.Latitude = strLocation[1, 0];
        centerLatLng.Longitude = strLocation[1, 1];

        var marker = new Reimers.Google.Map.Marker(centerLatLng);
        Map1.Overlays.Add(marker);
    }

OTHER TIPS

Use $.parseJSON to parse the json string which you get in the ajax success handler. It will give you a JSON object. Using this object you can easily access latitude and longitude. Try this.

success: function (result) {
    //The JSON string is copied from the console here..
    console.log(result.toString()); 
    result = $.parseJSON(result);

    /*Create a new POI collection.*/
    var sc = new MQA.ShapeCollection(), poi, 
        latlng = { lat: result.d.results[0].geolocation.places[0].latitude, 
                   lng: result.d.results[0].geolocation.places[0].longitude }, 
        i;

    /*Create additional POIs and add them to the shape collection.*/
    for (i = 0; i < 5; i++) {
       latlng.lat = latlng.lat + 0.01;
       latlng.lng = latlng.lng - 0.01;

       poi = new MQA.Poi(latlng);
       sc.add(poi);
    }

    /*Construct an instance of MQA.TileMap with the shape collection 
    in the map constructor.*/
    window.map = new MQA.TileMap({
       elt: document.getElementById('map'),
       collection: sc,
       bestFitMargin: 100
    });
},

Take a look at using Douglas Crockford's popular JSON parser. I like using it, because it uses the browser's native JSON parser if it is available.

Also, ASP.NET returns JSON as a wrapped object for security reasons. Hence you will notice the JSON wrapped with a d parameter. You would then parse the JSON in your success callback like

// Parse the JSON result
result = JSON.parse(result);
if (result && result.hasOwnProperty("d"))
    result = result.d;

and access the latitude and longitude using

latlng = { lat: results[0].geolocation.places[0].latitude, lng: results[0].geolocation.places[0].longitude }

You could also setup a global jQuery ajax converter to parse the JSON before your success callback is executed. Something like

$.ajaxSetup({
    converters: { "text json": function (jsonData) {
            var result = JSON.parse(jsonData);

            if (result && result.hasOwnProperty("d"))
                result = result.d;

            return result;
        }
    }
});

Now in your callback you would just access the desired data as previously shown.

Calling asp.net web services is slightly different.

You need to set your ajax call's dataType to 'json' and then parse result.d, not result.

success: function (result) {
  result = $.parseJSON(result.d);
  // now use result like normal, using result, not result.d like you listed in your example.
}

How do you return your JSON object in the ASp.Net method, seems like you are returning it as a string. If you are returning it like this it won't be a problem for you to access properties of that object in java script.

return Jason(yourObject)

then you can access that object properties in javascript like this,

success: function (result) {
            alert(result.latitude);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top