70729

VB.net deserialize, JSON Conversion from type 'Dictionary(Of String,Object)' to type '

So I have looked at many posts, but I am still struggling with serializing this JSON object into classes. The JSON structure is this

{"value":{"HashTag":"12342345636","companyname":"my test company","LeadDetail":{"id":"1","firstname":"john","lastname":"clark","email":"emak@mai.com","phone":"9874534444"}}}

My class structure is as follows:

<Serializable> _ Public Class LeadDetailCall Public Property Hash() As String Get Return m_Hash End Get Set(value As String) m_Hash = value End Set End Property Private m_Hash As String = "" Public Property CompanyName() As String Get Return _CompanyName End Get Set(value As String) _CompanyName = value End Set End Property Private _CompanyName As String = "" Public Property Details() As List(Of LeadDetail) Get Return _Details End Get Set(ByVal value As List(Of LeadDetail)) _Details = value End Set End Property Private _Details As List(Of LeadDetail) End Class <Serializable> _ Public Class LeadDetail Private _id As String = "" Private _firstname As String = "" Private _lastname As String = "" Private _email As String = "" Private _phone As String = "" Public Property id() As String Get Return _id End Get Set(value As String) _id = value End Set End Property Public Property firstname() As String Get Return _firstname End Get Set(ByVal value As String) _firstname = value End Set End Property Public Property lastname() As String Get Return _lastname End Get Set(ByVal value As String) _lastname = value End Set End Property Public Property email() As String Get Return _email End Get Set(ByVal value As String) _email = value End Set End Property Public Property phone() As String Get Return _phone End Get Set(ByVal value As String) _phone = value End Set End Property End Class

I call like so:

<WebMethod()> _ Public Function SendLeadDetails(ByVal value As Object) As UpdateResponse Dim CurCall As LeadDetailCall = JsonConvert.DeserializeObject(Of LeadDetailCall)(value) End Function

What have I tried? Using the JavaScriptSerializer, using http://jsontodatacontract.azurewebsites.net/ crawling stackoverflow for examples. So many things that at this point I am flustered. So I continuously get the following invalid cast exception error.

Conversion from type 'Dictionary(Of String,Object)' to type 'String' is not valid.

If anyone can help me out I would be very appreciative :)

Answer1:

The JSON provided only has one element, so it will result in a collection (dictionary) of one. I added an "item" to be sure the code below worked and for illustration purposes. Proper indentation makes things easier to follow:

{ "foo": { "HashTag": "12342345636", "companyname": "my test company", "LeadDetail": { "id": "1", "firstname": "ziggy", "lastname": "clark", "email": "emak@mai.com", "phone": "9874534444" } }, "bar": { "HashTag": "02342345636", "companyname": "my test company2", "LeadDetail": { "id": "1", "firstname": "john", "lastname": "clark", "email": "emak@mai.com", "phone": "1874534444" } } }

Starting with the most deeply indented, it is easy to see a LeadDetail class with {ID, FirstName, etc). With more than one item (as in mine), this would repeat.

Then there are "foo" and "bar" objects with a little data and a LeadDetail object. When you use any of the Robots, they will create a class for each. Mine would be named "foo" and "bar" but otherwise be identical. In the code below, I condensed this to one class named "Item". Then you can treat them (Foo and Bar) as a Dictionary(of String, Item) where their names are the keys.

But there is one more, less obvious class/Type: The outer most {..}. The robot tools will create a class named "Example" or "RootObject". You dont need it or want it for a dictionary:

' modified from VS's EDIT -> Paste Special -> JSON as Classes Public Class Item Public Property HashTag As String Public Property companyname As String Public Property LeadDetail As Leaddetail End Class Public Class Leaddetail Public Property id As String Public Property firstname As String Public Property lastname As String Public Property email As String Public Property phone As String End Class

Then the code:

Dim jstr As String = ... ' use the Item/Value class not the container Dim myJ = JsonConvert.DeserializeObject(Of Dictionary(Of String, Item))(jstr) ' print some of the data For Each kvp As KeyValuePair(Of String, Item) In myJ Console.WriteLine("key {0}, CompName {1}, Contact: {2}", kvp.Key, kvp.Value.companyname, kvp.Value.LeadDetail.firstname) Next

Output:

key: foo, CompName: my test company, Contact: ziggy key: bar, CompName: my test company2, Contact: john

If you run it on your original JSON, you get a dictionary of one.

<div class="grid mb0 fw-wrap ai-start jc-end gs8 gsy"> <div class="grid--cell mr16" style="flex: 1 1 100px;"> <div class="post-menu">share<span class="lsep">|</span>improve this answer <div class="post-signature grid--cell fl0"> <div class="user-info "> <div class="user-action-time"> edited <span title="2017-03-19 13:15:00Z" class="relativetime">Mar 19 '17 at 13:15</span> <div class="user-gravatar32"> <div class="user-details"> <div class="-flair"> <div class="post-signature grid--cell fl0"> <div class="user-info user-hover"> <div class="user-action-time"> answered <span title="2015-04-24 14:27:35Z" class="relativetime">Apr 24 '15 at 14:27</span> <div class="user-gravatar32"> <div class="gravatar-wrapper-32"><img src="https://i.stack.imgur.com/DRURw.png?s=32&g=1" alt="" width="32" height="32"> <div class="user-details"> Plutonix <div class="-flair"> <span class="reputation-score" title="reputation score 34,760" dir="ltr">34.8k</span><span title="11 gold badges"><span class="badge1"></span><span class="badgecount">11</span></span><span title="36 silver badges"><span class="badge2"></span><span class="badgecount">36</span></span><span title="92 bronze badges"><span class="badge3"></span><span class="badgecount">92</span></span> <div class="post-layout--right"> <div id="comments-29850101" class="comments js-comments-container ">
    <li id="comment-47827058" class="comment js-comment " data-comment-id="47827058"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="number of 'useful comment' votes received" class="cool">1</span> <div class="comment-text js-comment-text-and-form"> <div class="comment-body" style="display: block;" > <span class="comment-copy">Awesomeness :) cause I actually understand that exception error now</span> – Keith Beard <span class="comment-date" dir="ltr"><span title="2015-04-24 14:47:31Z" class="relativetime-clean">Apr 24 '15 at 14:47</span></span> </li> <li id="comment-47827594" class="comment js-comment " data-comment-id="47827594"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <div class="comment-text js-comment-text-and-form"> <div class="comment-body" style="display: block;" > <span class="comment-copy">OMG in hind sight it was sooo clear</span> – Keith Beard <span class="comment-date" dir="ltr"><span title="2015-04-24 14:57:32Z" class="relativetime-clean">Apr 24 '15 at 14:57</span></span> </li> <li id="comment-47827732" class="comment js-comment " data-comment-id="47827732"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <div class="comment-text js-comment-text-and-form"> <div class="comment-body" style="display: block;" > <span class="comment-copy">Sometimes when you are lost in the forest it is hard to see the trees ;)</span> – Plutonix <span class="comment-date" dir="ltr"><span title="2015-04-24 15:00:10Z" class="relativetime-clean">Apr 24 '15 at 15:00</span></span> </li> <li id="comment-55475195" class="comment js-comment " data-comment-id="55475195"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <div class="comment-text js-comment-text-and-form"> <div class="comment-body" style="display: block;" > <span class="comment-copy">@Plutonix: Facing a same issue in this question but unable to sort it out. Can you please take a look on it.</span> – A.K <span class="comment-date" dir="ltr"><span title="2015-11-22 13:53:13Z" class="relativetime-clean">Nov 22 '15 at 13:53</span></span> </li> </ul> <div id="comments-link-29850101" data-rep=50 data-anon=true> add a comment<span class="js-link-separator dno"> | </span> <div id="dfp-mlb" class="everyonelovesstackoverflow everyoneloves__mid-leaderboard"> <div id="answer-29849208" class="answer" data-answerid="29849208" itemscope itemtype="http://schema.org/Answer"> <div class="post-layout"> <div class="votecell post-layout--left"> <div class="vote"> <input type="hidden" name="_id_" value="29849208"> up vote <span itemprop="upvoteCount" class="vote-count-post ">0</span> down vote <div class="answercell post-layout--right">

    Your classes don't seem to correspond properly to your Json.

    Using http://jsonutils.com/, it suggested that your classes should look like this:

    Public Class LeadDetail Public Property id As String Public Property firstname As String Public Property lastname As String Public Property email As String Public Property phone As String End Class Public Class Value Public Property HashTag As String Public Property companyname As String Public Property LeadDetail As LeadDetail End Class Public Class LeadDetailCall Public Property value As Value End Class <div class="grid mb0 fw-wrap ai-start jc-end gs8 gsy"> <div class="grid--cell mr16" style="flex: 1 1 100px;"> <div class="post-menu">share<span class="lsep">|</span>improve this answer <div class="post-signature grid--cell fl0"> <div class="user-info user-hover"> <div class="user-action-time"> answered <span title="2015-04-24 13:46:59Z" class="relativetime">Apr 24 '15 at 13:46</span> <div class="user-gravatar32"> <div class="gravatar-wrapper-32"><img src="https://www.gravatar.com/avatar/ea09548513a626ee8166f6be61118354?s=32&d=identicon&r=PG" alt="" width="32" height="32"> <div class="user-details"> Hans Olsson <div class="-flair"> <span class="reputation-score" title="reputation score 43,604" dir="ltr">43.6k</span><span title="11 gold badges"><span class="badge1"></span><span class="badgecount">11</span></span><span title="78 silver badges"><span class="badge2"></span><span class="badgecount">78</span></span><span title="102 bronze badges"><span class="badge3"></span><span class="badgecount">102</span></span> <div class="post-layout--right"> <div id="comments-29849208" class="comments js-comments-container ">
      <li id="comment-47824494" class="comment js-comment " data-comment-id="47824494"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <div class="comment-text js-comment-text-and-form"> <div class="comment-body" style="display: block;" > <span class="comment-copy">Still getting the invalid cast exception though,</span> – Keith Beard <span class="comment-date" dir="ltr"><span title="2015-04-24 13:50:35Z" class="relativetime-clean">Apr 24 '15 at 13:50</span></span> </li> <li id="comment-47824812" class="comment js-comment " data-comment-id="47824812"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <span title="number of 'useful comment' votes received" class="cool">1</span> <div class="comment-text js-comment-text-and-form"> <div class="comment-body" style="display: block;" > <span class="comment-copy">@kcbeard Don't know then. I'd suggest that instead of starting with the nested Json you have above, start with something very basic, like {"value":"test"} and see if you can get that to work, and if so, make the json a bit more complicated one thing at a time.</span> – Hans Olsson <span class="comment-date" dir="ltr"><span title="2015-04-24 13:56:52Z" class="relativetime-clean">Apr 24 '15 at 13:56</span></span> </li> <li id="comment-47826032" class="comment js-comment " data-comment-id="47826032"> <div class="js-comment-actions comment-actions"> <div class="comment-score"> <div class="comment-text js-comment-text-and-form"> <div class="comment-body" style="display: block;" > <span class="comment-copy">I had to serialize it to a string then deserialize the string to my object to get it to work</span> – Keith Beard <span class="comment-date" dir="ltr"><span title="2015-04-24 14:24:33Z" class="relativetime-clean">Apr 24 '15 at 14:24</span></span> <span title="this comment was edited 2 times"> <svg aria-hidden="true" class="svg-icon va-text-bottom o50 iconPencilSm" width="14" height="15" viewBox="0 0 14 15"></svg> </span> </li> </ul> <div id="comments-link-29849208" data-rep=50 data-anon=true> add a comment<span class="js-link-separator dno"> | </span> <form id="post-form" action="/questions/29849015/answer/submit" method="post" class="post-form"> <input type="hidden" id="post-id" value="29849015" /> <input type="hidden" id="qualityBanWarningShown" name="qualityBanWarningShown" value="false" /> <input type="hidden" name="referrer" value=""/> <h2 class="space">Your Answer <script> StackExchange.ifUsing("editor", function () { StackExchange.using("externalEditor", function () { StackExchange.using("snippets", function () { StackExchange.snippets.init(); }); }); }, "code-snippets"); </script> <script> StackExchange.ready(function() { var channelOptions = { tags: "".split(" "), id: "1" }; initTagRenderer("".split(" "), "".split(" "), channelOptions); StackExchange.using("externalEditor", function() { // Have to fire editor after snippets, if snippets enabled if (StackExchange.settings.snippets.snippetsEnabled) { StackExchange.using("snippets", function() { createEditor(); }); } else { createEditor(); } }); function createEditor() { StackExchange.prepareEditor({ heartbeatType: 'answer', convertImagesToLinks: true, noModals: false, showLowRepImageUploadWarning: true, reputationToPostImages: 10, bindNavPrevention: true, postfix: "", onDemand: true, discardSelector: ".discard-answer" ,immediatelyShowMarkdownHelp:true }); } }); </script> <div id="post-editor" class="post-editor js-post-editor wz-element" data-wz-state="3,4,5,6,7,8"> <div style="position: relative;"> <div class="wmd-container"> <div id="wmd-button-bar" class="wmd-button-bar btr-sm"> <textarea id="wmd-input" class="wmd-input wz-element s-input bar0" name="post-text" cols="92" rows="15" tabindex="101" data-wz-state="8" data-min-length=""></textarea> <div class="fl" style="margin-top: 8px; height:24px;">  <div id="draft-saved" class="draft-saved community-option fl" style="margin-top: 8px; height:24px; display:none;">draft saved <div id="draft-discarded" class="draft-discarded community-option fl" style="margin-top: 8px; height:24px; display:none;">draft discarded <div id="wmd-preview" class="wmd-preview"> <div> <div class="edit-block"> <input id="fkey" name="fkey" type="hidden" value="1d73f6267369c77a2dbe2f1087a85481ed2fc3af2d77fd88bc7b680c0e07029a"> <input id="author" name="author" type="text"> <div style="position: relative;"> <div class="form-item dno new-post-login"> <div class="new-login-form"> <div class="new-login-left">

      Sign up or log in

      <script> StackExchange.ready(function () { StackExchange.helpers.onClickDraftSave('#login-link'); var $window = $(window), onScroll = function(e) { var $elem = $('.new-login-left'), docViewTop = $window.scrollTop(), docViewBottom = docViewTop + $window.height(), elemTop = $elem.offset().top, elemBottom = elemTop + $elem.height(); if ((docViewTop < elemTop) && (docViewBottom > elemBottom)) { StackExchange.using('gps', function() { StackExchange.gps.track('embedded_signup_form.view', { location: 'question_page' }); }); $window.unbind('scroll', onScroll); } }; $window.on('scroll', onScroll); }); </script> <div class="preferred-login google-login" data-ga="["sign up","Sign Up Started - Google","New Post",null,null]"> <svg aria-hidden="true" class="svg-icon native iconGoogle" width="18" height="18" viewBox="0 0 18 18"></g></svg> Sign up using Google <div class="preferred-login facebook-login" data-ga="["sign up","Sign Up Started - Facebook","New Post",null,null]"> <svg aria-hidden="true" class="svg-icon iconFacebook" width="18" height="18" viewBox="0 0 18 18"></svg> Sign up using Facebook <div class="preferred-login stackexchange-login" data-ga="["sign up","Sign Up Navigation","New Post",null,null]"> <svg aria-hidden="true" class="svg-icon native iconLogoGlyphXSm" width="18" height="18" viewBox="0 0 18 18"></g></svg> Sign up using Email and Password <input type="hidden" name="manual-openid" class="manual-openid" /> <input type="hidden" name="use-facebook" class="use-facebook" value="false" /> <input type="hidden" name="use-google" class="use-google" value="false" /> <input type="button" class="submit-openid" value="Submit" style="display:none" /> <div class="new-login-right">

      Post as a guest

      <div class="form-item"> <table> <tr> <td class="vm"> <div> <label for="display-name">Name</label> <input id="display-name" name="display-name" type="text" size="30" maxlength="30" value="" tabindex="105"> <div> <label for="m-address">Email</label> <input id="m-address" name="m-address" type="email" size="30" maxlength="100" value="" tabindex="106" placeholder="required, but never shown" /> </td> </tr> </table> <script> StackExchange.ready( function () { StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f29849015%2fvb-net-deserialize-json-conversion-from-type-dictionaryof-string-object-to%23new-answer', 'question_page'); } ); </script>

Recommend

  • Selenium File Chooser with a hidden input[type=file]
  • JGAP Robocode User Guide
  • Deserialize a json field with different data types without using Newtonsoft json but with System.Web
  • Simulate keypress in java to write user inputs to another application
  • How to parse JSON received in MVC Controller
  • Create list of objects from Json object with objects in xamarin for Android
  • MySQL Invalid query: Too high level of nesting for select
  • Get Distinct rows from a result of JOIN in SQL Server
  • Deserializing this JSON response to C#
  • How do I conditionally select a field from one of two tables?
  • How to trigger a KeyPressed event for unit testing in JAVA
  • windows batch file combine csv in a folder by column
  • cannot load gems in test environment
  • Deployments not visible in Kubernetes Dashboard
  • php show all images in directory and sort by last modified
  • Deduce parent class of inherited method in C++
  • EF 4.1 DBContext AutoDetectChangesEnabled
  • How do I remove all but some records based on a threshold?
  • Basic many-to-many left join query
  • Hide HTML elements without javascript, only CSS
  • Do I need to seed any random number generator before using EVP_PKEY_keygen of OpenSSL?
  • Array with custom indexes in Ionic2
  • How Lists (specifically, RecyclerView with CardViews) in Android work
  • How to add git credentials to the build so it would be able to be used within a shell code?
  • Android - Material Design - NavigationView - How to put vertical scroll?
  • Installed module is empty
  • Transactional Create with Validation in ServiceStack Redis Client
  • Change multiple background-images with jQuery
  • Why is an OPTIONS request sent to the server?
  • Align navbar back button on right side
  • Window Size for Mac application
  • Check if a string to interpolate provides expected placeholders
  • Javascript + PHP Encryption with pidCrypt
  • How can I get HTML syntax highlighting in my editor for CakePHP?
  • Why can't I rebase on to an ancestor of source changesets if on a different branch?
  • How do I configure my settings file to work with unit tests?
  • IndexOutOfRangeException on multidimensional array despite using GetLength check
  • Binding checkboxes to object values in AngularJs
  • Unable to use reactive element in my shiny app
  • How to push additional view controllers onto NavigationController but keep the TabBar?