Search code examples
c#genericsasp.net-web-apihttpwebrequestcompact-framework

How can I unpack a returned generic list of a custom type on the Compact Framework client?


I have a REST method on the Web API server that reads from a local-to-it MS Access table, and stores the values into a generic list, and passes that back:

public List<SiteMapping> GetSiteMappings(String userId, String pwd)
{
    List<SiteMapping> siteMappings = new List<SiteMapping>();
    string connStr =
        string.Format(
            @"Provider=Microsoft.ACE.OLEDB.12.0;User ID={0};Password={1};Data 
Source=C:\CDBWin\DATA\CDBSetup.MDB;Jet OLEDB:System database=C:\CDBWin\Data\sscs.mdw", userId, 
pwd); 
    using (var conn = new OleDbConnection(connStr))
    {
        using (OleDbCommand cmd = conn.CreateCommand())
        {
            cmd.CommandText = "SELECT site_no, location_num FROM t_sites order by site_no";
            cmd.CommandType = CommandType.Text;
            conn.Open();
            using (OleDbDataReader oleDbD8aReader = cmd.ExecuteReader())
            {
                while (oleDbD8aReader != null && oleDbD8aReader.Read())
                {
                    int siteNum = oleDbD8aReader["SiteNumber"] is DBNull
                        ? 0
                        : Convert.ToInt16(oleDbD8aReader["SiteNumber"]);
                    string locationNum = oleDbD8aReader["location_num"] is DBNull
                        ? string.Empty
                        : oleDbD8aReader["location_num"].ToString();
                    siteMappings.Add(new SiteMapping { SiteNumber = siteNum, LocationNumber = 
locationNum });
                }
            }
        }
    }
    return siteMappings;
}

public class SiteMapping
{
    public int SiteNumber { get; set; }
    public string LocationNumber { get; set; }
    public string SiteName { get; set; }
}

I call it from the client (Windows CE / Compact Framework) like so:

public ArrayList FetchSiteMappings(string url)
{
    HttpWebRequest httpwreq = SendHTTPRequestNoCredentials(url, HttpMethods.GET, String.Empty, "application/xml");
    // Idea from https://stackoverflow.com/questions/12350670/how-to-extract-zipped-file-received-from-httpwebresponse
    var response = httpwreq.GetResponse();
    var responseStream = response.GetResponseStream();
    responseStream. <= I'm stuck here
}

...but I don't know what to do with the response stream -- How do I convert what is passed back from a generic list to an ArrayList?

Here's the SendHTTPRequestNoCredentials() method, in case anybody's interested (or even if they're not):

public static HttpWebRequest SendHTTPRequestNoCredentials(string uri, HttpMethods method, string data, string contentType)
{
    WebRequest request = null;
    try
    {
        request = WebRequest.Create(uri);
        request.Method = Enum.ToObject(typeof(HttpMethods), method).ToString();
        request.ContentType = contentType;
        ((HttpWebRequest)request).Accept = contentType;
        ((HttpWebRequest)request).KeepAlive = false;
        ((HttpWebRequest)request).ProtocolVersion = HttpVersion.Version10;

        if (method != HttpMethods.GET && method != HttpMethods.DELETE)
        {
            byte[] arrData = Encoding.UTF8.GetBytes(data);
            request.ContentLength = arrData.Length;
            using (Stream oS = request.GetRequestStream())
            {
                oS.Write(arrData, 0, arrData.Length);
            }
        }
        else
        {
            request.ContentLength = 0;
        }
    }
    catch (Exception ex)
    {
        String msgInnerExAndStackTrace = String.Format(
                "{0}; Inner Ex: {1}; Stack Trace: {2}", ex.Message, ex.InnerException, 
ex.StackTrace);
        ExceptionLoggingService.Instance.WriteLog(String.Format("From 
FileXferREST.SendHTTPRequestNoCredentials(): {0}", msgInnerExAndStackTrace));
    }
    return request as HttpWebRequest;
}

UPDATE

I've changed the SendHTTPRequestNoCredentials() method to return a HttpWebResponse instead of a HttpWebRequest (see Is there something missing from this (borrowed/adapted) code, or am I not seeing where a Get gets fired? for the (minimal) details in the Update there), so the FetchSiteMappings() method has also changed; it is now:

HttpWebResponse httpwresp = SendHTTPRequestNoCredentials(url, HttpMethods.GET, String.Empty, "application/xml");
httpwresp. <= what now???

Solution

  • It seems that this should work:

    public ArrayList FetchSiteQuery(string url)
    {
        List<String> ls = new List<string>();
        byte[] buf = new byte[8192];
        string tempString = null;
        int count = 0;
        // Idea from http://stackoverflow.com/questions/12350670/how-to-extract-zipped-file-
    received-from-httpwebresponse
        HttpWebResponse httpwresp = SendHTTPRequestNoCredentials(url, HttpMethods.GET, 
    String.Empty, "application/xml");
        var responseStream = httpwresp.GetResponseStream();
        // adapted the following from http://www.csharp-station.com/HowTo/HttpWebFetch.aspx
        do
        {
            // fill the buffer with data
            count = responseStream.Read(buf, 0, buf.Length);
    
            // make sure we read some data
            if (count != 0)
            {
                // translate from bytes to ASCII text
                tempString = Encoding.ASCII.GetString(buf, 0, count);
    
                // continue building the string
                ls.Add(tempString);
            }
        }
        while (count > 0); // any more data to read?
        ArrayList myArrayList = new ArrayList();
        myArrayList.AddRange(ls);
        return myArrayList;
    }
    

    UPDATE

    Yes, it did work; this test code:

    private void button56_Click(object sender, EventArgs e)
    {
        ArrayList al = FetchSiteQuery("http://localhost:21608/api/sitequery/getall/dbill/ppus/3");
        foreach (String s in al)
        {
            MessageBox.Show(s);
        }
    }
    

    ...showed me this:

    enter image description here

    ...and several more "pages" (message box instantiations) after that.