Próbuję parsować zawartość JSON w C#. Dla prostszych przypadków mam ogromny sukces z JSON.NET i naprawdę doceniam czyste podejście oferowane przez dostawcę LINQ. Oto przykład, gdzie jestem pobieranie informacji o warstwie w mapie i wypełniania niektórych właściwości na klasę o nazwie Layer (zaskakująco!):LINQ i JSON.NET, gdy nazwy właściwości różnią się
using (var client = new WebClient())
{
_content = client.DownloadString(_url.AbsoluteUri + OutputFormats.Json);
}
JObject json = JObject.Parse(_content);
IEnumerable<Field> fields = from f in json["fields"].Children()
select new Field(
(string)f["name"],
(string)f["alias"],
(EsriFieldType)Enum.Parse(typeof(EsriFieldType), (string)f["type"])
);
_fields = fields.ToList();
_displayFieldName = (string)json["displayField"];
Możesz zajrzeć pod tym adresem do szczegółów JSON za które metoda: http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/WaterTemplate/WaterDistributionNetwork/MapServer/1?f=json&pretty=true. Ale problem pojawia się, gdy potrzebuję włączyć poszczególne pola danych skojarzone z warstwami mapy do elementu DataTable lub nawet struktury słownika. Problem polega na tym, że w przeciwieństwie do kanałów RSS lub innych spójnych formatów nazwy pól i liczba pól zmienia się z warstwy mapy na warstwę mapy. Oto przykład ze mnie działa zapytania:
[Test]
[Category(Online)]
public void Can_query_a_single_feature_by_id()
{
var layer = _map.LayersWithName(ObjectMother.LayerWithoutOID)[0];
layer.FindFeatureById("13141");
Assert.IsNotNull(layer.QueryResults);
}
Kod, który jest prowadzony w layer.FindFeatureById to jest i obejmuje część gdzie utknąć:
public void FindFeatureById(string id)
{
var queryThis = ObjectIdField() ?? DisplayField();
var queryUrl = string.Format("/query{0}&outFields=*&where=", OutputFormats.Json);
var whereClause = queryThis.DataType == typeof(string)
? string.Format("{0}='{1}'", queryThis.Name, id)
: string.Format("{0}={1}", queryThis.Name, id);
var where = queryUrl + HttpUtility.UrlEncode(whereClause);
var url = new Uri(_url.AbsoluteUri + where);
Debug.WriteLine(url.AbsoluteUri);
string result;
using (var client = new WebClient())
{
result = client.DownloadString(url);
}
JObject json = JObject.Parse(result);
IEnumerable<string> fields = from r in json["fieldAliases"].Children()
select ((JProperty)r).Name;
// Erm...not sure how to get this done.
// Basically need to populate class instances/rows with the
// values for each field where the list of fields is not
// known beforehand.
}
Możesz zobaczyć JSON wypluć przez odwiedzając ten adres URL (zwróć uwagę na kodowanie podczas wycinania i wklejania): href = "http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/WaterTemplate/WaterDistributionNetwork/MapServer/1/query?f=json & outFields = * & gdzie = FACILITYID% 3d'13141 '
Moje pytanie (nareszcie!) Jest takie. Jak przechodzić przez kolekcję "atrybutów" w "funkcjach", aby uzyskać rzeczywiste wartości pól. Widać, że wymyśliłem, jak uzyskać nazwy pól z pola Aliases, ale po tym jestem zakłopotany. Byłem majstrować przy JsonReader na plik, który wygląda tak, ale jeszcze nie radość:
{
"displayFieldName" : "FACILITYID",
"fieldAliases" : {
"FACILITYID" : "Facility Identifier",
"ACCOUNTID" : "Account Identifier",
"LOCATIONID" : "Location Identifier",
"CRITICAL" : "Critical Customer",
"ENABLED" : "Enabled",
"ACTIVEFLAG" : "Active Flag",
"OWNEDBY" : "Owned By",
"MAINTBY" : "Managed By"
},
"features" : [
{
"attributes" : {
"FACILITYID" : "3689",
"ACCOUNTID" : "12425",
"LOCATIONID" : "12425",
"CRITICAL" : 1,
"ENABLED" : 1,
"ACTIVEFLAG" : 1,
"OWNEDBY" : 1,
"MAINTBY" : 1
}
},
{
"attributes" : {
"FACILITYID" : "4222",
"ACCOUNTID" : "12958",
"LOCATIONID" : "12958",
"CRITICAL" : 1,
"ENABLED" : 1,
"ACTIVEFLAG" : 1,
"OWNEDBY" : 1,
"MAINTBY" : 1
}
}
]
}
Cóż, to jest ładne i proste. dzieki za sugestie. – Dylan