2

I have this url that i need to decode:

http://gistest:54321/default.aspx?data=%7B%22id%22:%2269403%22,%22longitude%22:%22-143.406417%22,%22latitude%22:%2232.785834%22,%22timestamp%22:%2223-10%2010:12%22%7D

This code changes every time

I use this code:

<%Response.Write(Request.QueryString.Item("data") )%><br/>
<%Response.Write(Request.QueryString.Item("id") )%><br/>
<%Response.Write(Request.QueryString.Item("longitude") )%><br/>
<%Response.Write(Request.QueryString.Item("latitude") )%><br/>
<%Response.Write(Request.QueryString.Item("timestamp") )%><br/>

But i only get this as output, maybe there is an option where to check if data is not null, and then i request.querystring the other parts in data:

{"id"="69403","longitude"="-143.406417","latitude"="32.785834","timestamp"="23-10 10:12"}

This is from

<%Response.Write(Request.QueryString.Item("data") )%>

David Raijmakers
  • 1,369
  • 1
  • 16
  • 40
  • "What am i doing wrong?" - the compiler/debugger should give you a few clues. Do you have any details of exceptions or errors you can provide us with? Haven't a clue where the issue is there without looking at some error details. –  Oct 03 '12 at 13:00
  • You need a way of testing the connection, testing the syntax of the query, testing the connection string etc. along with many other things that will need testing and debugging. Find a way to do that. This simple database issue is probably going to be the first of many if you don't find a way of debugging throughout projects. Just my bit of advice. –  Oct 03 '12 at 13:28
  • 1
    One problem is your Page Language="C#" at the top of the page, but your code is in VB. Change to Language="VB". – Jon Adams Oct 03 '12 at 13:48
  • You'll need a server that runs the ASP.NET. IIS or IIS Express or, for development, one of Visual Studio's built-in servers. Which one are you using? – Jon Adams Oct 03 '12 at 13:50

2 Answers2

1

I think the problem you are running into is that there only is one querystring parameter in the URL you posted, and that is data. The rest of the information is encoded in the data querystring value. The value stored in data almost looks like a JSON/Javascript object, except with an = in between the property names and values instead of a :.

So, basically you won't be able to use Request.QueryString to get the values of id, longitude, latitude, etc. I think your options are to either write some code to parse the value of data yourself or replace the = with : and use a JSON parser for .NET (i.e., the JavascriptSerializer class or JSON.net).

Personally, I would write a method in the codebehind that would return a Dictionary(Of String, Object). In that method just I would just change every "=" to a ":" and then use the JavaScriptSerializer provided with .NET to parse the string. I don't have an ASP.NET instance handy right now, but the following sample I threw together in LinqPad should illustrate the idea:

Sub Main
        Dim url = "http://gistest:54321/default.aspx?data=%7B%22id%22=%2269403%22,%22longitude%22=%22-143.406417%22,%22latitude%22=%2232.785834%22,%22timestamp%22=%2223-10%2010:12%22%7D"
        Dim uri = New Uri(url)
        Dim data = System.Web.HttpUtility.ParseQueryString(uri.Query)("data")
        Dim o = ParseData(data)
        Console.WriteLine(o("id"))
        Console.WriteLine(o("longitude"))
        Console.WriteLine(o("latitude"))
        Console.WriteLine(o("timestamp"))
End Sub

Function ParseData(data As String) As Dictionary(Of String, Object)
    Dim js = new System.Web.Script.Serialization.JavaScriptSerializer()
    Dim o = js.DeserializeObject(data.Replace("""=""", """:"""))
    ParseData = DirectCast(o, Dictionary(Of String, Object))
End Function

One thing to note about this approach is that I am expecting the url to be in the same format as what you posted. You may need to modify this method to make it more robust to handle different inputs.

If you drop the ParseData function into your codebehind, then something like the following code in your front page should give you the output you are looking for (again, sorry I don't have an ASP.NET instance to test with right now):

<%
    Dim o = ParseData(Request.QueryString.Item("data"))
    Response.Write(o("id"))
    Response.Write("<br />")
    Response.Write(o("longitude"))
    Response.Write("<br />")
    Response.Write(o("latitude"))
    Response.Write("<br />")
    Response.Write(o("timestamp"))
    Response.Write("<br />")
%>
rsbarro
  • 27,021
  • 9
  • 71
  • 75
  • Yes i changed the "=" to ":", so the string looks like this now: http://gistest:54321/default.aspx?data=%7B%22id%22:%2269403%22,%22longitude%22:%22-143.406417%22,%22latitude%22:%2232.785834%22,%22timestamp%22:%2223-10%2010:12%22%7D But the code is constantly changing. But when i use your code that is at the bottom it gives me that he doesnt know o, because that one ParseData @rsbarro – David Raijmakers Oct 30 '12 at 08:46
  • I cant quite figure out how to deseralise this json string. It is indeed a json string POST – David Raijmakers Oct 30 '12 at 09:44
1

I really hope I understood the problem correctly. I am assuming you require the values of each key within the query string key called Data? To do so I used the code below:

    Dim values() As String = Server.UrlDecode(Request.QueryString("data")).Replace("{", "").Replace("}", "").Split(New Char() {","}, StringSplitOptions.RemoveEmptyEntries)
    For Each value As String In values
        Dim keyValue() As String = value.Split(New Char() {":"}, StringSplitOptions.RemoveEmptyEntries)
        Response.Write(keyValue(0).Replace("""", "") & " : " & keyValue(1).Replace("""", "") & "<br/>")
    Next

In a nutshell, I decode the QueryString("data"), replace the braces and split the string into an array by using the comma as the first split character. We then end up with an array containing values in the following format "id":"649403".

Thereafter I iterate through the values and split one final time for each value based on the semi-colon (:) character.

With this method you can build and manipulate the data dynamically.

Code Edit

I replaced all references of ":" with "=" to ensure that the time stamp will be correctly retrieved and then split the key values based on =. You can use a select case to assign variables to values if necessary. (Obviously make sure your variable is not declared within the select as it will not be in the right scope for later use!)

If Request.QueryString("data") IsNot Nothing Then
    Dim values() As String = Request.QueryString("data").Replace("{", "").Replace("}", "").Replace(""":""", """=""").Split(New Char() {","}, StringSplitOptions.RemoveEmptyEntries)
    For Each value As String In values
        Dim keyValue() As String = value.Split(New Char() {"="}, StringSplitOptions.RemoveEmptyEntries)
        Response.Write(keyValue(0).Replace("""", "") & " : " & keyValue(1).Replace("""", "") & "<br/>")

        Select Case keyValue(0).ToLower()
            Case "id"
                Dim id As String = keyValue(1)
        End Select
    Next
End If

Reflection Edit

Create an instance of your object then retrieve all its properties (Dim properties() As PropertyInfo = myObj.GetType().GetProperties()). Iterate through the properties and set the value where the name is equal to the key. Don't forget to import the System.Reflection library.

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    Dim data As String = "%7B%22id%22:%2269403%22,%22longitude%22:%22-143.406417%22,%22latitude%22:%2232.785834%22,%22timestamp%22:%2223-10%2010:12%22%7D"
    If data IsNot Nothing Then

        Dim myObj As New MyObject
        Dim properties() As PropertyInfo = myObj.GetType().GetProperties()
        Dim values() As String = Server.UrlDecode(data).Replace("{", "").Replace("}", "").Replace(""":""", """=""").Split(New Char() {","}, StringSplitOptions.RemoveEmptyEntries)
        For Each value As String In values
            Dim keyValue() As String = value.Split(New Char() {"="}, StringSplitOptions.RemoveEmptyEntries)
            For Each prop As PropertyInfo In properties
                If prop.Name.ToLower = keyValue(0).ToLower.Replace("""", "") Then
                    prop.SetValue(myObj, keyValue(1), Nothing)
                End If
            Next
        Next

        myObj.Save()
    End If
End Sub


Public Class MyObject
    Private _ID As String
    Private _Longitude As String
    Private _Latitude As String
    Private _Timestamp As String

    Public Property ID As String
        Get
            Return _ID
        End Get
        Set(value As String)
            _ID = value
        End Set
    End Property

    Public Property Longitude As String
        Get
            Return _Longitude
        End Get
        Set(value As String)
            _Longitude = value
        End Set
    End Property

    Public Property Latitude As String
        Get
            Return _Latitude
        End Get
        Set(value As String)
            _Latitude = value
        End Set
    End Property

    Public Property Timestamp As String
        Get
            Return _Timestamp
        End Get
        Set(value As String)
            _Timestamp = value
        End Set
    End Property

    Public Sub Save()
        'Save logic here
    End Sub
End Class
Clarice Bouwer
  • 3,631
  • 3
  • 32
  • 55
  • Thank you for this code: i get this now: id : 69403 longitude : -143.406417 latitude : 32.785834 timestamp : 23-10 10 {"id":"69403","longitude":"-143.406417","latitude":"32.785834","timestamp":"23-10 10:12"} Only i need to make like: Dim id = that value.. – David Raijmakers Oct 30 '12 at 10:30
  • I Also don't get the timestamp correctly, it should be 23-1‌​0 10:12, but it is 23-10 10 – David Raijmakers Oct 30 '12 at 10:32
  • I have altered the code above to cater for the time stamp problem. I hope you come right. Shout if you need assistance with anything else. Regarding your variable assignment, if you don't come right with the above, give me more information regarding what exactly you need to do with your variables. – Clarice Bouwer Oct 30 '12 at 11:08
  • Ok, so if i want all Dim's for longitude i should use the Select Case function multiple times i guess – David Raijmakers Oct 30 '12 at 11:17
  • Yes, you would need to. Unless you want to use a collection object like a sorted list or array list. You could also take a look into reflection to make it more dynamic. http://social.msdn.microsoft.com/Forums/en-US/csharplanguage/thread/2e9b5d66-2738-4b3b-b33d-b57398541c14/ – Clarice Bouwer Oct 30 '12 at 11:20
  • Ok i still have a few questions and then i need to be ready i guess. Is it possible to let the value of id see in a label. And is the Dim id in the whole aspx file available for usage? – David Raijmakers Oct 30 '12 at 11:39
  • do you know if that is possible. I need to write it later in a database – David Raijmakers Oct 30 '12 at 11:54
  • With reflection it is definitely possible but I am no expert in it. Take a look at http://msdn.microsoft.com/en-us/magazine/cc163750.aspx, http://stackoverflow.com/questions/564816/reflection-setvalue-of-array-within-class and http://stackoverflow.com/questions/1456518/how-to-obtain-a-list-of-constants-in-a-class-and-their-values to see if you can find a conglomerate solution to your problem. It does not appear to difficult to implement. – Clarice Bouwer Oct 30 '12 at 12:11
  • I have added the reflection logic for you. Please mark this as the answer if it was indeed the answer to your question. I sincerely hope that I was able to help you. – Clarice Bouwer Oct 30 '12 at 12:42
  • Hello kleinkie, thanks for the edit, but i need to get the data from the url, because thats the value that changes, so i cant use the Dim data as string – David Raijmakers Oct 30 '12 at 12:45
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/18791/discussion-between-babboe-and-kleinkie) – David Raijmakers Oct 30 '12 at 12:51