Click here to Skip to main content
15,887,083 members
Articles / Web Development / ASP.NET
Tip/Trick

How to Return/Serialize JSON in VB.NET

Rate me:
Please Sign up or sign in to vote.
4.23/5 (4 votes)
23 Jan 2018CPOL4 min read 52.1K   5  
How to return Json in VB.NET in multiple ways

Introduction

As I started to based my web apps around sending json back and forth, I started to notice the many different ways there are to format and manipulate the responses. There seem to be three main ways to return json from an MVC app. Even the style of building the response within those three can differ with different features of the language. This tip will hopefully help me, as well as you to find a method that best fits our needs. If you know of any others, please let me know in the comments and I will try to include them.

Using the Code

I will show three different return types for Json responses:

  1. JsonResult - The preferred method to use when you have an object to send
  2. ContentResult - The preferred method when you have a serialized response (i.e., string) already
  3. String - Not preferred but still possible

JsonResult

*When looking at the JsonResult examples, you will see the json function set with the JsonRequestBehavior.AllowGet parameter passed. If this is left out of a GET, you will get a 500 message saying that the get method is insecure.*

If your database columns have the same names that you want your json properties to have, it is super easy to send back the response to the client using the json method to convert to a jsonresult and serialized to the client.

VB.NET
Function get_people_jsonresult(Optional id As Integer = 0) As JsonResult     
   Dim peoples = From c In db.dtb_people.OrderBy(Function(x) x.c_lastname).ToList
   Return Json(peoples, JsonRequestBehavior.AllowGet) 
End Function    

You can also just create a new JsonResult.

VB.NET
Function get_people_jsonresult(Optional id As Integer = 0) As JsonResult     
   Dim peoples = From c In db.dtb_people.OrderBy(Function(x) x.c_lastname).ToList
   Return New JsonResult With {.Data = peoples, .JsonRequestBehavior = JsonRequestBehavior.AllowGet}
End Function    

Since your database is probably not setup the same as your expected response, the most common way you'll see Json returned is by taking the data from a database and mapping it to a class. This class will then be serialized to the client. This is perfect if your class is setup to have the same properties as a class. You'll commonly see the classes using JsonProperty which is used to easily deserialize json from a client in order to map it to a class. Unfortunately, this can't be used the other way around and have the class names serialize to the jsonproperties. In that case, you can always create a new class.

VB.NET
Function get_people_jsonresult(Optional id As Integer = 0) As JsonResult     
   Dim peoples As New List(Of people)
   For Each c As dtb_people In db.dtb_people.OrderBy(Function(x) x.c_lastname).ToArray
       Dim peep As New people
       peep.firstname = c.c_firstname
       peep.lastname = c.c_lastname
       peep.id = c.c_Id
       peoples.Add(peep)
   Next 
   Return Json(peoples, JsonRequestBehavior.AllowGet) 
End Function    

Public Class class_people
        <JsonProperty(PropertyName:="fname")> Public Property firstname As String
        <JsonProperty(PropertyName:="lname")> Public Property lastname As String
        <JsonProperty(PropertyName:="id")> Public Property id As Integer
End Class

However, sometimes it is easier and more readable if the class is defined where it is actually used. Here, we see an anonymous class used to select and reassign column names from the list of rows in the database. I've also shortened the class definition using the with keyword. The Json function will, again, convert this to the expected json response as well.

VB.NET
Function get_people_jsonresult(Optional id As Integer = 0) As JsonResult
    Dim c As Object = From c In db.dtb_people.OrderBy(Function(x) x.c_lastname).ToList 
    Dim q = New With {
    .firstname = c.c_firstname,
    .lastname = c.c_lastname,
    .id = c.c_Id
    }
    Return Json(q, JsonRequestBehavior.AllowGet)
End Function

You can even go further to shorten this to my favorite version:

VB.NET
Function get_people_jsonresult(Optional id As Integer = 0) As JsonResult
    Dim q As Object = From c In db.dtb_people.OrderBy(Function(x) x.c_lastname).ToList Select New With {
    .firstname = c.c_firstname,
    .lastname = c.c_lastname,
    .id = c.c_Id
    }
    Return Json(q, JsonRequestBehavior.AllowGet)
End Function

All of these give the following output:

JavaScript
[
    {
      "firstname": "santa",
      "lastname": "clause",
      "id": 2
    },
    {
      "firstname": "john",
      "lastname": "smith",
      "id": 1
    }
  ]

When needing a single item vs. a list, you can reformat the query putting the select statement in the where clause and then picking the single element to return a non-array.

VB.NET
Function get_people_jsonresult(Optional id As Integer = 0) As JsonResult
    Dim q As Object = (From c In db.dtb_people.Where(Function(x) x.c_Id = id) Select New With {
        .firstname = c.c_firstname,
        .lastname = c.c_lastname,
        .id = c.c_Id
    }).Single()
    Return Json(q, JsonRequestBehavior.AllowGet)
End Function

Output:

JavaScript
{
    "firstname": "john",
    "lastname": "smith",
    "id": 1
  }

You can again separate the anonymous class if you prefer it that way:

VB.NET
Function get_people_jsonresult(Optional id As Integer = 0) As JsonResult
    Dim c As dtb_people = db.dtb_people.Where(Function(x) x.c_Id = 1).Single
    q = New With {
        .firstname = c.c_firstname,
        .lastname = c.c_lastname,
        .id = c.c_Id
    }
    Return Json(q, JsonRequestBehavior.AllowGet)
End Function

The Json function not only does classes, but it can also convert a multidimensional dictionary as well:

VB.NET
Function get_people_jsonresult(Optional id As Integer = 0) As JsonResult
    Dim c As dtb_people = db.dtb_people.Where(Function(x) x.c_Id = 1).Single
    Dim d As New Dictionary(Of String, String) From {
         {"firstname", c.c_firstname},
         {"lastname", c.c_lastname},
         {"id", c.c_Id}
     }
    Return Json(d, JsonRequestBehavior.AllowGet)
End Function

However, it is unable to convert a string! The reason is that it is expecting to serialize something. If you have a string, your content is already serialized.

However, if you must, you can deserialize it to a dictionary and then have the Json function serialize it again.

VB.NET
Function get_people_jsonresult(Optional id As Integer = 0) As JsonResult
    Dim c As dtb_people = db.dtb_people.Where(Function(x) x.c_Id = 1).Single
    'multiline string literal
    Dim jsonstr As String = "{
    'firstname':'" + c.c_firstname + "',
    'lastname':'" + c.c_lastname + "',
    'id':" + c.c_Id.ToString + "
    }"
   Dim d As Dictionary(Of String, String) = _
       JsonConvert.DeserializeObject(Of Dictionary(Of String, String))(jsonstr)
   Return Json(d, JsonRequestBehavior.AllowGet)
End Function

You can even skip the Json function and just create a new JsonResult directly:

VB.NET
Return New JsonResult With {.Data = JsonConvert.DeserializeObject_
(Of Dictionary(Of String, String))(jsonstr), .JsonRequestBehavior = JsonRequestBehavior.AllowGet}

ContentResult

The next most common return method would be ContentResult. ContentResult comes in where you would like to use a string either by manually creating one like that below. (If using double quotes, you need to escape them.)

VB.NET
Function get_people_ContentResult(Optional id As Integer = 0) As ContentResult
    Dim c As dtb_people = db.dtb_people.Where(Function(x) x.c_Id = 1).Single
    Dim jsonstr As String = "{
    ""firstname"":""" + c.c_firstname + """,
    ""lastname"":""" + c.c_lastname + """,
    ""id"":" + c.c_Id.ToString + "
    }"
    Return Content(jsonstr.Replace(vbCrLf, ""), "application/json")
End Function

Or if you are using the Newtonsoft library:

VB.NET
Function get_people_ContentResult(Optional id As Integer = 0) As ContentResult
    Dim c As dtb_people = db.dtb_people.Where(Function(x) x.c_Id = 1).Single
    Dim jsonstr As JObject = New JObject(
        New JProperty("firstname", c.c_firstname),
        New JProperty("lastname", c.c_lastname),
        New JProperty("id", c.c_Id)
    )
    Return Content(jsonstr.ToString(), "application/json")
End Function

Here, we are using the Content function to send the string as is without re-serializing it. Since it doesn't know what type of data is being sent, we need to specifiy the mime type.

String

However, there a number of other ways to serialize content. Instead of serializing using Content to return a ContentResult, you can use any of these other methods and return the string directly.

VB.NET
Function get_people_string(Optional id As Integer = 0) As String
    Dim c As dtb_people = db.dtb_people.Where(Function(x) x.c_Id = id).Single
    Dim m As Object = New With {.firstname = c.c_firstname, .lastname = c.c_lastname, .id = c.c_Id}
    Dim serializer As New Script.Serialization.JavaScriptSerializer()
    Return serializer.Serialize(m)
End Function

However, Microsoft suggests to use JSON.NET instead of this solution: https://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer.aspx

Here, I've used a string literal to assemble the string and call the response method directly.

VB.NET
Function get_people_string(Optional id As Integer = 0) As String
    Dim jsonstr2 As String = $"{{
        'firstname': '{c.c_firstname}',
        'lastname':'{c.c_lastname}' ,
        'id':{c.c_Id.ToString}
    }}"
    Response.Clear()
    Response.ContentType = "application/json; charset=utf-8"
    Response.Write(jsonstr)
    Response.End()
End Function

And one last function that can be used is the JsonConvert to serialize an object which requires the import of Newtonsoft.Json.

VB.NET
Function get_people_ContentResult(Optional id As Integer = 0) As String
    Dim d As New Dictionary(Of String, String) From {
         {"James", 9001},
         {"Jo", 3474},
         {"Jess", 11926}
     }
    Return JsonConvert.SerializeObject(d, Formatting.Indented)
End Function

Wow, that's a lot of different ways! Hopefully you find this useful.

History

  • 23rd January, 2018: Initial tip

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
I'm a Principal Performance Engineer who uses VB.Net, HTML, CSS, etc. to write automation tools and reports.

Comments and Discussions

 
-- There are no messages in this forum --