Main Site Documentation

Gadgeteer.Networking.Responder.Body is null frequently receiving a http POST


#1

I am using the Gadgeteer.Networking.WebServer class to transmit a web page that is an html form with a few data entry fields and a submit button. When the user presses the submit button to send post the data entry fields back to the WebServer, most of the time, in the WebEventReceived event handler, the Responder.Body.Text is null, but I discovered that the Responder.Body.RawContent byte array has the posted text but offset from the start of the RawContent array by many zero bytes. Sometimes the zero bytes are not there and the Responder.Body.Text is not null, it contains the correct text from the posted page. Please look into why this is happening.

My web server code:


using System;
using System.Text;
using System.Threading;
using Gadgeteer;
using Microsoft.SPOT;
using Gadgeteer.Networking;
using System.Collections;
using Configuration;
using DeviceHive;

namespace WebInterface
{

    public class WebPage
    {
        public string Content;
        public string MimeType;
        public string Url;

        public WebPage(string _Content, string _Url, string _MimeType)
        {
            Content = _Content;
            Url = _Url;
            MimeType = _MimeType;
        }
    }

    /// <summary>     
    /// This is our sample web server app project     
    /// </summary>     
    /// 
    public class WebApp     
    {         
        /*
        private WebEvent signup;
        private WebEvent defaultcss;
         */ 

        private Mainboard mainboard;         
        private string ipAddress = "0.0.0.0";
        private Hashtable WebPageList;
        private NetworkConfigData netData;
        private SystemConfigData systemData;

        public WebApp(Mainboard _mainboard,  NetworkConfigData _netData, SystemConfigData _systemData, Hashtable _WebPageList)         
        {             
            mainboard = _mainboard;
            netData = _netData;
            systemData = _systemData;
            WebPageList = _WebPageList;
            // create our web events
            InitWebEvents();
        }         

        private void InitWebEvents()
        {
                foreach (string key in WebPageList.Keys)
                {
                    WebServer.SetupWebEvent(key).WebEventReceived += new WebEvent.ReceivedWebEventHandler(WebEventReceived);
                }
        }

        void WebEventReceived(string path, WebServer.HttpMethod method, Responder responder)
        {
            try
            {
                WebPage PageData = (WebPage)WebPageList[path];
                string content = PageData.Content;

                if ( PageData.Url.ToLower() == "smartcardhome.htm" )
                {
                    if (method == WebServer.HttpMethod.POST)
                    {
                        string Body = responder.Body.Text;
                        if (Body != null)
                        {
                            Debug.Print("responder.Body.Text is OK");
                            Debug.Print(Body);
                            content = Body;
                        }
                        else
                        {
                            //random bug here - responder.Body.Text is null, but the 
                            //responder.Body.RawContent byte array contains the text offset by many zeros
                            int len = responder.Body.RawContent.Length;
                            byte[] raw = new byte[len];
                            for (int i = 0, j = 0; i < len; i++)
                            {
                                if (responder.Body.RawContent[i] > 0)
                                {
                                    raw[j] = responder.Body.RawContent[i];
                                    j++;
                                }
                            }
                            if (raw.Length > 0)
                            {
                                content = new string(Encoding.UTF8.GetChars(raw));
                                Debug.Print("responder.Body.Text is null, I fixed it");
                            }
                            else
                            {
                                content = "responder.Body.RawContent is null, cannot be fixed";
                                Debug.Print("responder.Body.Text is null, cannot be fixed");
                            }
                        }
                    }
                    else if (method == WebServer.HttpMethod.GET)
                    {

                        //replace placeholder text vertical bar in web page with the run-time text
                        //regular expressions are much too slow, use split function instead
                        string[] parts = content.Split(new char[] { '|' });
                        if (parts.Length == 9)
                        {
                            content = parts[0] + netData.MacAddress.ToHex()
                                    + parts[1] + netData.StaticIP
                                    + parts[2] + netData.NetMask
                                    + parts[3] + netData.GatewayAddress
                                    + parts[4] + netData.CloudIP
                                    + parts[5] + systemData.ModelNumber
                                    + parts[6] + systemData.SerialNumber
                                    + parts[7] + systemData.DeviceHiveId.ToString()
                                    + parts[8];
                        }
                    }
                }

                byte[] data = Encoding.UTF8.GetBytes(content);
                responder.Respond(data, PageData.MimeType);
            }
            catch (Exception ex)
            {
                Debug.Print("WebEventReceived(): " + ex.ToString());
            }
        }

        /// <summary>         
        /// Start the server         
        /// </summary>         
        /// <param name="IPAddress"></param>         
        public bool StartServer(string _IPAddress)
        {
            ipAddress = _IPAddress; 
            WebServer.StartLocalServer(_IPAddress, 80);
            Debug.Print("Web server started at: " + _IPAddress );
            return true;
        }     

    } 
}

The code that starts the web server:



            //Set up web pages
            WebPageList = new Hashtable();
            HomePageData = new WebPage(Resources.GetString(Resources.StringResources.smartcardhome), "smartcardhome.htm",  "text/html");
            CssPageData = new WebPage(Resources.GetString(Resources.StringResources.smartcardcss), "smartcard.css", "text/css" );
            //Keys for the HashTable should be the URL paths
            WebPageList.Add("smartcardhome", HomePageData);
            WebPageList.Add("smartcardhome.htm", HomePageData);
            WebPageList.Add("index.htm", HomePageData);
            WebPageList.Add("smartcard.css", CssPageData);
            webServer = new WebApp(Mainboard, netData, systemData, WebPageList);

                if (webServer.StartServer(netData.StaticIP) )
                {
                    WebServerStarted = true;
                    Debug.Print("Web Server started");
                }
                else
                {
                    Debug.Print("Web Server cannot start ");
                }





#2

Can you create a minimal complete program with as little code as possible that reproduces the problem along with a sample HTML page that we can test with?


#3

I give you below a working demo in a Gadgeteer Cobra II board VS2010 NETMF 4.2 project with no external Gadgeteer modules. Here is the C# file Program.cs, a web page smartcardhome.htm, and a style sheet smartcard.css. You do not have a text paste code for html in the forum, so I used the CS code to past the web page text here. You will have to add smartcardhome.htm as a file resource named “smartcardhome” and smartcard.css as a file resource named “smartcardcss”, in Resources.resx. A web server is started at IP address 192.168.8.235. Browse to http://192.168.8.235/smartcardhome. Press the submit button, see the result, go back and press the submit button again, about 10 times. Watch what happens in the function “fixResponderText”. When the submit button is pressed, responder.Body.Text is null about half the time.


//Program.cs
using System;
using System.Text;
using System.Collections;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Controls;
using Microsoft.SPOT.Presentation.Media;
using Microsoft.SPOT.Presentation.Shapes;
using Microsoft.SPOT.Touch;
using Microsoft.SPOT.Net.NetworkInformation;
using Microsoft.SPOT.Hardware;

using Gadgeteer.Networking;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using GHINET = GHI.Premium.Net;
using GHI.Hardware.G120;
using GHI.Premium.System;

namespace GadgeteerDemoWebApp
{
    public partial class Program
    {
        private Hashtable WebPageList;
        private WebPage HomePageData;
        private WebPage CssPageData;
        private HTTPServer webServer;
        private NetworkConfigData netData;
        private SystemConfigData systemData;
        private GHINET.EthernetENC28J60 eth;
        private Microsoft.SPOT.Net.NetworkInformation.NetworkInterface ni;
        private AutoResetEvent CableConnectedEvent;
        private static StringBuilder sb = new StringBuilder();
        private static Object StringBuilderLock = new Object();


        // This method is run when the mainboard is powered up or reset.   
        void ProgramStarted()
        {
            /*******************************************************************************************
            Modules added in the Program.gadgeteer designer view are used by typing 
            their name followed by a period, e.g.  button.  or  camera.
            
            Many modules generate useful events. Type +=<tab><tab> to add a handler to an event, e.g.:
                button.ButtonPressed +=<tab><tab>
            
            If you want to do something periodically, use a GT.Timer and handle its Tick event, e.g.:
                GT.Timer timer = new GT.Timer(1000); // every second (1000ms)
                timer.Tick +=<tab><tab>
                timer.Start();
            *******************************************************************************************/

            ThreadStart starter = new ThreadStart(ProcessCommands);
            Thread th = new Thread(starter);
            th.Start();

            // Use Debug.Print to show messages in Visual Studio's "Output" window during debugging.
            Debug.Print("Program Started");

        }

        /// <summary>
        /// Initialize objects, start the network interface, start the web server
        /// </summary>
        void ProcessCommands()
        {
            try
            {
                CableConnectedEvent = new AutoResetEvent(false);

                //Set up data objects for the data entry fields on the web page
                byte[] MacAddress = new byte[] { 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 };
                string StaticIP = "192.168.8.235";
                string NetMask = "255.255.255.0";
                string GatewayAddress = "0.0.0.0";
                string PrimaryDNS = "0.0.0.0";
                string SecondaryDNS = "0.0.0.0";
                string CloudIP = "0.0.0.0";
                netData = new NetworkConfigData(MacAddress, StaticIP, NetMask, GatewayAddress, PrimaryDNS, SecondaryDNS, CloudIP);
                string ModelNumber = "SCD10003";
                string SerialNumber = "CWCSCD11234";
                Guid DeviceHiveId = Guid.NewGuid();
                Guid DeviceHiveKey = Guid.NewGuid();
                systemData = new SystemConfigData(ModelNumber, SerialNumber, DeviceHiveId, DeviceHiveKey);

                //Set up virtual web pages for the web server
                WebPageList = new Hashtable();
                HomePageData = new WebPage(Resources.GetString(Resources.StringResources.smartcardhome), "smartcardhome.htm", "text/html");
                CssPageData = new WebPage(Resources.GetString(Resources.StringResources.smartcardcss), "smartcard.css", "text/css");
                //Keys for the HashTable should be the URL paths to virtual web pages
                WebPageList.Add("smartcardhome", HomePageData);
                WebPageList.Add("smartcardhome.htm", HomePageData);
                WebPageList.Add("index.htm", HomePageData);
                WebPageList.Add("smartcard.css", CssPageData);
                webServer = new HTTPServer(WebPageList);
                webServer.webServer_WebEventHandler += new WebEvent.ReceivedWebEventHandler(WebEventHandler);

                StartTCPIP();
                webServer.StartServer(netData.StaticIP);
            }
            catch (Exception ex)
            {
                Debug.Print("Could not start program: " + ex.ToString() );
            }

        }

        /// <summary>
        /// Handle requests for web pages from the webServer object  
        /// </summary>
        /// <param name="path">relative URL path to the page</param>
        /// <param name="method">http method GET or POST</param>
        /// <param name="responder">Responder class object</param>
        public void WebEventHandler(string path, WebServer.HttpMethod method, Responder responder)
        {
            try
            {

                WebPage PageData = (WebPage)WebPageList[path];
                string content = PageData.Content;

                if (PageData.Url.ToLower() == "smartcardhome.htm")
                {
                    if (method == WebServer.HttpMethod.POST)
                    {
                        content = webServer.fixResponderText(responder);
                        if (content == null)
                        {
                            content = "responder.Body.Text is null, cannot be fixed";
                        }
                    }
                    else if (method == WebServer.HttpMethod.GET)
                    {
                        if ((netData != null) && (systemData != null))
                        {
                            //replace placeholder text vertical bar in web page with the run-time text
                            //regular expressions are much too slow, use split function instead
                            string[] parts = content.Split(new char[] { '|' });
                            if (parts.Length == 9)
                            {
                                content = parts[0] + netData.MacAddress.ToHex()
                                        + parts[1] + netData.StaticIP
                                        + parts[2] + netData.NetMask
                                        + parts[3] + netData.GatewayAddress
                                        + parts[4] + netData.CloudIP
                                        + parts[5] + systemData.ModelNumber
                                        + parts[6] + systemData.SerialNumber
                                        + parts[7] + systemData.DeviceHiveId.ToString()
                                        + parts[8];
                            }
                        }
                        else
                        {
                            content = "memory cannot be read";
                        }
                    }
                }

                byte[] data = Encoding.UTF8.GetBytes(content);
                responder.Respond(data, PageData.MimeType);
            }
            catch (Exception ex)
            {
                Debug.Print("WebEventReceived(): " + ex.ToString());
            }
        }


        /// <summary>
        /// Start the  TCP/IP network interface
        /// </summary>
        /// <returns></returns>
        private bool StartTCPIP()
        {
            bool rc = false;
            eth = new GHINET.EthernetENC28J60(SPI.SPI_module.SPI2, Pin.P1_10, Pin.P2_11, Pin.P1_9, 4000);
            eth.NetworkAddressChanged += new GHINET.NetworkInterfaceExtension.NetworkAddressChangedEventHandler(eth_NetworkAddressChanged);
            eth.CableConnectivityChanged += new GHINET.EthernetENC28J60.CableConnectivityChangedEventHandler(eth_CableConnectivityChanged);
            GHI.Premium.System.Util.SetMACAddress(GHI.Premium.System.NetworkInterface.ENC28j60_Ethernet, netData.MacAddress);
            if (!eth.IsOpen) eth.Open();
            if (!eth.IsCableConnected)
            {
                Debug.Print("Ethernet cable is not connected, waiting for connection");
                CableConnectedEvent.WaitOne();
                Thread.Sleep(1000);
            }
            ni = eth.NetworkInterface;
            if (ni == null)
            {
                rc = false;
                return rc;
            }

            //report MAC address settings
            byte[] PhyAddress = netData.MacAddress;
            string sMAC = BytesToHexString(PhyAddress, PhyAddress.Length);
            Debug.Print("MAC address in flash memory = " + sMAC);
            PhyAddress = ni.PhysicalAddress;
            sMAC = BytesToHexString(PhyAddress, PhyAddress.Length);
            Debug.Print("MAC address in Network Interface = " + sMAC);

            //set IP, Gateway, DNS IPs
            ni.EnableStaticIP(netData.StaticIP, netData.NetMask, netData.GatewayAddress);
            ni.EnableStaticDns(new string[] { netData.PrimaryDNS, netData.SecondaryDNS });

            GHINET.NetworkInterfaceExtension.AssignNetworkingStackTo(eth);

            if (eth.IsActivated)
                Debug.Print("EthernetENC28J60 is activated");
            else
                Debug.Print("EthernetENC28J60 is shut down");

            if (eth.IsOpen)
                Debug.Print("EthernetENC28J60 interface is open");
            else
                Debug.Print("EthernetENC28J60 interface is closed");

            if (eth.IsCableConnected)
                Debug.Print("EthernetENC28J60 cable is connected");
            else
                Debug.Print("EthernetENC28J60 cable is not connected");

            int waitCount = 60;
            bool niSet = false;
            while ((waitCount > 0) && !niSet)
            {
                Thread.Sleep(1000);
                waitCount--;
                if ((ni.IPAddress == netData.StaticIP) && (ni.SubnetMask == netData.NetMask))
                    niSet = true;
            }

            if (niSet)
            {
                Debug.Print("EthernetENC28J60 IP address has been set: IP = " + ni.IPAddress + " Subnet mask = " + ni.SubnetMask);
                rc = true;
            }
            else
            {
                Debug.Print("Could not set EthernetENC28J60 IP address");
                rc = false;
            }
            return rc;
        }

        void eth_CableConnectivityChanged(object sender, GHINET.EthernetENC28J60.CableConnectivityEventArgs e)
        {
            try
            {
                if (e.IsConnected)
                {
                    Debug.Print("PrototypeDevice.CableConnectivityChanged Event - Ethernet cable is connected");
                    CableConnectedEvent.Set();
                }
                else
                {
                    Debug.Print("PrototypeDevice.CableConnectivityChanged Event - Ethernet cable is not connected");
                }
            }
            catch (Exception ex)
            {
                Debug.Print("PrototypeDevice.eth_CableConnectivityChanged() exception " + ex.ToString());
            }
        }

        void eth_NetworkAddressChanged(object sender, EventArgs e)
        {
            try
            {
                Microsoft.SPOT.Net.NetworkInformation.NetworkInterface ni = eth.NetworkInterface;
                Debug.Print("NetworkAddressChanged Event");
                if (ni.IsDhcpEnabled)
                    Debug.Print("DHCP is enabled");
                else
                    Debug.Print("DHCP is disabled");
                Debug.Print("IP address = " + ni.IPAddress);
                Debug.Print("Gateway address = " + ni.GatewayAddress);
                Debug.Print("Subnet mask = " + ni.SubnetMask);

                foreach (string address in ni.DnsAddresses)
                {
                    Debug.Print("DNS address  = " + address);
                }
            }
            catch (Exception ex)
            {
                Debug.Print("eth_NetworkAddressChanged() exception " + ex.ToString());
            }
        }



        /// <summary>
        /// Convert byte array to a ASCII-HEX character string
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static string BytesToHexString(byte[] Data, int Count)
        {
            string rv = "";
            try
            {
                lock (StringBuilderLock)
                {
                    sb.Clear();
                    for (int i = 0; i < Count; i++)
                    {
                        sb.Append(Data[i].ToHex());
                    }
                    rv = sb.ToString();
                }
            }
            catch (Exception ex)
            {
                Debug.Print("Exception in BytesToHexString(): " + ex.ToString());
            }
            return rv;
        }


    } //class Program


    /// <summary>
    /// TCP/IP network configuration
    /// </summary>
    public class NetworkConfigData
    {
        public byte[] MacAddress { get; set; }
        public string StaticIP { get; set; }
        public string NetMask { get; set; }
        public string GatewayAddress { get; set; }
        public string PrimaryDNS { get; set; }
        public string SecondaryDNS { get; set; }
        public string CloudIP { get; set; }


        public NetworkConfigData(
                                    byte[] _MacAddress,
                                    string _StaticIP,
                                    string _NetMask,
                                    string _GatewayAddress,
                                    string _PrimaryDNS,
                                    string _SecondaryDNS,
                                    string _CloudIP
                                 )
        {
            MacAddress = _MacAddress;
            StaticIP = _StaticIP;
            NetMask = _NetMask;
            GatewayAddress = _GatewayAddress;
            PrimaryDNS = _PrimaryDNS;
            SecondaryDNS = _SecondaryDNS;
            CloudIP = _CloudIP;
        }

    }


    /// <summary>
    /// Device configuration data
    /// </summary>
    public class SystemConfigData
    {
        public string ModelNumber { get; set; }
        public string SerialNumber { get; set; }
        public Guid DeviceHiveId { get; set; }
        public Guid DeviceHiveKey { get; set; }

        public SystemConfigData(
                                    string _ModelNumber,
                                    string _SerialNumber,
                                    Guid _DeviceHiveId,
                                    Guid _DeviceHiveKey
                                 )
        {
            ModelNumber = _ModelNumber;
            SerialNumber = _SerialNumber;
            DeviceHiveId = _DeviceHiveId;
            DeviceHiveKey = _DeviceHiveKey;
        }

    }


    public class WebPage
    {
        public string Content;
        public string MimeType;
        public string Url;

        public WebPage(string _Content, string _Url, string _MimeType)
        {
            Content = _Content;
            Url = _Url;
            MimeType = _MimeType;
        }
    }

    /// <summary>     
    /// This is our sample web server app project     
    /// </summary>     
    /// 
    public class HTTPServer
    {
        private string ipAddress = "0.0.0.0";
        private Hashtable WebPageList;
        public event WebEvent.ReceivedWebEventHandler webServer_WebEventHandler;

        public HTTPServer(Hashtable _WebPageList)
        {
            WebPageList = _WebPageList;
            // create our web events
            foreach (string key in WebPageList.Keys)
            {
                WebServer.SetupWebEvent(key).WebEventReceived += new WebEvent.ReceivedWebEventHandler(WebEventHandler);
            }
        }

        /// <summary>
        /// Send web events to the Business Logic module for handling
        /// </summary>
        /// <param name="path"></param>
        /// <param name="method"></param>
        /// <param name="responder"></param>
        void WebEventHandler(string path, WebServer.HttpMethod method, Responder responder)
        {
            if (webServer_WebEventHandler != null)
            {
                webServer_WebEventHandler(path, method, responder);
            }
        }

        public string fixResponderText(Responder responder)
        {
            string content = null;
            if (responder.Body != null)
            {
                if (responder.Body.Text != null)
                {
                    Debug.Print("responder.Body.Text is valid");
                    content = responder.Body.Text;
                }
                else
                {
                    //random bug here - responder.Body.Text is null, but the 
                    //responder.Body.RawContent byte array contains the text offset by many zeros
                    int len = responder.Body.RawContent.Length;
                    byte[] raw = new byte[len];
                    for (int i = 0, j = 0; i < len; i++)
                    {
                        if (responder.Body.RawContent[i] > 0)
                        {
                            raw[j] = responder.Body.RawContent[i];
                            j++;
                        }
                    }
                    if (raw.Length > 0)
                    {
                        content = new string(Encoding.UTF8.GetChars(raw));
                        Debug.Print("responder.Body.Text is null, I fixed it");
                    }
                    else
                    {
                        Debug.Print("responder.Body.Text is null, cannot be fixed");
                    }
                }
            }
            return content;
        }

        /// <summary>         
        /// Start the server         
        /// </summary>         
        /// <param name="IPAddress"></param>         
        public bool StartServer(string _IPAddress)
        {
            ipAddress = _IPAddress;
            WebServer.StartLocalServer(_IPAddress, 80);
            Debug.Print("Web server started at: " + _IPAddress);
            return true;
        }

    } 



    public static class ArrayHelpers
    {
        const string hexChars = "0123456789ABCDEF";

        public static byte[] SkipAndTake(this byte[] array, int skip, int take)
        {
            byte[] result = new byte[take];
            Array.Copy(array, skip, result, 0, take);
            return result;
        }

        public static bool Compare(this byte[] array1, params byte[] array2)
        {
            int len1 = array1.Length;
            if (len1 != array2.Length)
            {
                return false;
            }
            if (len1 == 0)
            {
                return true;
            }
            if (len1 > 256)
            {
                for (int i = 0; i < len1; i++)
                {
                    if (array1[i] != array2[i])
                    {
                        return false;
                    }
                }
            }
            else
            {
                for (byte i = 0; i < len1; i++)
                {
                    if (array1[i] != array2[i])
                    {
                        return false;
                    }
                }
            }
            return true;
        }

        public static String ToHex(this byte b)
        {
            return hexChars[b >> 4].ToString() + hexChars[b & 0x0F].ToString();
        }

        public static String ToHex(this byte[] data)
        {
            String s = "";
            foreach (byte b in data)
            {
                s += b.ToHex();
            }
            return s;
        }

        public static String ToHex(this byte[] data, String spacer)
        {
            String s = "";
            foreach (byte b in data)
            {
                if (s.Length > 0)
                {
                    s += spacer;
                }
                s += b.ToHex();
            }
            return s;
        }

        public static String ToHex(this byte[] data, Char spacer)
        {
            String s = "";
            foreach (byte b in data)
            {
                if (s.Length > 0)
                {
                    s += spacer;
                }
                s += b.ToHex();
            }
            return s;
        }
    }



}



Smartcardhome.htm


<!DOCTYPE HTML PUBLIC "-//W3C/DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>CompuWeigh Corporation</title>
<meta name="keywords" content="Kiosk, SmartCard, Dispenser" />
<style type="text/css">
</style>
<link rel="stylesheet" type="text/css" href="smartcard.css"/>
</head>

<body>
<div id="masthead">
<h2 class="pagetitle">SmartCard Kiosk Configuration</h2>
</div>

<!-- <div id="topnav">
<a href="index.htm">Index</a>  
<a href="tips.htm">Tips</a> 
<a href="problems.htm">Problems</a> 
<a href="products.htm">Products</a> 
</div> -->

<div id="main">
<form method="post" enctype="application/x-www-form-urlencoded" action="smartcardhome">
<table>
   <colgroup align="right" valign="top" width="200px"/> 
   <tr><td>&nbsp;</td></tr>
   <tr>
      <td>MacAddress:</td>
      <td><input type="text" name="MacAddress" size="20" maxlength="12" value="|" /></td>
   </tr>
   <tr>
      <td>IP address:</td>
      <td><input type="text" name="IPAddress" size="20" value="|"  maxlength="15" /></td>
   </tr>
   <tr>
      <td>Subnet Mask:</td>
      <td><input type="text" name="SubnetMask" size="20" value="|" maxlength="15" /></td>
   </tr>
   <tr>
      <td>Gateway Address:</td>
      <td><input type="text" name="GatewayAddress" size="20" value="|" maxlength="15" /></td>
   </tr>
   <tr>
      <td>DeviceHive IP Address:</td>
      <td><input type="text" name="HiveIPAddress" size="20" value="|" maxlength="15" /></td>
   </tr>
   <tr><td>&nbsp;</td></tr>
   <tr>
      <td>Model Number:</td>
      <td><input type="text" name="ModelNumber" size="48" value="|" maxlength="30" /></td>
   </tr>
      <tr>
      <td>Serial Number:</td>
      <td><input type="text" name="SerialNumber" size="48" value="|" maxlength="30" /></td>
   </tr>
   <tr>
      <td>Device Hive ID:</td>
      <td><input type="text" name="DeviceHiveID" size="48" value="|" maxlength="36" /></td>
   </tr>
   <tr><td>&nbsp;</td></tr>
   <tr>
      <td></td>
      <td><input type="submit" value="Submit" />&nbsp;</td>
   </tr>
</table>
</form>
</div>
</body>
</html>


smartcard.css



body {font-family: "Verdana", "Arial", "Helvetica", sans-serif}
hr {color: green; background-color: green; height: 3px; clear: left}
h1 {font-size: 26px}
h2 {font-size: 20px}

a:link {color: green}
a:visited {color: green}
a:hover {color:  Red}

.pagetitle {font-size: 30px; margin: 0}
.tagline {margin: 2px}
.logo {float: left; margin: 5px; border: none; height: 45px}

table {border-style: none}
td {border-style: none; font-size: 13px;}
dl, p, li {font-size: 13px}
dt {font-weight: bold}

 #masthead {background-color:Yellow; clear: left}
 #topnav {padding-top: 15px;}
 #bottomnav {background-color:Yellow; clear: left}
 #copy {clear: left}




#4

I was unable to reproduce the issue. Can you take a look at https://www.ghielectronics.com/docs/122/gadgeteer-driver-modification but with the Gadgeteer source at http://gadgeteer.codeplex.com/ instead and see if the data being received from the socket contains the 0’s or it is some sort of bug that inserts the 0’s?


#5

So for your test, responder.Body.Text is never null when you press the submit button on the web page? Are you using the ENC28 module for Ethernet?

Please give me more details on what I should do. Should I download the source code for the WebServer dll? I am using C:\Program Files (x86)\Microsoft .NET Gadgeteer\Core\Assemblies.NET Micro Framework 4.2\Gadgeteer.WebServer.dll
Or should I download the source code for the ENC28 Ethernet module? Please give me a web link for the download you want me to get.


#6

I was using the ENC28 and the Cobra. responded.Body.Text was never null and I pressed it nearly 100 times.

On the http://gadgeteer.codeplex.com/SourceControl/latest page, download the Gadgeteer source using the Download button near the upper right of the page. Add the WebServer42.csproj project under Main/GadgeteerCore/Libraries/Core/WebServer42 to your solution and add a reference to it instead of Gadgeteer.WebServer.dll. The document at https://www.ghielectronics.com/docs/122/gadgeteer-driver-modification can help you with the details. You are replacing a Gadgeteer DLL instead of a module driver though. Now that you have the source for that DLL, you can step through it and debug like you would your own code to try and narrow down the cause. When I looked in the code, responded.Body.Text was null because encoding the leading null bytes in RawContent cause it to terminate. So we need to find out why RawContent has null bytes at the start.


#7

I found the cause of the problem: In the WebServer42 project, WebServerManager.cs, in the function ProcessRequest(), there are these two lines of code:


 // receiving data, add to an array to process later 
    buffer = new byte[clientSocket.Available];
    clientSocket.Receive(buffer);

frequently, clientSocket.Available reports the total number of bytes in the header plus body section, but the body part of the POST message in buffer contains all zeros whose length equals the body content. Possibly caused by a router problem, or a bug in the Socket class. I am not going to try to fix the Socket class. I found a fix for this by making a change to the function FindHeaderSection() in the file Responder.cs of the WebServer42 project: toward the end, I changed this line of code:


      receivedList.Add(tempContent);

to this:


if ((tempContent != null) && (tempContent.Length > 0) && (tempContent[0] != 0))
{
      receivedList.Add(tempContent);
}

Now the receivedList will not get an array of all zeros added to it. The clientSocket.Receive() function will be called again on a second pass and then the program will receive the remainder of the body content, and then responder.Body.Text will not be null and responder.Body.RawContent will contain the proper body text without the first part being full of many zeros.