Unable to populate the libRETS query using SearchResultSet

1.2k Views Asked by At

I am very new to libRETS. I wanted to pull some MLS data from MidWEST RETS service. I followed the sample mentioned in web RESO official website. http://www.reso.org/assets/Resources/CodeExamples/c-sharp-connection-ex.txt. I am using C# as the programming language and using nuget package https://www.nuget.org/packages/libRETS-x64/. I am able to login, but after sending query, I am not getting the result. I am pasting my sample below.

using librets;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LibRETSExample
{
    public class RetsHelper : IDisposable
    {
        private List<Listing> listings = new List<Listing>();

        #region Properties

        /// <summary>
        /// Contains the rets session connection.
        /// </summary>
        internal RetsSession Session
        {
            get
            {
                return _sess;
            }
            set
            {
                _sess = value;
            }
        }
        private RetsSession _sess;

        #endregion


        #region Constructors

        public RetsHelper(string url, string userAgent, string userName,
            string password)
        {
            this.Session = new RetsSession(url);
            //this.Session.SetUserAgent(userAgent);
            this.Session.LoggerDelegate = new RetsHttpLogger.Delegate(LogRETS);
            //this.Session.SetDefaultEncoding(EncodingType.RETS_XML_ISO_ENCODING);
            try
            {   //Log in to RETS
                bool loginResult = this.Session.Login(userName, password);

                if (!loginResult)
                {
                    Trace.WriteLine("\nLogin to RETS Failed at " + DateTime.Now);
                }
                else
                {
                    Trace.WriteLine("\nLogin to RETS Succeeded at " + DateTime.Now);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        #endregion

        #region Instance Methods

        /// <summary>
        /// Gets search results for a given query.
        /// </summary>
        /// <param name="searchType">Resource from rets metadata</param>
        /// <param name="searchClass">Class from rets metadata</param>
        /// <param name="query">RETS query to run.</param>
        /// <param name="offset">Record number to start at.  This is 1-based, not zero-based.</param>
        /// <returns>Results of query.</returns>
        internal SearchResultSet GetRetsSearchResults(string searchType, string searchClass, 
            string query, int offset)
        {
            using (SearchRequest search = this.Session.CreateSearchRequest(
                searchType, searchClass.ToString(), query))
            {
                search.SetQueryType(SearchRequest.QueryType.DMQL2);
                search.SetStandardNames(false);
                search.SetLimit(10);
                //search.SetFormatType(SearchRequest.FormatType.COMPACT);
                search.SetOffset(offset);

                SearchResultSet results = this.Session.Search(search);
                return results;
            }
        }


        /// <summary>
        /// Downloads all listings, starting at the given offset.  This method will recurse if needed.
        /// </summary>
        /// <param name="propType"></param>
        /// <param name="offset">Starting record of results.  This is 1-based, not zero-based.</param>
        internal void DownloadAllListings(string propType, int offset)
        {
            try
            {
                using (SearchResultSet results = GetRetsSearchResults("Property", propType, "(LP=300000-)", offset))
                {
                    // get the results as a list of objects.
                    List<Listing> list = Populate(results);

                    // Add to the master list
                    listings.AddRange(list);              

                    // check to see if the list finished to the end.
                    int totalProcessed = list.Count + offset;
                    if (results.GetCount() > totalProcessed)
                    {
                        // recurse if needed.
                        DownloadAllListings(propType, totalProcessed);
                    }
                }
            }
            catch (Exception ex)
            {
                Trace.WriteLine(ex.Message);
            }
        }

        public List<Listing> GetAllListings(string propType, int offset)
        {
            listings.Clear();
            DownloadAllListings(propType, offset);
            return listings;
        }

        /// <summary>
        /// Populates a ListingCollection from a RETS result set.
        /// </summary>
        /// <param name="results">ResultSet to create the ListingCollection from.</param>
        /// <returns>ListingCollection representing the result set.  Will return 
        /// an empty collection if no records.</returns>
        private List<Listing> Populate(SearchResultSet results)
        {
            List<Listing> listings = new List<Listing>();

            while (results.HasNext())
            {
                Listing currentListing = new Listing();
                //sample db mapping
                currentListing.StreetNumber = results.GetString("StreetNumber");
                currentListing.StreetDirection = results.GetString("StreetDirection");
                currentListing.StreetName = results.GetString("StreetName");
                listings.Add(currentListing);
            }
            return listings;
        }

        #endregion

        #region IDisposable Members
        /// <summary>
        /// Logout of the RETS session.
        /// </summary>
        public void Dispose()
        {
            try
            {
                Session.Logout();
            }
            finally
            {
                Session.Dispose();
            }
        }

        #endregion

        public void LogRETS(RetsHttpLogger.Type type, byte[] data)
        {
            Trace.WriteLine(type.ToString() + ": " + Encoding.UTF8.GetString(data));
        }

    }

    public class Listing
    {
        public string StreetNumber { get; set; }

        public string StreetDirection { get; set; }

        public string StreetName { get; set; } 
    }
}

The issue I am facing is inside the function private List Populate(SearchResultSet results), the code will never enter into while loop since HasNext() always returns false. But actually query has been sent to server and server returns the results. I am able to see them in Trace window as xml data. Please note that I have attached a logger delegate. I am kind of clueless why my populate function is failing eventhough server returned the query results. Any kind of help will be appreciated.

1

There are 1 best solutions below

0
On

You may need to configure the search format type. I know that FlexMLS requires COMPACT_DECODED to be used or hasNext() will return false.

searchRequest.SetFormatType(SearchRequest.FormatType.COMPACT_DECODED);