I am using WebRequest to read JSON data from the FCC so I can output it to a view. Here is my custom class to hold an FCC license:
public class License
{
public string Name{ get; set; }
public string Frn { get; set; }
public string Callsign { get; set;}
public string CategoryDesc { get; set; }
public string ServiceDesc { get; set; }
public string StatusDesc { get; set; }
public DateTime ExpiredDate { get; set; }
public string Id { get; set; }
public string DetailUrl { get; set; }
}
Here is the Controller action that I am using to read the json results.
I have Verizon Wireless hard-coded as the search value for now:
public ActionResult GetLicenses()
{
var result = string.Empty;
var url = "http://data.fcc.gov/api/license-view/basicSearch/getLicenses?searchValue=Verizon+Wireless&format=jsonp&jsonCallback=?";
var webRequest = WebRequest.Create(url);
webRequest.Timeout = 2000;
using (var response = webRequest.GetResponse() as HttpWebResponse)
{
if (response.StatusCode == HttpStatusCode.OK)
{
var receiveStream = response.GetResponseStream();
if (receiveStream != null)
{
var stream = new StreamReader(receiveStream);
result = stream.ReadToEnd();
}
}
}
return new ContentResult { Content = result, ContentType = "application/json" };
}
Here is the view. I am trying to enumerate through all the licenses and output them to a table, but when I go to /Home/GetLicenses, it prompts me to download the file:
@model IEnumerable<MvcApplication1.Models.License>
@{
ViewBag.Title = "Licenses";
}
<h2>Licenses</h2>
<table>
<tr>
<th>
Name
</th>
<th>
Frn
</th>
<th>
Callsign
</th>
<th>
CategoryDesc
</th>
<th>
ServiceDesc
</th>
<th>
StatusDesc
</th>
<th>
ExpiredDate
</th>
<th>
DetailUrl
</th>
<th></th>
</tr>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.Frn)
</td>
<td>
@Html.DisplayFor(modelItem => item.Callsign)
</td>
<td>
@Html.DisplayFor(modelItem => item.CategoryDesc)
</td>
<td>
@Html.DisplayFor(modelItem => item.ServiceDesc)
</td>
<td>
@Html.DisplayFor(modelItem => item.StatusDesc)
</td>
<td>
@Html.DisplayFor(modelItem => item.ExpiredDate)
</td>
<td>
@Html.DisplayFor(modelItem => item.DetailUrl)
</td>
</tr>
}
</table>
I got the above working if I do it directly through jquery’s getJSON method, but I wanted to see if I could get the results from a contoller to a view and then have it rendered in the view.
This is a sample of what is returned in the results variable:
?({
"status": "OK",
"Licenses": {
"page": "1",
"rowPerPage": "100",
"totalRows": "1995",
"lastUpdate": "Sep 21, 2011",
"License": [
{
"licName": "CELLCO PARTNERSHIP (\"VERIZON WIRELESS\")",
"frn": "",
"callsign": "",
"categoryDesc": "Satellite Earth Station",
"serviceDesc": "",
"statusDesc": "Active",
"expiredDate": "",
"licenseID": "2300007967",
"licDetailURL": "http://licensing.fcc.gov/cgi-bin/ws.exe/prod/ib/forms/reports/swr031b.hts?prepare=&column=V_SITE_ANTENNA_FREQ.file_numberC/File+Number&q_set=V_SITE_ANTENNA_FREQ.file_numberC/File+Number/=/FCNNEW2000060800036"
},
{
"licName": "CELLO PARTNERSHIP (\"VERIZON WIRELESS\")",
"frn": "",
"callsign": "",
"categoryDesc": "Satellite Earth Station",
"serviceDesc": "",
"statusDesc": "Active",
"expiredDate": "",
"licenseID": "2300010661",
"licDetailURL": "http://licensing.fcc.gov/cgi-bin/ws.exe/prod/ib/forms/reports/swr031b.hts?prepare=&column=V_SITE_ANTENNA_FREQ.file_numberC/File+Number&q_set=V_SITE_ANTENNA_FREQ.file_numberC/File+Number/=/FCNNEW2000083100048"
},
{
"licName": "Cellco Partnership d/b/a Verizon Wireless",
"frn": "0003290673",
"callsign": "KE2XMC",
"categoryDesc": "Experimental",
"serviceDesc": "Experimental Developmental",
"statusDesc": "Unknown",
"expiredDate": "12/14/2000",
"licenseID": "3000020853",
"licDetailURL": "https://fjallfoss.fcc.gov/oetcf/els/reports/ELSSearchResult.cfm?callsign=KE2XMC"
},
{
"licName": "Cellco Partnership d/b/a Verizon Wireless",
"frn": "0003290673",
"callsign": "WA2XPS",
"categoryDesc": "Experimental",
"serviceDesc": "Experimental Developmental",
"statusDesc": "Unknown",
"expiredDate": "12/14/2000",
"licenseID": "3000020851",
"licDetailURL": "https://fjallfoss.fcc.gov/oetcf/els/reports/ELSSearchResult.cfm?callsign=WA2XPS"
},
{
"licName": "Cellco Partnership dba Verizon Wireless",
"frn": "0003290673",
"callsign": "KNKP866",
"categoryDesc": "Mobile/Fixed Broadband",
"serviceDesc": "Cellular",
"statusDesc": "Cancelled",
"expiredDate": "10/01/2005",
"licenseID": "13328",
"licDetailURL": "http://wireless2.fcc.gov/UlsApp/UlsSearch/license.jsp?__newWindow=false&licKey=13328"
}
]
}
})
I added this class:
public class FCC
{
public string status { get; set; }
public Licenses Licenses { get; set; }
}
But I still get the Invalid JSON primitive.
public ActionResult GetLicenses()
{
var result = string.Empty;
var url =
"http://data.fcc.gov/api/license-view/basicSearch/getLicenses?searchValue=Verizon+Wireless&format=jsonp&jsonCallback=?";
var webRequest = WebRequest.Create(url);
webRequest.Timeout = 2000;
webRequest.ContentType = "application/json";
using (var response = webRequest.GetResponse() as HttpWebResponse)
{
if (response.StatusCode == HttpStatusCode.OK)
{
var receiveStream = response.GetResponseStream();
if (receiveStream != null)
{
var stream = new StreamReader(receiveStream);
result = stream.ReadToEnd();
}
}
}
FCC fcc = new FCC();
if (result.StartsWith(@"?("))
{
result = result.Substring(2);
}
if (result.EndsWith(@")"))
{
result = result.Remove(result.Length - 1);
}
if (result != null)
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
fcc = serializer.Deserialize<FCC>(result);
}
return View(fcc.Licenses.License);
}
By returning a
ContentResultfrom your ActionMethod, your browser is going to respond with the appropriate action based upon the content. In this case a JSON string will be downloaded similar to a file since it is not a HTML doc.If you want to render the results in a View and not through AJAX, then you will need to create a C# Model class representing your WebRequest response data, and then return a
ViewResultand pass the model (or collection of models) to the View.I would suggest changing your
ActionMethodto do something like below, and also create a View called “Licenses”Also, your example response is a bit of a trick. It is more complex than an array of your original License Object, AND it is wrapped with a
?(). The JavaScriptSerializer will only deserialize properties that it can match based on property name (it is case sensitive as well). And because of the?()wrapping, we need to remove that so the deserialization won’t break.So you would need to modify your License object accordingly:
Lastly, you will need to change the property names in your CSHTML file, since the new License object doesn’t have the same property names anymore.
AJAX is probably another question, but I’ll post back here if I run across a good example