【问题标题】:Restsharp RequestBody challenge, JSON format issue?Restsharp RequestBody 挑战,JSON 格式问题?
【发布时间】:2021-11-06 05:28:35
【问题描述】:

TLDR:我有一个功能正常的 C# 脚本,它调用 ESRI 地理编码服务。它传入地址,并取回 LAT/LON 数据。只要我在 URL 中嵌入地址,它就可以正常工作。我很难让类似的代码与调用正文中的地址内容一起运行。这里的目标是一次调用 500 多个地址的 REST 服务。

下面是一个脚本,只要我将地址作为 URL 的一部分嵌入,它就可以正常工作。它处理2-5个地址,没问题。但是(可以预见)——当尝试增加到 100 个地址时,我收到一个错误“无效的 URI:Uri 字符串太长。”

```C# 
SqlDataAdapter geoA = new SqlDataAdapter(SQLStatement, GEOconn);
DataSet GeoDS = new DataSet();
geoA.Fill(GeoDS, "records");
var obj = JObject.FromObject(GeoDS);
obj["records"] = new JArray(obj["records"].Select(jo => new JObject(new JProperty("attributes", jo))));
string geoAJSON = obj.ToString();
geoAJSON = HttpUtility.UrlEncode(geoAJSON);
var con1 = "https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/geocodeAddresses?f=pjson&token=abc123&outFields=ResultID,Status,Score,Addr_type,ShortLabel,City,Subregion,RegionAbbr,Postal,PostalExt,Country,X,Y&addresses=";
var client = new RestClient(con1 + geoAJSON);
client.Timeout = -1;
var request = new RestRequest(Method.POST);
request.AddHeader("Cookie", "AGS_ROLES=abc123");
IRestResponse response = client.Execute(request);
ESRIcls esri = JsonConvert.DeserializeObject<ESRIcls>(response.Content);
```

所以我试图利用 URL 请求的正文,并将所有地址推送到正文。到此为止我使用的脚本 sn-p 如下(上面稍作修改)。

SqlDataAdapter geoA = new SqlDataAdapter(SQLStatement, GEOconn);
DataSet GeoDS = new DataSet();
geoA.Fill(GeoDS, "records");
var obj = JObject.FromObject(GeoDS);
obj["records"] = new JArray(obj["records"].Select(jo => new JObject(new JProperty("attributes", jo))));
string geoAJSON = obj.ToString();               
geoAJSON = HttpUtility.UrlEncode(geoAJSON);     
var con1 = "https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/geocodeAddresses?f=pjson&token=abc123&outFields=ResultID,Status,Score,Addr_type,ShortLabel,City,Subregion,RegionAbbr,Postal,PostalExt,Country,X,Y";
var client = new RestClient(con1)
client.Timeout = -1
var request = new RestRequest(Method.POST);
request.AddJsonBody(geoAJSON);
//request.AddParameter("application/json", geoAJSON, ParameterType.RequestBody);
request.AddHeader("Cookie", "AGS_ROLES=abc123");
IRestResponse response = client.Execute(request);
ESRIcls esri = JsonConvert.DeserializeObject<ESRIcls>(response.Content);

在运行时,我在执行该 IRestResponse 行时遇到以下错误:

错误代码 400 extendedCode -2147467259 消息:无法完成 操作。

作为参考,这里是 geoAJSON 变量的内容。我尝试了多种 url 编码变体,但没有。不清楚我错了哪一部分,希望有任何建议。

    "{\r\n  \"records\": [\r\n    {\r\n      \"attributes\": {\r\n        
    \"OBJECTID\": 144,\r\n        \"Address\": \"02483 BERRY RD\",\r\n        
    \"City\": \"CEDARTOWN\",\r\n        \"Region\": \"GA\",\r\n        
    \"Postal\": \"30125\"\r\n      }\r\n    },\r\n    {\r\n      
    \"attributes\": {\r\n        \"OBJECTID\": 145,\r\n        \"Address\": 
    \"0N321 SILVERLEAF BLVD\",\r\n        \"City\": \"WHEATON\",\r\n        
    \"Region\": \"IL\",\r\n        \"Postal\": \"60187-2913\"\r\n      }\r\n    
    },\r\n    {\r\n      \"attributes\": {\r\n        \"OBJECTID\": 146,\r\n        
    \"Address\": \"1\",\r\n        \"City\": \"ROME\",\r\n        
    \"Region\": \"GA\",\r\n        \"Postal\": \"30165\"\r\n      }\r\n    
    }\r\n  ]\r\n}"

【问题讨论】:

    标签: c# json geocoding restsharp esri


    【解决方案1】:

    对于在 esri 地理编码方面面临类似挑战的其他人,以下方法有效

    using System;
    using System.Data;
    using System.Linq;
    using System.Data.SqlClient;
    using Newtonsoft.Json;
    using Newtonsoft.Json.Linq;
    using RestSharp;
    using System.Collections.Generic;
    
    namespace GeoCode
    {
        class GeoCode_Main
        {
            readonly static string strDDInstance = @"server";       // where is geo.datasources table?
            readonly static string strddDB = "database";
            readonly static string connDDstring = "Data Source=" + strDDInstance + ";Initial Catalog=" + strddDB + ";Integrated Security=True;MultipleActiveResultSets = True";
            readonly static int intBatchSize = 250;                     // how many rows to send to batch geocoder at one time?
            public static int intRowsProcessed = 0;             // how many geocode addresses have we done this run?
    
            static void Main()
            {
                Console.WriteLine("Launching GeoCode_Main_BI routine");
                string SQLStatement = "select top " + intBatchSize + " MAFid as OBJECTID, FMCaddr as Address, FMCcity as City, FMCstate as Region, FMCzip as Postal from maf.addresses where GSscore is null "; // and bitwise_nulls = 30 and MAFid < 750";
                string SQLTempRecCount = "select count(*) as RecCnt from maf.addresses_temp";
                using SqlConnection GEOconn = new SqlConnection(connDDstring);
                GEOconn.Open();
    
                // if maf.addresses_temp has data in it -- some prior run failed -- hit the exit ramp until that gets fixed
                SqlCommand selectCommand = new SqlCommand(SQLTempRecCount, GEOconn);
                int MafTempRecCnt = (int)selectCommand.ExecuteScalar();
                if (MafTempRecCnt > 1)
                {
                    Console.WriteLine("Rows exist in maf.addresses_temp and they shouldn't -- bailing out - 1");
                    Console.ReadKey();
                    return; } // bailout
                do
                {
                    // now open up maf.addresses and see if any rows flagged for geocoding. 
                    SqlDataAdapter geoDA = new SqlDataAdapter(SQLStatement, GEOconn);
                    DataSet GeoDS = new DataSet();
                    geoDA.Fill(GeoDS, "records");
                    int GeoDSCnt = GeoDS.Tables[0].Rows.Count;
                    // likewise - if no recs return -- just exit
                    if (GeoDSCnt == 0)
                    { 
                        Console.WriteLine("Finished processing records - about to exit");
                        Console.ReadKey();
                        return;
                    }
                    intRowsProcessed += GeoDSCnt;
                    Console.WriteLine("{0} rows so far", intRowsProcessed);
    
                    var JSONobj = JObject.FromObject(GeoDS);  
                    JSONobj["records"] = new JArray(JSONobj["records"].Select(jo => new JObject(new JProperty("attributes", jo))));
                    string geoAJSON = JSONobj.ToString();     
                    var client = new RestClient("https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/geocodeAddresses");
                    client.Timeout = -1;
                    var request = new RestRequest(Method.POST);
                    request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
                    request.AddParameter("addresses", geoAJSON);
                    request.AddParameter("forStorage", "true");
                    request.AddParameter("outFields", "ResultID,Status,Score,Addr_type,ShortLabel,City,Subregion,RegionAbbr,Postal,PostalExt,Country,X,Y");
                    request.AddParameter("f", "pjson");
                    request.AddParameter("token", "blahblah");
                    request.AddParameter("Cookie", "blahblah");
                    IRestResponse response = client.Execute(request);
                    ESRIcls esri = JsonConvert.DeserializeObject<ESRIcls>(response.Content);
                    int Cntr = 0;
                    while (Cntr < esri.locations.Count)
                    {
                        //                                Console.WriteLine(esri.locations[Cntr].attributes.Addr_type);
                        var cmd = new SqlCommand
                        {
                            CommandText = "maf.spPopMAF",
                            CommandType = CommandType.StoredProcedure,
                            Connection = GEOconn
                        };
                        cmd.Parameters.Clear();
                        cmd.Parameters.Add("@MAFid", SqlDbType.Int).Value = esri.locations[Cntr].attributes.ResultID;
                        cmd.Parameters.Add("@GSstatus", SqlDbType.VarChar).Value = esri.locations[Cntr].attributes.Status;
                        cmd.Parameters.Add("@GSscore", SqlDbType.Decimal).Value = esri.locations[Cntr].attributes.Score;
                        cmd.Parameters.Add("@GSaddresstype", SqlDbType.VarChar).Value = esri.locations[Cntr].attributes.Addr_type;
                        cmd.Parameters.Add("@GSaddress", SqlDbType.VarChar).Value = esri.locations[Cntr].attributes.ShortLabel;
                        cmd.Parameters.Add("@GScity", SqlDbType.VarChar).Value = esri.locations[Cntr].attributes.City;
                        cmd.Parameters.Add("@GScounty", SqlDbType.VarChar).Value = esri.locations[Cntr].attributes.Subregion;
                        cmd.Parameters.Add("@GSstate", SqlDbType.VarChar).Value = esri.locations[Cntr].attributes.RegionAbbr;
                        cmd.Parameters.Add("@GSzip5", SqlDbType.VarChar).Value = esri.locations[Cntr].attributes.Postal;
                        cmd.Parameters.Add("@GSzip4", SqlDbType.VarChar).Value = esri.locations[Cntr].attributes.PostalExt;
                        cmd.Parameters.Add("@GSlongitude", SqlDbType.Decimal).Value = esri.locations[Cntr].attributes.X;
                        cmd.Parameters.Add("@GSlatitude", SqlDbType.Decimal).Value = esri.locations[Cntr].attributes.Y;
                        cmd.Parameters.Add("@GScountry", SqlDbType.VarChar).Value = esri.locations[Cntr].attributes.Country;
                        cmd.ExecuteNonQuery();
                        Cntr++;
                    };
                    // Console.WriteLine("Just populated esri feed into maf.addresses_temp table");
                    // now move content from temp to maf.addresses
                    var cmdsp = new SqlCommand
                    {
                        CommandText = "maf.spESRIGeoCodedUpToMAFAddresses",
                        CommandType = CommandType.StoredProcedure,
                        Connection = GEOconn
                    };
                    cmdsp.ExecuteNonQuery();
                    // Console.WriteLine("Just executed maf.spESRIGeoCodedUpToMAFAddresses routine");
                    SqlCommand scTemp = new SqlCommand(SQLTempRecCount, GEOconn);
                    int MafTempRecCnt2 = (int)scTemp.ExecuteScalar();
                    if (MafTempRecCnt2 > 0)
                    {
                        Console.WriteLine("Rows exist in maf.addresses_temp and they shouldn't -- bailing out - 2 ");
                        Console.ReadKey();
                        return; }
                }
                while (true);
            }
        }
    
    
        public class SpatialReference
        {
            public int wkid { get; set; }
            public int latestWkid { get; set; }
        }
    
        public class Attributes
        {
            public int ResultID { get; set; }
            public string Loc_name { get; set; }
            public string Status { get; set; }
            public Decimal Score { get; set; }
            public string Match_addr { get; set; }
            public string LongLabel { get; set; }
            public string ShortLabel { get; set; }
            public string Addr_type { get; set; }
            public string Type { get; set; }
            public string PlaceName { get; set; }
            public string Place_addr { get; set; }
            public string Phone { get; set; }
            public string URL { get; set; }
            public Decimal Rank { get; set; }
            public string AddBldg { get; set; }
            public string AddNum { get; set; }
            public string AddNumFrom { get; set; }
            public string AddNumTo { get; set; }
            public string AddRange { get; set; }
            public string Side { get; set; }
            public string StPreDir { get; set; }
            public string StPreType { get; set; }
            public string StName { get; set; }
            public string StType { get; set; }
            public string StDir { get; set; }
            public string BldgType { get; set; }
            public string BldgName { get; set; }
            public string LevelType { get; set; }
            public string LevelName { get; set; }
            public string UnitType { get; set; }
            public string UnitName { get; set; }
            public string SubAddr { get; set; }
            public string StAddr { get; set; }
            public string Block { get; set; }
            public string Sector { get; set; }
            public string Nbrhd { get; set; }
            public string District { get; set; }
            public string City { get; set; }
            public string MetroArea { get; set; }
            public string Subregion { get; set; }
            public string Region { get; set; }
            public string RegionAbbr { get; set; }
            public string Territory { get; set; }
            public string Zone { get; set; }
            public string Postal { get; set; }
            public string PostalExt { get; set; }
            public string Country { get; set; }
            public string LangCode { get; set; }
            public int Distance { get; set; }
            public Decimal X { get; set; }
            public Decimal Y { get; set; }
            public Decimal DisplayX { get; set; }
            public Decimal DisplayY { get; set; }
            public Decimal Xmin { get; set; }
            public Decimal Xmax { get; set; }
            public Decimal Ymin { get; set; }
            public Decimal Ymax { get; set; }
            public string ExInfo { get; set; }
        }
    
        public class Location
        {
            public string address { get; set; }
            public Location location { get; set; }
            public Decimal score { get; set; }
            public Attributes attributes { get; set; }
        }
    
        public class ESRIcls
        {
            public SpatialReference spatialReference { get; set; }
            public IList<Location> locations { get; set; }
        }
    }
    
    

    【讨论】:

      猜你喜欢
      • 2010-12-22
      • 1970-01-01
      • 2021-01-15
      • 1970-01-01
      • 2011-09-25
      • 2015-05-02
      • 1970-01-01
      • 2022-06-14
      • 1970-01-01
      相关资源
      最近更新 更多