Select to view content in your preferred language

issues passing map properties from SL to a WCF service

1093
3
08-04-2011 08:35 AM
TerryGiles
Frequent Contributor
Hi all,

I'm working on a custom ID tool to work against WMS layers in my map.  I've set up a WCF service to do most of the work but when I pass in an object (FeatureInfoParams, definition below) only the string/int properties are populated, I lose the objects (ESRI Envelope, System.Windows.Point, & System.Windows.Rect).  What do I need to change in my class to get these from the client to the server?

Thanks,  Terry


server side -

side question - If I do not mark the WMSQuery class with the [XmlSerializerFormat] attribute I get a generic "Communicators error - Not found" when I call the GetFeatureInfoAsynch client side.  Anyone know why?

namespace AWEMap.Web
{
    [ServiceContract(Namespace = "AWEMap.Web")]
    [XmlSerializerFormat]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class WMSQuery
    {
        [OperationContract]
        public void GetFeatureInfo(FeatureInfoParams FIParams)
        {

            WebClient web = new WebClient();

            string strGetFeat = FIParams.Url + "?REQUEST=GetFeatureInfo&SERVICE=WMS&VERSION=" + FIParams.Version;
            strGetFeat += "&Layers=" + FIParams.Layers;
            strGetFeat += "&STYLES=default&FORMAT=image/png&BGCOLOR=0xFFFFFF&TRANSPARENT=TRUE";
            strGetFeat += "&BBOX=" + FIParams.Extent.XMin + "," + FIParams.Extent.YMin + "," + FIParams.Extent.XMax + "," + FIParams.Extent.YMax;
            strGetFeat += "&WIDTH=" + FIParams.Map.Width + "&HEIGHT=" + FIParams.Map.Height;
            strGetFeat += "&QUERY_LAYERS=" + FIParams.Layers;
            if (FIParams.Version == "1.3.0")
            {
                strGetFeat += "&CRS=EPSG:" + FIParams.SRID;
                strGetFeat += "&I=" + FIParams.Point.X + "&J=" + FIParams.Point.Y;
            }
            else
            {
                strGetFeat += "&SRS=EPSG:" + FIParams.SRID;
                strGetFeat += "&X=" + FIParams.Point.X + "&Y=" +  FIParams.Point.Y;
            }
            ...... more code here to handle XML returned by webclient.... 
       }
   }

  [DataContract(Namespace = "AWEMap.Web")]
    public class FeatureInfoParams : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public FeatureInfoParams() { }

        private string _url;
        private string _version;
        private string _layers;
        private int _srid;
        private Envelope _extent;
        private Rect _map;
        private Point _point;

        [DataMember]
        public string Url
        {
            get { return _url; }
            set { _url = value; NotifyPropertyChanged("Url"); }
        }
        [DataMember]
        public string Version
        {
            get { return _version; }
            set { _version = value; NotifyPropertyChanged("Version"); }
        }
        [DataMember]
        public string Layers
        {
            get { return _layers; }
            set { _layers = value; NotifyPropertyChanged("Layers"); }
        }
        [DataMember]
        public int SRID
        {
            get { return _srid; }
            set { _srid = value; NotifyPropertyChanged("SRID"); }
        }
        [DataMember]
        public Envelope Extent
        {
            get { return _extent; }
            set { _extent = value; NotifyPropertyChanged("Extent"); }
        }
        [DataMember]
        public Rect Map
        {
            get { return _map; }
            set { _map = value; NotifyPropertyChanged("Map"); }
        }
        [DataMember]
        public Point Point
        {
            get { return _point; }
            set { _point = value; NotifyPropertyChanged("Point"); }
        }

        public void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        } 



client side
                        WLyr = (_Map.Layers as WmsLayer);
                        WMSQueryService.WMSQueryClient client = new WMSQueryService.WMSQueryClient("RelativeBinding_WMSQuery");
                        WMSQueryService.FeatureInfoParams fip = new WMSQueryService.FeatureInfoParams()
                        {
                            Url = WLyr.Url,
                            Extent = _Map.Extent,
                            Layers = string.Join(",", WLyr.Layers),
                            Map = new System.Windows.Rect(0, 0, _Map.Width, _Map.Height),
                            Point = new Point(_Map.MapToScreen(ptMapPoint).X, _Map.MapToScreen(ptMapPoint).Y),
                            SRID = _Map.SpatialReference.WKID,
                            Version = WLyr.Version
                        };
                        client.GetFeatureInfoAsync(fip);
0 Kudos
3 Replies
PatrickBrooke
Emerging Contributor
I don't have the code samples to show you, but you will have to serialize those objects. For example, I sent a png image, awhile back for client to server, and I had to convert it to a string (Base64). I have a sample of how to do that to an image. Basically, you need to convert all of those values to int or string to send them through WCF.

I know this is not s silver bullet solution, but I hope the logic is helpful.

byte[] byt = System.Text.Encoding.UTF8.GetBytes(strOriginal);


    // convert the byte array to a Base64 string


    strModified = Convert.ToBase64String(byt);
0 Kudos
PatrickBrooke
Emerging Contributor
Also, this is actually closer to what you are doing:

http://weblogs.asp.net/albertpascual/archive/2009/04/06/serializing-json-geometry-objects-between-si...

Same rule applies, you must serialize objects to string/json/html or whatever when send through WCF.
0 Kudos
TerryGiles
Frequent Contributor
Thanks Patrick I saw that blog earlier today too.  In the end I changed from trying to pass the objects to just passing their properties I needed (point.X map.Width, etc..) as primative types (string, double, etc...).

Also found a good summary of what works with the DataContractSerializer from Microsoft here - http://msdn.microsoft.com/en-us/library/cc656732.aspx
0 Kudos