Connection to bingmap api fails when invoke via COM interop

Jianmin Wang 1 Reputation point
2022-12-14T18:49:50.827+00:00

I have a C# component that interacts with Bing Map API for geocoding and other services using WebClient from .Net framework. The component is COM visible. It has been working well for years in the field. It recently fails when invoked via COM. The error message is something like "The underlying connection was closed: An unexpected error occurred on a send." Any suggestions of what could be the problems?

Thanks.

Windows for home | Windows 11 | Apps
{count} votes

1 answer

Sort by: Most helpful
  1. Jianmin Wang 1 Reputation point
    2022-12-15T04:25:33.803+00:00

    Hello TongXu,
    The API involved is Bing Map location. The end point is https://dev.virtualearth.net/REST/v1/Locations. Here is the code used the sample project to reproduce the problem outside the actual application. It is a VS 2017 project (I tried with VS 2019 and encountered the same issue.)

    After building the project, I tried to invoke its method in PowerShell, e.g.,

    $obj = New-Object -ComObject "BingMapHelper.GeocodingService"
    $obj.GeocodeSites("1 Microsoft|Way|Redmond|WA|", <my bing map api key>)

    Really appreciate your taking time to look into this.

    GeocodingService.cs

    namespace BingMapHelper
    {
    [ClassInterface(ClassInterfaceType.AutoDual)]
    [ComVisible(true)]
    public class GeocodingService
    {
    [ComVisible(true)]
    public string GeocodeSites(string siteTable, string key)
    {
    string result = "";

            //split into address componenet  
            string[] tokens = siteTable.Split('|');  
            GAddress address = new GAddress();  
            address.Address1 = tokens[0];  
            address.City = tokens[1];  
            address.State = tokens[2];  
            address.Zip = tokens[3];  
            address.Country = tokens[4];  
    
            BingGeocoder geocoder = new BingGeocoder();  
            geocoder.Key = key;  
    
    
            BingGeoResults response = geocoder.BingGeocodeSite(address);  
            Trace.WriteLine(response.resourceSets[0].resources[0].ToString());  
            double lon = response.resourceSets[0].resources[0].geocodePoints[0].coordinates[0];  
            double lat = response.resourceSets[0].resources[0].geocodePoints[0].coordinates[1];  
            result = lon.ToString() + " " + lat.ToString();  
            return result;  
        }  
    }  
    

    }

    BingGeocoder.cs

    using BingMapsRESTToolkit;

    using Newtonsoft.Json;

    namespace BingMapHelper
    {
    public class BingGeocoder
    {
    const string BING_LOCATION_SERVICE = "https://dev.virtualearth.net/REST/v1/Locations?q={0}&&maxResults=5&key={1}";

         public string Key { get; set; }  
         
        public BingGeoResults BingGeocodeSite(GAddress address)  
        {  
            if (string.IsNullOrEmpty(Key))  
            {  
                throw new MissingFieldException("Your API Key is missing");  
            }  
    
            using (var client = new WebClient())  
            {  
                string formatAddress = string.Format(BING_LOCATION_SERVICE, EncodeAddress(address), Key);  
                var result = client.DownloadString(formatAddress);  
                var O = JsonConvert.DeserializeObject<BingGeoResults>(result);  
                // SetGeoResultFlag(O.status);  
                return O;  
            }  
        }  
        
        private string EncodeAddress(GAddress address)  
        {  
            var sb = new StringBuilder();  
    
            if (!string.IsNullOrEmpty(address.Address1))  
                sb.Append(Uri.EscapeUriString(" " + address.Address1));  
    
            if (!string.IsNullOrEmpty(address.Address2))  
                sb.Append(Uri.EscapeUriString(" " + address.Address2));  
    
            if (!string.IsNullOrEmpty(address.City))  
                sb.Append(Uri.EscapeUriString(" " + address.City));  
    
            if (!string.IsNullOrEmpty(address.State))  
                sb.Append(Uri.EscapeUriString(" " + address.State));  
    
            if (!string.IsNullOrEmpty(address.Zip))  
                sb.Append(Uri.EscapeUriString(" " + address.Zip));  
    
    
            return sb.ToString();  
        }  
    }  
    
    
    public class Point  
    {  
        public string type { get; set; }  
        public List<double> coordinates { get; set; }  
    }  
    
    
    public class Address  
    {  
        public string addressLine { get; set; }  
        public string adminDistrict { get; set; }  
        public string adminDistrict2 { get; set; }  
        public string countryRegion { get; set; }  
        public string formattedAddress { get; set; }  
        public string locality { get; set; }  
        public string postalCode { get; set; }  
    
        //we may include mora fields if needed.  
    }  
    
    public class GeocodePoint  
    {  
        public string type { get; set; }  
        public List<double> coordinates { get; set; }  
        public string calculationMethod { get; set; }  
        public List<string> usageTypes { get; set; }  
    }  
    
    public class Resource  
    {  
        public string __type { get; set; }  
        public List<double> bbox { get; set; }  
        public string name { get; set; }  
        public Point point { get; set; }  
        public Address address { get; set; }  
        public string confidence { get; set; }  
        public string entityType { get; set; }  
        public List<GeocodePoint> geocodePoints { get; set; }  
        public List<string> matchCodes { get; set; }  
    }  
    
    public class ResourceSet  
    {  
        public int estimatedTotal { get; set; }  
        public List<Resource> resources { get; set; }  
    }  
    
    public class BingGeoResults  
    {  
        public string authenticationResultCode { get; set; }  
        public string brandLogoUri { get; set; }  
        public string copyright { get; set; }  
        public List<ResourceSet> resourceSets { get; set; }  
        public int statusCode { get; set; }  
        public string statusDescription { get; set; }  
        public string traceId { get; set; }  
    }  
    
    public class GAddress  
    {  
        public string Address1 { get; set; }  
        public string Address2 { get; set; }  
        public string City { get; set; }  
        public string State { get; set; }  
        public string Country { get; set; }  
        public string Zip { get; set; }  
    }  
     
    

    }

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.