Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Question
Thursday, November 17, 2016 10:40 PM
Been using Bing Maps API pretty flawlessly for a while now and just got a new exception without changing code (I was deploying the final version).
I've been writing an app that requests the boundaries for 9000+ zip codes that I have ran to completion without issues about 10 times now, and today was my first time running it in about a month (I am deploying it to the server it will live on as it's done).
However during my test run it fails about halfway through (3000ish zip codes in) on different queries each time.
An exception of type 'System.Runtime.Serialization.SerializationException' occurred in System.Runtime.Serialization.dll but was not handled in user code
Additional information: There was an error deserializing the object of type TMIAuditorTerritoryExtract.Response. Encountered unexpected character 'R'.
I find it very strange I started getting this error without changing anything and that it's failing on different zip codes each time (after processing a few thousand correctly). Any thoughts? Below are 2 of the Response.RequestMessages it failed on in some test runs today.
{Method: GET, RequestUri: 'https://platform.bing.com/geo/spatial/v1/public/geodata?spatialFilter=GetBoundary('75261-0000',1,'Postcode1',1,0,'en','US')&$format=json&key={maps key}', Version: 1.1, Content: <null>, Headers:
{}}
{Method: GET, RequestUri: 'https://platform.bing.com/geo/spatial/v1/public/geodata?spatialFilter=GetBoundary('77260-0000',1,'Postcode1',1,0,'en','US')&$format=json&key={maps key}', Version: 1.1, Content: <null>, Headers:
{}}
All replies (11)
Monday, November 21, 2016 9:24 PM ✅Answered
The service hasn't had any changes. At first I thought the issue might be due to the fact that you are passing in zip+4 in which are not supported. Testing these URL's the service just returns the main zip code boundary and ignores the +4 value, so that's not the issue. The response I see back is inline with the documented schema which has not changed since the service was released. Not sure why your serializer is seeing an "R" character, aside from the string values, there is no R character in the response. If you are using a basic key, it is highly possible that your requests are being rather limited which would result in empty responses. Also possible that if an error is occurring that HTML is returned which is why your serializer is having issues. I suggest doing a network trace on one of the failing requests and seeing what is returned. This should help in determining where the issue is. When you try the URL in a browser, do you see the expected JSON response?
Tuesday, November 29, 2016 11:24 PM ✅Answered
Everything looks correct. The issue seems to be with the code you are using to serialize the response. What's odd is that it is saying it is encountering "R" which none of the property names start with in the response, so not sure where that is coming from. The "R" character is If you are parsing that string into shapes are part of your serialization process then the error may be in there somewhere.
Wednesday, November 30, 2016 4:24 PM ✅Answered
Ah, ok, that's the issue. The Data Contracts in the documentation are for the Bing Maps REST services. The GeoData API is part of the Bing Spatial Data Services which is a different service. Here are the data contracts for the GeoData API:
using System.Runtime.Serialization;
namespace Bing.GeoDataServices
{
[DataContract]
public class Response
{
[DataMember(Name = "d", EmitDefaultValue = false)]
public ResultSet ResultSet { get; set; }
}
[DataContract]
public class ResultSet
{
[DataMember(Name = "__copyright", EmitDefaultValue = false)]
public string Copyright { get; set; }
[DataMember(Name = "results", EmitDefaultValue = false)]
public Result[] Results { get; set; }
}
[DataContract]
public class Result
{
[DataMember(Name = "EntityID", EmitDefaultValue = false)]
public string EntityID { get; set; }
[DataMember(Name = "EntityMetadata", EmitDefaultValue = false)]
public Metadata EntityMetadata { get; set; }
[DataMember(Name = "Name", EmitDefaultValue = false)]
public Name Name { get; set; }
[DataMember(Name = "Primitives", EmitDefaultValue = false)]
public Primitive[] Primitives { get; set; }
[DataMember(Name = "Copyright", EmitDefaultValue = false)]
public Copyright Copyright { get; set; }
}
[DataContract]
public class Metadata
{
[DataMember(Name = "AreaSqKm", EmitDefaultValue = false)]
public string AreaSqKm { get; set; }
[DataMember(Name = "BestMapViewBox", EmitDefaultValue = false)]
public string BestMapViewBox { get; set; }
[DataMember(Name = "OfficialCulture", EmitDefaultValue = false)]
public string OfficialCulture { get; set; }
[DataMember(Name = "RegionalCulture", EmitDefaultValue = false)]
public string RegionalCulture { get; set; }
[DataMember(Name = "PopulationClass", EmitDefaultValue = false)]
public string PopulationClass { get; set; }
}
[DataContract]
public class Name
{
[DataMember(Name = "EntityName", EmitDefaultValue = false)]
public string EntityName { get; set; }
[DataMember(Name = "Culture", EmitDefaultValue = false)]
public string Culture { get; set; }
[DataMember(Name = "SourceID", EmitDefaultValue = false)]
public string SourceID { get; set; }
}
[DataContract]
public class Primitive
{
[DataMember(Name = "PrimitiveID", EmitDefaultValue = false)]
public string PrimitiveID { get; set; }
[DataMember(Name = "Shape", EmitDefaultValue = false)]
public string Shape { get; set; }
[DataMember(Name = "NumPoints", EmitDefaultValue = false)]
public string NumPoints { get; set; }
[DataMember(Name = "SourceID", EmitDefaultValue = false)]
public string SourceID { get; set; }
}
[DataContract]
public class Copyright
{
[DataMember(Name = "CopyrightURL", EmitDefaultValue = false)]
public string CopyrightURL { get; set; }
[DataMember(Name = "Sources", EmitDefaultValue = false)]
public CopyrightSource[] Sources { get; set; }
}
[DataContract]
public class CopyrightSource
{
[DataMember(Name = "SourceID", EmitDefaultValue = false)]
public string SourceID { get; set; }
[DataMember(Name = "SourceName", EmitDefaultValue = false)]
public string SourceName { get; set; }
[DataMember(Name = "Copyright", EmitDefaultValue = false)]
public string Copyright { get; set; }
}
}
These data contracts are available in this open source project: http://mapstoolbox.codeplex.com/SourceControl/latest#Microsoft.Maps.Spatialtoolbox/Source/Microsoft.Maps.SpatialToolbox.Core/Bing/Services/GeoDataServices.cs
We plan to release a .NET library for the Bing Maps REST and Spatial Data Services that make it easier to connect to those services from any .NET project. These should be online in the next month or two.
Friday, December 2, 2016 11:19 AM ✅Answered
ok, check to see if the header has a property X-MS-BM-WS-INFO that is set to 1. If so, then the request has been rate limited. If not, then try and grab a network trace and provide that to the Bing Maps support team who you can contact here: https://support.microsoft.com/en-us/getsupport?tenant=ClassicCommercial&locale=en-us&supportregion=en-us&pesid=13766&sd=&oaspworkflow=start_1.0.0.0&wf=0&ccsid=635830587906447783
Friday, December 2, 2016 5:23 PM ✅Answered
Not sure about this issue, please contact the Bing Maps support team.
In regards to questions about metadata. The response has two twos of metadata; __metadata and EntityMetadata. __metadata consists of a URL that is directly to the shape. EntityMetadata provides additional information about the boundary. Not all boundaries have values for all metadata properties (few boundaries have all of them). for the __copyright, it looks like this may have changed.
Tuesday, November 29, 2016 9:41 PM
The service hasn't had any changes. At first I thought the issue might be due to the fact that you are passing in zip+4 in which are not supported. Testing these URL's the service just returns the main zip code boundary and ignores the +4 value, so that's not the issue. The response I see back is inline with the documented schema which has not changed since the service was released. Not sure why your serializer is seeing an "R" character, aside from the string values, there is no R character in the response. If you are using a basic key, it is highly possible that your requests are being rather limited which would result in empty responses. Also possible that if an error is occurring that HTML is returned which is why your serializer is having issues. I suggest doing a network trace on one of the failing requests and seeing what is returned. This should help in determining where the issue is. When you try the URL in a browser, do you see the expected JSON response?
Just got back to this after the holidays, thanks for taking the time to help!
I just ran it again and it failed on this query (same 'R' character fail):
Running that in the browser seems to give a valid response:
{"d":{"Copyright":"\u00a9 2016 Microsoft and its suppliers. This API and any results cannot be used or accessed without Microsoft's express written permission.","results":[{"__metadata":{"uri":"https:\/\/platform.bing.com\/geo\/spatial\/v1\/public\/geodata?$filter=GetEntity(-37999903044L,1,0,'en','US')"},"EntityID":"-37999903044","Name":{"EntityName":"75087","Culture":"en","SourceID":"5"},"Primitives":[{"PrimitiveID":"-37999856999","Shape":"1,gwz4_6_xwJ7rE1hR24vB845KnJyIC5jBhJxVCDqmBoFCD5t2avqmHyuiFnqQ0qlCu4-tCDFnSsGutiCKDK5B5jsCpGnGgF9DjCDyCpLrrDj77sBzyGDD7_J1cgqC6Q6QikHszH8-gD7IDgn9K6mID-yjFrDFDFB-qGt-K_Y8xjC_wCxtBFrKkGiG7E4DiL1QG8M7S_M7O7gEwrBliBqrFoojB0yCx1DqyBkV3lCzwK-qDzlCp_JklBr4EqyBuhCr4E2zMkkJozI-qDui4C28Sw1T39M_6DozIwmG6-LnsEof7uB-kF8pCzrHp7H2rF2mEiqCtqMotLn2B0yBF-lC7sE2yBzzNh5Eoa5XhkU0m4C3uGpvBw-Er-MylB7lFzhDqzCv2BuqCi7Kg2G3rD_1G93C4yB-O-O8G0yB_Q7B0C8GoBwEppOpTwVMDnTszCj_B-3CymDgiC9c6-PulBj3L-1D83oB6rF-gDkod5uB_7Cn4E7SiyEyyCqsLsmevlC78O-sqBtwnC0yC7qDt1D3kFu_ExgvF_7CvlC7qDloBkyEvgpC5uB7xFnniGy5BomE71e0jHiyE4pCsrBt9B5gD4lDt1DyyCt9B2QwJy5BmyBlLhI6M2QmftX2Q7SmfuhCyrB8ZFmyE4oVliB51B8ZshCuyC3qD0lDqrBglBilBilBl3C6MonKrD5gDiuav-FwzM78OwJqsLqE9qI_7CsrB1gnBlxoD5Su5K3xkCsrB11f5gDglBgwD-9JqhCpyN0yCoyB_0GunKi1Gz9Bh8Iq7D_8S25XhqQkVh4hCzyNsm1G_pC-gDi7Dv9BD91BqkJ9xpEyhCgmDD7gEnlFtuC5lC0hC-tG__P-gEwyBufrrD09N92Lh4D6zHztJ-4EmzCjsI22QnIulBxrDFF1KjF1KqMkZgR-OFkNv2BtLm6B5Xoa3XqVkoKn2B0ngBzjpCvznCz8I4nf5kZxuGsnG1rDssFpIskWzlFliRj9GDF8yGqehS7E8Dp5kBuhTvuEz6Es9qBp0Vn3jB0lGz3D8a3inD7H9WqGvHkCiCoxFi_iB-gF-V-3FjinCq3ByuElPoNxLtI_JvIvIzTiKzIwNztCtibplRpnFh5Cx1W0p7BFBqqpC69CF0lGFwqBvnB-b6CijMziD3HjDhDtK5Rpb-EhhBpOkiSFB6ruKn8epj-BFB4Y7hFrHgMiG9EjbwYhWwpBtnJB2tCuwGg-B4hK4gUwtMxmjB_Fqv1DydtB5E84b_FpmK84bl0T7ujBzpxEhnBgyJ_Pzx1Tm9KkKpFsGBtbmwJsiGrKsG5Lw3GjjBt0FwgzH0p2BhkF4gFgjS3vnnBzSDFp3B2lEgiIi0G2_LzwgCncu6T8jMlmuB4sBDFv-CxppEyxmSmJt08NFg7LihiC-wkDlqGBzuFo2xkB6nLu0pHBowrLzxbimtxBBx6KCDgNmB5BVdQfwBwBuBCCNnB2cnB0uCnBLRIzBoG1BTFBjpiFhpSoc93X9xidlDBgBBPBnBYlBtBclBgjsL9opGBBlN8BvE1JsoBpkHlasiBioYgTgTptL1JvEvlBzCyFxhCuDyFB1yBjN1JhNz0gD3rB2_MCvEiT7hCrzHmxW8uBqrDoiBzopFyyNnf6Sz5mCx24BrE9kBqDuuCjlBzGvJBsD69ByXpyEBzCBmvBzCyyN75KsDvCiiBsDsDqiBkIj8Cpod86btmfmL54F8Sy3d4tG0wKquCirDjVkLxC4B7MiL2xFryC0xF_2C5ZnmG2gDx4FgI1Gk1DvJy6kB-UzQhyB3ZBC9e1q7CqY1kBuothC9tF__IBqk2EwuE9za7twS2vpBn8xCs2Nk9douIyk5NuhuJBC8oBUBjBDwO4b2KvM2DwSCoOD-PqKnGpGCwK0HjEjErB7J7QxC8S7M3GC9QpaBuvB8cnlB9Q1JyuCtlB7wDnlBkiBoiBmIB5JCgCCpCjBuIy2B5JC2BUpGyS5U2D5CC2H8KrR1aiYkP_rDy2B1VnNCnECkOxMhH1JC0DjErC0HpB3J6FCrCrGUzEqI2FsIxGCoDCkOhJsOtQrB0DCp2IpRxVnEC2KvQ4KhJjE0DxEwFpEkIByiBjBkD8HzE0F7JtCmDCDiFnMtG_BrBDCyBD_CjElH5apQ5V_XvExCByDBjHC-J-JsI5G3GBwDChBwHrBuDwFkL7GpNwLiPC5CvGDrGmOmO4LsI6XqLhHlN5J0LnE9V4L2D8FCjB2HrGlEyI0LrmJC4L6HsIoLoL9QBtnSrRvavaoIuLmPoI-QCvECjHhHtEtBhF9CwFzEBCtGnEhH5GkL_HtJ9QvlBiTtfnlB0Sw1DCsuCqiBw9Bo9B-ZjViC4BBCgC6F4LhHlRzC7CeoGmC4IBrE3J5JCwnBpQwIjVivB6d0I-ZBCU6B4B9MmrD1JyFBlNCtCC0KnE3CnBC6BCq2D7G4X7f-nG0F-Jxa9QB3f4D5GzVpJC2HlHnNpasT0LqP-6BwTCtQ7qB1U4LuOwSnNrBzEvEvE3JC4F6FwIClJ0KiF2KvGnE0BjB0HoDyIxGCkDCjE2DCkDgC5CCpCgF7DsoICyH2KmDDrGlGnMjJoO2H4W9Y2WjJ4HC2KhZrUrGzeuS_KoDxEmzFC9J2oBjN0FBanByF1GgLlWhW4IoLB0F7J-J2FvfmIxJgM6jBtsCvbiJBgGsFuFqIBC59oGl5BCw1CnJwSCzU6W0HlQsSqFhlD0nBCtGwtCjpG_zF2lLsI3J-MtEBChrB80D2nnB1tdiz8CCuBD9HCwQhGlClehxBhkBlqBhxCjZpxoB_sCpCk0D-kE5qB2LzZz6BmsDq4CgpB44LjwRpgB_pDCnZzeo1B3kBoSC0W4K8b_bpkBw0DtCsIEtCBqFD8btgCzUte2KD5IrG-GCqOCpGCsH8NyWnJDle-d7jBwbmhBrUmSqKDC-KFhL5P-jBD0pE9jEkvFxwCi0BvoFzgHk_D3vIub-DoFwH6RpDuErDsHw3HqsCnJwHD5IooD6gB8mB0bpMrGtG2HJmD5CgCqFCnGwKD_ErF6M6M3d7T7pBtvE2_ChenUjJnZCiS8N3IzPmK-S2N5D-H7DgDiDrBrBpBrBgCC0BkDCrGrMCyKmOpG0K2K0HrM2H2HtMtMnZx4Fi4E5M9taxjH7jJBCCvxB8bshBxqBvqBpG5uOrwEonBiIupB-e0qDpfknO6OzJsLC75Fi_BxCtB7C9C4IBBCg9B3nD3EUmgDw0FjBySuuE3kBmjBrrC7JyS59CvR-lIl5BtC1sBkXsuB1sBvxEqwGzqKpgBoDnE8FxG06E1sBtCoDyShrBmxFvqF6_I1sBqFilCknC4hBnmBppC53FpJCyhBqF_KjKCDzrEvqDuCFDZtqBmqExVyc0c1fCtNkP2rDCwLoT6uCo_BB5lB1E5Jra-yBpNrJsIkTCwvBwvBlsBCu_BpxDuhE9QoLgI4T_LltB-NjFBgGyO6B-zMvECB3E8H1CCtCCiDlGmWhUnM2sCteoF0TyLamPpN-0IxV95FivGB5lBtiCtlB2oBsT7fsD1CqT-J05E2FCzatauTm_BwFBsLkL6I4d8P_PFkM6I-CsF3GiPiTx5BzNCnHB1Q5EtW6wB_Y_jBgQkevb_pBkUgJxBvHsDBCtC0KDC-F_gByKoD2HCD6_C7gHD9vI8oDoFCnClGDoVduWjG8gBq0B7jBsWpGpGtG2BJ0iBB_uC0ThzBwmC8XnR0LjHwI3V__B-Jta_iBC3gF-xDj0Cz6BnBooBjyB-V5zBt7BB5MBzC_BC-PCDhM3wCk_DzxJubyb0B0BDCgFuHkpDrkDvgC7xBhK7aC2KiFjJyD9GmL5QmI-MzCCxGDiDDjCoE8C5P6E9IoFqSoDxE5gCiXvG5C-GnNnEm8B-DiFpCzUrQnEC3xC5CC1C3JCCiDD-DJkIxQxQscqX8SoTtRlNyvBCoYrQ2HoL7G-JsO6tBoS2DjHnzBlRkIsFpH_FB4S8OBuIC2KvG_W7kDvZ0H8EDzcD7OuB2BvlBoP2HzJCCk1E","NumPoints":"4805","SourceID":"5"}],"Copyright":{"CopyrightURL":"http:\/\/windows.microsoft.com\/en-us\/windows-live\/about-bing-data-suppliers","Sources":[{"SourceID":"5","SourceName":"TOM","Copyright":"TomTom (former GDT, TeleAtlas)"}]}}]}}As far as the key goes, I don't think it's basic. Here are the details from https://www.bingmapsportal.com/ :
Key type: Enterprise / Private Windows App (8.x and earlier)
Created date: 04/13/2016
Expiration date: None
Key Status: Enabled
Wednesday, November 30, 2016 3:22 PM
Everything looks correct. The issue seems to be with the code you are using to serialize the response. What's odd is that it is saying it is encountering "R" which none of the property names start with in the response, so not sure where that is coming from. The "R" character is If you are parsing that string into shapes are part of your serialization process then the error may be in there somewhere.
Here's my function to asyncronously send and process requests. I'm using DataContractSeralizer where the Response class is the one from the API docs provided by Microsoft. Additonally, the funny thing is this was working fine for months, and when it came time to deploy on the server I noticed it was suddenly broken with no code changes (broken in debug mode in VS2015 as well as the final installed version).
/// <summary>
/// Asynchronously send all queries that have been generated and wait for them all to respond before moving on.
/// </summary>
/// <param name="queries">The Dictionary of queries to send.</param>
/// <param name="cts">CancellationTokenSource for the method to use to check for any cancel requests</param>
private void QueryBingMapsApi(Dictionary<string, Uri> queries, CancellationTokenSource cts)
{
_log.Debug($"Parameters: queries={queries.Count}, CancellationTokenSource={cts.Token}");
using (var httpClient = new HttpClient())
{
httpClient.Timeout = new TimeSpan(0, 10, 0); // 10 minutes for life of the client
var tasks = queries.Select(query => httpClient.GetAsync(query.Value, cts.Token).ContinueWith(t =>
{
try
{
_log.Debug($"{Auditor} - {query.Key}: Parsing Bing API Response.");
var response = t.Result;
if (response.StatusCode == HttpStatusCode.OK)
{
var serializer = new DataContractJsonSerializer(typeof(Response));
var r = serializer.ReadObject(t.Result.Content.ReadAsStreamAsync().Result) as Response;
if (r != null &&
r.ResultSet != null &&
r.ResultSet.Results != null &&
r.ResultSet.Results.Length > 0)
{
if (r.ResultSet.Results[0].Name.EntityName == query.Key)
{
var g = ParseBingMapsApiResponse(r, query.Key);
lock (queueLock)
{
ZipCodeRegions.Add(query.Key, g.AsBinaryZM());
}
}
else
_log.Warn($"{Auditor} - {query.Key}: Zip code requested and the returned EntityName do not match. This indicates "
+ "the zip code could be for a PO Box and will be ignored.");
}
}
else if (response.StatusCode == HttpStatusCode.NotFound)
_log.Warn($"{Auditor} - {query.Key}: Zip code was not found by Bing Maps & will be skipped.");
else
_log.Warn($"{Auditor} - {query.Key}: An exception occurred while reading the response from Bing Maps API. The following "
+ $"response code was returned: {response.StatusCode}");
}
catch (AggregateException ex)
{
if (ex.InnerException is TaskCanceledException)
{
if (((TaskCanceledException)ex.InnerException).CancellationToken == cts.Token)
_log.Error($"{Auditor} - {query.Key}: Operation was canceled.", ex.InnerException);
else
_log.Error($"{Auditor} - {query.Key}: Web request timeout.", ex.InnerException);
}
else
_log.Error($"{Auditor} - {query.Key}: An unknown exception occurred while processing the responses from Bing Maps API.",
ex.InnerException);
}
}));
Task.WhenAll(tasks).Wait();
_log.Info($"{Auditor} - Waiting for all queries.");
}
}
For completeness, heres the GeoDataServices data contract class I used:
using System.Runtime.Serialization;
/// <summary>
/// Data Contract used by Bing Maps API.
/// Source: https://code.msdn.microsoft.com/Creating-terriorties-from-73c7ebc5
/// </summary>
namespace TheNamespace
{
[DataContract]
public class Response
{
[DataMember(Name = "d", EmitDefaultValue = false)]
public ResultSet ResultSet { get; set; }
}
[DataContract]
public class ResultSet
{
[DataMember(Name = "__copyright", EmitDefaultValue = false)]
public string Copyright { get; set; }
[DataMember(Name = "results", EmitDefaultValue = false)]
public Result[] Results { get; set; }
}
[DataContract]
public class Result
{
[DataMember(Name = "EntityID", EmitDefaultValue = false)]
public string EntityID { get; set; }
[DataMember(Name = "EntityMetadata", EmitDefaultValue = false)]
public Metadata EntityMetadata { get; set; }
[DataMember(Name = "Name", EmitDefaultValue = false)]
public Name Name { get; set; }
[DataMember(Name = "Primitives", EmitDefaultValue = false)]
public Primitive[] Primitives { get; set; }
[DataMember(Name = "Copyright", EmitDefaultValue = false)]
public Copyright Copyright { get; set; }
}
[DataContract]
public class Metadata
{
[DataMember(Name = "AreaSqKm", EmitDefaultValue = false)]
public string AreaSqKm { get; set; }
[DataMember(Name = "BestMapViewBox", EmitDefaultValue = false)]
public string BestMapViewBox { get; set; }
[DataMember(Name = "OfficialCulture", EmitDefaultValue = false)]
public string OfficialCulture { get; set; }
[DataMember(Name = "RegionalCulture", EmitDefaultValue = false)]
public string RegionalCulture { get; set; }
[DataMember(Name = "PopulationClass", EmitDefaultValue = false)]
public string PopulationClass { get; set; }
}
[DataContract]
public class Name
{
[DataMember(Name = "EntityName", EmitDefaultValue = false)]
public string EntityName { get; set; }
[DataMember(Name = "Culture", EmitDefaultValue = false)]
public string Culture { get; set; }
[DataMember(Name = "SourceID", EmitDefaultValue = false)]
public string SourceID { get; set; }
}
[DataContract]
public class Primitive
{
[DataMember(Name = "PrimitiveID", EmitDefaultValue = false)]
public string PrimitiveID { get; set; }
[DataMember(Name = "Shape", EmitDefaultValue = false)]
public string Shape { get; set; }
[DataMember(Name = "NumPoints", EmitDefaultValue = false)]
public string NumPoints { get; set; }
[DataMember(Name = "SourceID", EmitDefaultValue = false)]
public string SourceID { get; set; }
}
[DataContract]
public class Copyright
{
[DataMember(Name = "CopyrightURL", EmitDefaultValue = false)]
public string CopyrightURL { get; set; }
[DataMember(Name = "Sources", EmitDefaultValue = false)]
public CopyrightSource[] Sources { get; set; }
}
[DataContract]
public class CopyrightSource
{
[DataMember(Name = "SourceID", EmitDefaultValue = false)]
public string SourceID { get; set; }
[DataMember(Name = "SourceName", EmitDefaultValue = false)]
public string SourceName { get; set; }
[DataMember(Name = "Copyright", EmitDefaultValue = false)]
public string Copyright { get; set; }
}
}
Wednesday, November 30, 2016 8:29 PM
Ah, ok, that's the issue. The Data Contracts in the documentation are for the Bing Maps REST services. The GeoData API is part of the Bing Spatial Data Services which is a different service. Here are the data contracts for the GeoData API:
using System.Runtime.Serialization; namespace Bing.GeoDataServices { [DataContract] public class Response { [DataMember(Name = "d", EmitDefaultValue = false)] public ResultSet ResultSet { get; set; } } [DataContract] public class ResultSet { [DataMember(Name = "__copyright", EmitDefaultValue = false)] public string Copyright { get; set; } [DataMember(Name = "results", EmitDefaultValue = false)] public Result[] Results { get; set; } } [DataContract] public class Result { [DataMember(Name = "EntityID", EmitDefaultValue = false)] public string EntityID { get; set; } [DataMember(Name = "EntityMetadata", EmitDefaultValue = false)] public Metadata EntityMetadata { get; set; } [DataMember(Name = "Name", EmitDefaultValue = false)] public Name Name { get; set; } [DataMember(Name = "Primitives", EmitDefaultValue = false)] public Primitive[] Primitives { get; set; } [DataMember(Name = "Copyright", EmitDefaultValue = false)] public Copyright Copyright { get; set; } } [DataContract] public class Metadata { [DataMember(Name = "AreaSqKm", EmitDefaultValue = false)] public string AreaSqKm { get; set; } [DataMember(Name = "BestMapViewBox", EmitDefaultValue = false)] public string BestMapViewBox { get; set; } [DataMember(Name = "OfficialCulture", EmitDefaultValue = false)] public string OfficialCulture { get; set; } [DataMember(Name = "RegionalCulture", EmitDefaultValue = false)] public string RegionalCulture { get; set; } [DataMember(Name = "PopulationClass", EmitDefaultValue = false)] public string PopulationClass { get; set; } } [DataContract] public class Name { [DataMember(Name = "EntityName", EmitDefaultValue = false)] public string EntityName { get; set; } [DataMember(Name = "Culture", EmitDefaultValue = false)] public string Culture { get; set; } [DataMember(Name = "SourceID", EmitDefaultValue = false)] public string SourceID { get; set; } } [DataContract] public class Primitive { [DataMember(Name = "PrimitiveID", EmitDefaultValue = false)] public string PrimitiveID { get; set; } [DataMember(Name = "Shape", EmitDefaultValue = false)] public string Shape { get; set; } [DataMember(Name = "NumPoints", EmitDefaultValue = false)] public string NumPoints { get; set; } [DataMember(Name = "SourceID", EmitDefaultValue = false)] public string SourceID { get; set; } } [DataContract] public class Copyright { [DataMember(Name = "CopyrightURL", EmitDefaultValue = false)] public string CopyrightURL { get; set; } [DataMember(Name = "Sources", EmitDefaultValue = false)] public CopyrightSource[] Sources { get; set; } } [DataContract] public class CopyrightSource { [DataMember(Name = "SourceID", EmitDefaultValue = false)] public string SourceID { get; set; } [DataMember(Name = "SourceName", EmitDefaultValue = false)] public string SourceName { get; set; } [DataMember(Name = "Copyright", EmitDefaultValue = false)] public string Copyright { get; set; } } }These data contracts are available in this open source project: http://mapstoolbox.codeplex.com/SourceControl/latest#Microsoft.Maps.Spatialtoolbox/Source/Microsoft.Maps.SpatialToolbox.Core/Bing/Services/GeoDataServices.cs
We plan to release a .NET library for the Bing Maps REST and Spatial Data Services that make it easier to connect to those services from any .NET project. These should be online in the next month or two.
Hmm, just got the same error after copy+pasting your class in there:
System.AggregateException: One or more errors occurred. > System.Runtime.Serialization.SerializationException: There was an error deserializing the object of type Bing.GeoDataServices.Response. Encountered unexpected character 'R'. > System.Xml.XmlException: Encountered unexpected character 'R'.
Used the code from your quote.
EDIT
I noticed some irregularities with the response in browser and the GeoDataServices Data contract
Here's the (formatted) browser response for zip code 88004-0000:
{
"d":{
"Copyright":"\u00a9 2016 Microsoft and its suppliers. This API and any results cannot be used or accessed without Microsoft's express written permission.",
"results":[
{
"__metadata":{
"uri":"https:\/\/platform.bing.com\/geo\/spatial\/v1\/public\/geodata?$filter=GetEntity(-37999899756L,1,0,'en','US')"
},
"EntityID":"-37999899756",
"Name":{
"EntityName":"88001",
"Culture":"en",
"SourceID":"5"
},
"Primitives":[
{
"PrimitiveID":"-37999853593",
"Shape":"1,sou3r39i-KDruCFDFB8nojB-jj-D5zD1tgKvzxE4vtFt4Hx5lCvk5B-3zEkxBziY2kkB--KkxBu5jDt7JlSi81Vt4H94I8w8BqgIgtnBywYuxQ30BsenooDswMwwI10BqqBs2Fj2Eq2Fx0BluBF5sCx-HDF8-fkuD54O58FF44DjyLxsKz3H8Pz1E7xL6qnBmC_5F6GFDFB3ufxi3DzmqC9N-EykHnguBFg5D9oDnbuYqc6uBmXzgB04D92Uu5NjgpiBgulBD3ctlFysjIFFBp8Svw2D5Mv3vBlB83wCu1gB_3cq7I_hBgoB0uBo9B0kFpmG2mYhynBqXyuB0O7E-C6I1oD7rD8J3F_J4E9FqJ5HuzJ0e9qExwFukBmsUssUwxIBopQ99PugRzkC7tS-2Er0DxhBnlvCinK38OzsqB51Bu8NrgmC-tCk-qB60Q67C-hBmyB1uB1uB-Hq_Ekf60Q0iWFyxMn5HFkiJF3pD1pHwM0gCklEFBBtyEzG4BLNE-vzBgpjNCsDyF6BWulCrE6O5G2qyC5wZ_q9DBC4HlEnE2DgCgC3CwD7GvEkIrE7MrhC5ZzpkB9umB0I2dkGvH-mBtbtHBtjCB7ocslK8yTsZ_uDyMlDzwoDDFiBr1f71LgkS3qIu_EjoBhsEqhCDlwSt1VgrF3kF00GvcD_QmB3kFlL5yPmyB4jJj3CkfjsJtgDisNh0KlXuJghC5rEDx7Ut9BtXiua97G51B7iZDFqxHmiJ-oI72bwyQglExzd5ywCipyFskBj04Ll97Rgl8Du3KpgxG9xxDqxIyUuxB7WwMlrtKmJIBnyB0gDw9B2I08gHnDlFuG3vhC4rB6lDFD7oBo2JDoyuCwsL23Hr-BDofqlBmVF7b6kEwwE2uDuUiEv2E6wIz6M5-2C_vjamx0Cny_IkZj57H8sZghhBw78CkigJ1i4ExhhEi0qSj9QszsCz0RnhBvmMmxC8_VsqBxmMiEtoI1bz5OwgSuoCuoCwuDlOjDICBgtE51GrqVxmDtlJnkIyyStzCsvBrajurCqkUopO6_yBok_CuL42pE4iRy4fw2BsvBo8HotEv0H0sHxuRgd4gGsrM0z4EotE7waw9GyrQzC-7DqI1C8sHwmC7qCuTrB5oGvoEChrB0hBnJy7M3vOkD7oChiH7lVop9BuhBvM9pFy3kBm5HjhI7wExyoB-kG96W54Bx3KsnMtGoOnJy8B_bvMvgC5qaCwKrxH1EChB4HhB2BCUY8BapBoD_B8ByDiTjN7G5J2FsI0DwIlH8KzkBuOs2C5qBtZtkB-uD1kDzex5KCnsUrZl6ND2yI-7PmFmpI-oCCkDi_Fy6G8nXDCyyCtct9B8Zq0Do0DlE9kDllDknFtsBhmBrgF52GCDlMuH1jc69nBs8QxwlDowexv8BytxD_qG7-HhqU85M_lM9oF843BvjiCjyG6by43BswhB9-H0tB84IpM7yJskC8tBl6NrzJhEhBg34IvU2jYtxB9iiBsnB1pRwnBrGCDwCSkDguB_gL_gL8gL8zLq-D3qBwhBuOySuP3a0LviCvatgQhsBzlJ1C2FkP_DBCxVkT11GkI2csppBroP6SuLuF7xOBCCnxC0HmhBymMkFjEJrBC9gHr4BpxCukClJjByDuD_5jBBCDmzL2bhElhf3kV_oHv4B20R9hiBteH9DkSvoCrqBlwEBBCClkBmD5CCu4HkOumMu4Hy4Hz8Evl7Bp5Dm9QCD4s7Bo1nD5lCrLihBtqBx6C-wI60B4b8sCt4Bi8BgnBwzRi4CovB-5BghEkimClnequCBCC8ljHD25B-kkB_1kBDCFx2fw_uCCDm8CmjI7O3yN7nO-tGvFrFo8CtDrDpD0G3BtDwC7BD0C9B9B0Ew8DF-2BhX9bFqUoUgQlS70BuR9F5LFB_PrY1iBtZCnZiDhJ1ajH8HjErMpUnkEkSlJuSqFhK0vGoiEsPuP_Ky6G5gCC75D_K-fyvB4iB5JmP6iE8hB9mKjsLg4E0SkCmGjDByhUCC76PCDjrHs80F9joBk6lD5p9FhI8UD1cDF_pFpSFsMkZokEmUFniFxHqGv2EoMF_YgZkE8a0MqQshS1KBoM0wCq4DB9E5Er5BwP9oE0dxQhVryBn8BmxBqhiD5yLkiC--J9wBohBqlTD-vEDpqQ4hmPgwhBDvjUinG2uxD6xkpBv6PvwI3mlBrjhM_i7Dkl3D9kyF_3H_sK9wB6zyBg6zJ6zyBlpwGCtqB6v4LClxG53B_yD9IyK80Bj3qBrztqE8l1kBm9Qq-CDn6nClkuEsJ",
"NumPoints":"2496",
"SourceID":"5"
}
],
"Copyright":{
"CopyrightURL":"http:\/\/windows.microsoft.com\/en-us\/windows-live\/about-bing-data-suppliers",
"Sources":[
{
"SourceID":"5",
"SourceName":"TOM",
"Copyright":"TomTom (former GDT, TeleAtlas)"
}
]
}
}
]
}
}
A couple things I noticed:
1) Actual response has "Copyright" under "d", while data contract has "__copyright"
2) Actual response has "__metadata" under "results", while contract has "EntityMetadata"
3) The metadata itself seems completely wrong. Actual response has just "uri" while contract has a lot of things like "AreaSqKm", "BestMapViewBox", ect. Thoughts?
Wednesday, November 30, 2016 10:08 PM
Additional thought, since it does process a few thousand correctly could it be something like these people experienced?
- Error occurred due to non-UTF8 character in data
- Error occurred due to DataContractJsonSerializer not removing the BOM byte sequence
Basically, lots of responses fine but somewhere along the line I get a funky character?
I tried the 2nd one but couldn't find a way to strip the BOM that fit with my code without re-writing everything.
UPDATE
Breakthrough, all the ones that fail seem to only return the header. Inspected t.Result.Content.ReadAsStringAsync().Result in the Immediate Window and all of em have this:
"Ref A: 2A9030D6EF394AF0A5A4D650CCDC63E1 Ref B: 7280DFCC4848D5F80D437111701C4C56 Ref C: Wed Nov 30 14:16:28 2016 PST"
There's your capital R, first character. Why is the server giving back just the header after a while?
Friday, December 2, 2016 4:47 PM
ok, check to see if the header has a property X-MS-BM-WS-INFO that is set to 1. If so, then the request has been rate limited. If not, then try and grab a network trace and provide that to the Bing Maps support team who you can contact here: https://support.microsoft.com/en-us/getsupport?tenant=ClassicCommercial&locale=en-us&supportregion=en-us&pesid=13766&sd=&oaspworkflow=start_1.0.0.0&wf=0&ccsid=635830587906447783
Here's another example of a header from a failed request today:
{X-MSEdge-Ref: Ref A: 8AF74994F18A44FEAF785C662D4D667D Ref B: 3366D59789E87A5752AC3DF1657ABF7A Ref C: Fri Dec 2 07:56:27 2016 PST
Cache-Control: no-store
Date: Fri, 02 Dec 2016 15:56:27 GMT
Server: Microsoft-IIS/8.5
}
Friday, December 2, 2016 6:45 PM
Not sure about this issue, please contact the Bing Maps support team.
In regards to questions about metadata. The response has two twos of metadata; __metadata and EntityMetadata. __metadata consists of a URL that is directly to the shape. EntityMetadata provides additional information about the boundary. Not all boundaries have values for all metadata properties (few boundaries have all of them). for the __copyright, it looks like this may have changed.
Ah, thanks. Will do!