Dyl*_*lan 9 c# json json.net arcgis-server
我试图将一些JSON内容解析为C#.对于更简单的情况,我在JSON.NET上取得了巨大的成功,并且非常感谢LINQ提供商提供的干净方法.这是一个例子,我在地图中下载有关图层的信息,并在一个叫做的类上填充一些属性(令人惊讶!)图层:
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"];
Run Code Online (Sandbox Code Playgroud)
您可以查看此URL以获取该方法的JSON的详细信息:http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/WaterTemplate/WaterDistributionNetwork/MapServer/1?f = json&pretty = true.但是当我需要将与地图图层关联的单个数据字段转换为DataTable甚至只是字典结构时,问题就出现了.问题是,与RSS提要或其他一致格式不同,字段名称和字段数量从地图图层更改为地图图层.这是我运行查询的一个例子:
[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);
}
Run Code Online (Sandbox Code Playgroud)
在layer.FindFeatureById中运行的代码是这个,包括我卡住的部分:
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.
}
Run Code Online (Sandbox Code Playgroud)
您可以通过访问此URL看到JSON吐出(请注意切割'n'paste时的编码):href ="http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/WaterTemplate/WaterDistributionNetwork/MapServer/1 /查询?F = JSON&外场=*&其中= FACILITYID%3d'13141'
所以我的问题(最后!)是这样的.如何循环"特征"中的"属性"集合以获取实际字段值.你可以看到我已经弄清楚如何从fieldAliases中获取字段名称,但之后我很难过.我一直在修补一个看起来像这样的文件的JsonReader,但仍然没有快乐:
{
"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
}
}
]
}
Run Code Online (Sandbox Code Playgroud)
要获得快速且脏的(非LINQ)方法来获取属性和值,请尝试以下操作:
JObject jo = JObject.Parse(json);
foreach (JObject j in jo["features"])
{
foreach (JProperty k in j["attributes"])
{
Console.WriteLine(k.Name + " = " + k.Value);
}
}
Run Code Online (Sandbox Code Playgroud)
它并不理想,但是当你不知道将要回来的字段名称时它会起作用.如果我找到更好的方法,我会更新它.
事实证明,最好的方法是使用 JsonTextReader 并直接读取数据,而不是尝试使用 LINQ。它有很多缩进,这让我不高兴,但我认为这是首先使用分层数据结构的直接影响。以下是打印行列表(“属性”)及其名称/值集合的方法:
using (var file = File.OpenText(_fileWithGeom))
{
JsonReader reader = new JsonTextReader(file);
while (reader.Read())
{
while (Convert.ToString(reader.Value) != "features")
{
reader.Read();
}
Console.WriteLine("Found feature collections");
// ignore stuff until we get to attribute array
while (reader.Read())
{
switch (Convert.ToString(reader.Value))
{
case "attributes":
Console.WriteLine("Found feature");
reader.Read(); // get pass attributes property
do
{
// As long as we're still in the attribute list...
if (reader.TokenType == JsonToken.PropertyName)
{
var fieldName = Convert.ToString(reader.Value);
reader.Read();
Console.WriteLine("Name: {0} Value: {1}", fieldName, reader.Value);
}
reader.Read();
} while (reader.TokenType != JsonToken.EndObject
&& Convert.ToString(reader.Value) != "attributes");
break;
case "geometry":
Console.WriteLine("Found geometry");
reader.Read();
break;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
这次我还必须处理几何图形,因此请查看以下 URL 以获取上述代码正在解析的 JSON:
| 归档时间: |
|
| 查看次数: |
8323 次 |
| 最近记录: |