Thursday, August 8, 2013

Web Essentials Goodness - Paste XML/JSON As Classes

I recently have been working on project where I have been evaluating some vendor APIs. Across the multiple vendors the responses have been in either XML or JSON. Since I am most familiar with .NET development, I have been creating my testing clients in C# after verifying the responses from the API with Fiddler. So in many cases once I have seen the XML/JSON output, I want to be able to download that data into my application as a class. Thankfully, the Web Essentials Visual Studio extension by Mads Kristensen, includes two excellent options. Paste XML As Classes and Paste JSON As Classes. With these two options ( from the File->Paste Special menu) when you have a class open you can paste any JSON or XML object and the extension will generate a class that corresponds to the document for you. In some cases (especially with XML) you may need to perform some additional clean up of local variable names, etc. But in the long run this has saved me lots of keystrokes. Below are a couple of examples.

JSON Object
{
"parameters":{
"tbdb":"nasapoc",
"service":"prefix",
"template":"service.json",
"term_prefix":"11"
},
"termHints":[
{
"name":"Soyuz T11",
"id":"OMII0IIN2112985674",
"index":"nasapoc",
"values":[
{
"value":"T-11",
"pre_em":"T-",
"em":"11",
"post_em":"",
"nature":"NPT",
"id":"OMII0II957832499"
}
],
"facets":[
{"id":"OMII0IIN417970619","name":"Programs & Missions"},
{"id":"OMII0IIN708454495","name":"Organizations"}
]},
{
"name":"Soyuz TM11",
"id":"OMII0II1817708082",
"index":"nasapoc",
"values":[
{
"value":"TM-11",
"pre_em":"TM-",
"em":"11",
"post_em":"",
"nature":"NPT",
"id":"OMII0IIN1708344299"
}
],
"facets":[
{"id":"OMII0IIN417970619","name":"Programs & Missions"},
{"id":"OMII0IIN708454495","name":"Organizations"}
]},
{
"name":"Soyuz TMA11",
"id":"OMII0II402255746",
"index":"nasapoc",
"values":[
{
"value":"TMA-11",
"pre_em":"TMA-",
"em":"11",
"post_em":"",
"nature":"NPT",
"id":"OMII0IIN564231465"
}
],
"facets":[
{"id":"OMII0IIN417970619","name":"Programs & Missions"},
{"id":"OMII0IIN708454495","name":"Organizations"}
]},
{
"name":"Apollo 11",
"id":"OMII0IIN408999708",
"index":"nasapoc",
"values":[
{
"value":"Apollo 11",
"pre_em":"Apollo ",
"em":"11",
"post_em":"",
"nature":"PT",
"id":"OMII0IIN408999708"
}
],
"facets":[
{"id":"OMII0IIN417970619","name":"Programs & Missions"}
]},
{
"name":"Expedition 11",
"id":"OMII0II1043857968",
"index":"nasapoc",
"values":[
{
"value":"Expedition 11",
"pre_em":"Expedition ",
"em":"11",
"post_em":"",
"nature":"PT",
"id":"OMII0II1043857968"
}
],
"facets":[
{"id":"OMII0IIN417970619","name":"Programs & Missions"}
]},
{
"name":"Group 11",
"id":"OMII0II1304089265",
"index":"nasapoc",
"values":[
{
"value":"Group 11",
"pre_em":"Group ",
"em":"11",
"post_em":"",
"nature":"PT",
"id":"OMII0II1304089265"
}
],
"facets":[
{"id":"OMII0IIN1655901465","name":"People"}
]},
{
"name":"ISS Assembly Mission 11A",
"id":"OMII0IIN1793710402",
"index":"nasapoc",
"values":[
{
"value":"ISS Assembly Mission 11A",
"pre_em":"ISS Assembly Mission ",
"em":"11",
"post_em":"A",
"nature":"PT",
"id":"OMII0IIN1793710402"
}
],
"facets":[
{"id":"OMII0IIN417970619","name":"Programs & Missions"}
]},
{
"name":"Lunar Module 11",
"id":"OMII0II962622437",
"index":"nasapoc",
"values":[
{
"value":"Lunar Module 11",
"pre_em":"Lunar Module ",
"em":"11",
"post_em":"",
"nature":"PT",
"id":"OMII0II962622437"
}
],
"facets":[
{"id":"OMII0IIN81023276","name":"Systems & Equipment"}
]},
{
"name":"Mir expedition crew 11",
"id":"OMII0II74828100",
"index":"nasapoc",
"values":[
{
"value":"Mir expedition crew 11",
"pre_em":"Mir expedition crew ",
"em":"11",
"post_em":"",
"nature":"PT",
"id":"OMII0II74828100"
}
],
"facets":[
{"id":"OMII0IIN417970619","name":"Programs & Missions"},
{"id":"OMII0IIN708454495","name":"Organizations"}
]},
{
"name":"Orion 11",
"id":"OMII0II800124355",
"index":"nasapoc",
"values":[
{
"value":"Orion 11",
"pre_em":"Orion ",
"em":"11",
"post_em":"",
"nature":"PT",
"id":"OMII0II800124355"
}
],
"facets":[
{"id":"OMII0IIN417970619","name":"Programs & Missions"}
]}
],"total":10
}
view raw JSON-Example hosted with ❤ by GitHub
Corresponding Class created with Paste JSON as Classes

public class Rootobject
{
public Parameters parameters { get; set; }
public Termhint[] termHints { get; set; }
public int total { get; set; }
}
public class Parameters
{
public string tbdb { get; set; }
public string service { get; set; }
public string template { get; set; }
public string term_prefix { get; set; }
}
public class Termhint
{
public string name { get; set; }
public string id { get; set; }
public string index { get; set; }
public Value[] values { get; set; }
public Facet[] facets { get; set; }
}
public class Value
{
public string value { get; set; }
public string pre_em { get; set; }
public string em { get; set; }
public string post_em { get; set; }
public string nature { get; set; }
public string id { get; set; }
}
public class Facet
{
public string id { get; set; }
public string name { get; set; }
}
view raw JSON-Class hosted with ❤ by GitHub
XML Object

<?xml version="1.0" encoding="utf-8"?>
<SEMAPHORE>
<PARAMETERS>
<PARAMETER NAME='TBDB'>nasapoc</PARAMETER>
<PARAMETER NAME='SERVICE'>prefix</PARAMETER>
<PARAMETER NAME='TEMPLATE'>service.xml</PARAMETER>
<PARAMETER NAME='TERM_PREFIX'>11</PARAMETER>
</PARAMETERS>
<TERM_HINTS>
<TERM_HINT NAME='Soyuz T11' ID='OMII0IIN2112985674' INDEX='nasapoc' WEIGHT='39.1393' CLASS='Missions'>
<FACET NAME='Programs &amp; Missions' ID='OMII0IIN417970619'/>
<FACET NAME='Organizations' ID='OMII0IIN708454495'/>
<HINT NATURE='NPT' ID='OMII0II957832499'>
T-<EM>11</EM>
</HINT>
</TERM_HINT>
<TERM_HINT NAME='Soyuz TM11' ID='OMII0II1817708082' INDEX='nasapoc' WEIGHT='21.1928' CLASS='Missions'>
<FACET NAME='Programs &amp; Missions' ID='OMII0IIN417970619'/>
<FACET NAME='Organizations' ID='OMII0IIN708454495'/>
<HINT NATURE='NPT' ID='OMII0IIN1708344299'>
TM-<EM>11</EM>
</HINT>
</TERM_HINT>
<TERM_HINT NAME='Soyuz TMA11' ID='OMII0II402255746' INDEX='nasapoc' WEIGHT='21.1928' CLASS='Missions'>
<FACET NAME='Programs &amp; Missions' ID='OMII0IIN417970619'/>
<FACET NAME='Organizations' ID='OMII0IIN708454495'/>
<HINT NATURE='NPT' ID='OMII0IIN564231465'>
TMA-<EM>11</EM>
</HINT>
</TERM_HINT>
<TERM_HINT NAME='Apollo 11' ID='OMII0IIN408999708' INDEX='nasapoc' WEIGHT='17.612' CLASS='Missions'>
<FACET NAME='Programs &amp; Missions' ID='OMII0IIN417970619'/>
<HINT NATURE='PT' ID='OMII0IIN408999708'>
Apollo <EM>11</EM>
</HINT>
<METADATA>
<FIELD NAME='site_description'>The purpose of the Apollo 11 mission was to land men on the lunar surface and to return them safely to Earth.</FIELD>
<FIELD NAME='site_title'>The Apollo 11 Mission</FIELD>
</METADATA>
</TERM_HINT>
<TERM_HINT NAME='Expedition 11' ID='OMII0II1043857968' INDEX='nasapoc' WEIGHT='16.6638' CLASS='Missions'>
<FACET NAME='Programs &amp; Missions' ID='OMII0IIN417970619'/>
<HINT NATURE='PT' ID='OMII0II1043857968'>
Expedition <EM>11</EM>
</HINT>
<METADATA>
<FIELD NAME='site_description'>Commander Sergei Krikalev and Flight Engineer John Phillips lived and worked aboard the International Space Station from April 2005 through October 2005. Krikalev had served on the station previously as part of the Expedition 1 crew, and Phillips visited the station as part of the STS-100 crew.</FIELD>
<FIELD NAME='site_title'>Expedition 11</FIELD>
</METADATA>
</TERM_HINT>
<TERM_HINT NAME='Group 11' ID='OMII0II1304089265' INDEX='nasapoc' WEIGHT='17.8633' CLASS='Astronauts'>
<FACET NAME='People' ID='OMII0IIN1655901465'/>
<HINT NATURE='PT' ID='OMII0II1304089265'>
Group <EM>11</EM>
</HINT>
</TERM_HINT>
<TERM_HINT NAME='ISS Assembly Mission 11A' ID='OMII0IIN1793710402' INDEX='nasapoc' WEIGHT='18.3697' CLASS='Missions'>
<FACET NAME='Programs &amp; Missions' ID='OMII0IIN417970619'/>
<HINT NATURE='PT' ID='OMII0IIN1793710402'>
ISS Assembly Mission <EM>11</EM>A
</HINT>
</TERM_HINT>
<TERM_HINT NAME='Lunar Module 11' ID='OMII0II962622437' INDEX='nasapoc' WEIGHT='17.8589' CLASS='Systems and Equipment'>
<FACET NAME='Systems &amp; Equipment' ID='OMII0IIN81023276'/>
<HINT NATURE='PT' ID='OMII0II962622437'>
Lunar Module <EM>11</EM>
</HINT>
</TERM_HINT>
<TERM_HINT NAME='Mir expedition crew 11' ID='OMII0II74828100' INDEX='nasapoc' WEIGHT='18.3755' CLASS='Missions'>
<FACET NAME='Programs &amp; Missions' ID='OMII0IIN417970619'/>
<FACET NAME='Organizations' ID='OMII0IIN708454495'/>
<HINT NATURE='PT' ID='OMII0II74828100'>
Mir expedition crew <EM>11</EM>
</HINT>
</TERM_HINT>
<TERM_HINT NAME='Orion 11' ID='OMII0II800124355' INDEX='nasapoc' WEIGHT='17.8689' CLASS='Missions'>
<FACET NAME='Programs &amp; Missions' ID='OMII0IIN417970619'/>
<HINT NATURE='PT' ID='OMII0II800124355'>
Orion <EM>11</EM>
</HINT>
</TERM_HINT>
</TERM_HINTS>
</SEMAPHORE>
view raw XML-Example hosted with ❤ by GitHub
Corresponding Class created with Paste XML as Classes

/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class SEMAPHORE
{
private SEMAPHOREPARAMETER[] pARAMETERSField;
private SEMAPHORETERM_HINT[] tERM_HINTSField;
/// <remarks/>
[System.Xml.Serialization.XmlArrayItemAttribute("PARAMETER", IsNullable = false)]
public SEMAPHOREPARAMETER[] PARAMETERS
{
get
{
return this.pARAMETERSField;
}
set
{
this.pARAMETERSField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlArrayItemAttribute("TERM_HINT", IsNullable = false)]
public SEMAPHORETERM_HINT[] TERM_HINTS
{
get
{
return this.tERM_HINTSField;
}
set
{
this.tERM_HINTSField = value;
}
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class SEMAPHOREPARAMETER
{
private string nAMEField;
private string valueField;
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string NAME
{
get
{
return this.nAMEField;
}
set
{
this.nAMEField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTextAttribute()]
public string Value
{
get
{
return this.valueField;
}
set
{
this.valueField = value;
}
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class SEMAPHORETERM_HINT
{
private SEMAPHORETERM_HINTFACET[] fACETField;
private SEMAPHORETERM_HINTHINT hINTField;
private SEMAPHORETERM_HINTFIELD[] mETADATAField;
private string nAMEField;
private string idField;
private string iNDEXField;
private decimal wEIGHTField;
private string cLASSField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("FACET")]
public SEMAPHORETERM_HINTFACET[] FACET
{
get
{
return this.fACETField;
}
set
{
this.fACETField = value;
}
}
/// <remarks/>
public SEMAPHORETERM_HINTHINT HINT
{
get
{
return this.hINTField;
}
set
{
this.hINTField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlArrayItemAttribute("FIELD", IsNullable = false)]
public SEMAPHORETERM_HINTFIELD[] METADATA
{
get
{
return this.mETADATAField;
}
set
{
this.mETADATAField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string NAME
{
get
{
return this.nAMEField;
}
set
{
this.nAMEField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string ID
{
get
{
return this.idField;
}
set
{
this.idField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string INDEX
{
get
{
return this.iNDEXField;
}
set
{
this.iNDEXField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public decimal WEIGHT
{
get
{
return this.wEIGHTField;
}
set
{
this.wEIGHTField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string CLASS
{
get
{
return this.cLASSField;
}
set
{
this.cLASSField = value;
}
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class SEMAPHORETERM_HINTFACET
{
private string nAMEField;
private string idField;
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string NAME
{
get
{
return this.nAMEField;
}
set
{
this.nAMEField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string ID
{
get
{
return this.idField;
}
set
{
this.idField = value;
}
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class SEMAPHORETERM_HINTHINT
{
private byte emField;
private string[] textField;
private string nATUREField;
private string idField;
/// <remarks/>
public byte EM
{
get
{
return this.emField;
}
set
{
this.emField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTextAttribute()]
public string[] Text
{
get
{
return this.textField;
}
set
{
this.textField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string NATURE
{
get
{
return this.nATUREField;
}
set
{
this.nATUREField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string ID
{
get
{
return this.idField;
}
set
{
this.idField = value;
}
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class SEMAPHORETERM_HINTFIELD
{
private string nAMEField;
private string valueField;
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string NAME
{
get
{
return this.nAMEField;
}
set
{
this.nAMEField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTextAttribute()]
public string Value
{
get
{
return this.valueField;
}
set
{
this.valueField = value;
}
}
}
view raw XML-Class hosted with ❤ by GitHub
As I stated earlier, the variable names in the classes created for this XML object could use a little clean up, but with a good refactoring tool, this should not be a difficult task and something that I find much more enjoyable than creating the entire file by hand.

Hope that you find this useful and that it can save you some time.