Laurent Ellerbach

Ce blog est principalement destiné à publier des informations relatives à Microsoft, à ses technologies, aux outils Visual Studio et à ses versions Express notamment Visual Basic

December, 2011

  • Laurent Ellerbach

    ASP.NET and .NET Microframework HTTP web server together (part 2/2)

    • 0 Comments

    In my previous post, I’ve explained how create a HTTP web server on a .NET Microframework Netduino board with no OS like Windows or Linux. And how to consume a kind of web service from this device from an ASP.NET application. The idea was to get setup data from the Netduino. Those data are a list of lights placed in my Lego city. And the ASP.NET application will allow to display the lights on a map and allow the user to click on a light. When clicking, the application will call the Netduino which will do the work of turning on or off the led. And that’s this part we will explain in this post.

    The function ProcessSwitch on the Netduino board is called when a URL like http://ipaddressnetduino/switch.aspx?id=0;lg=true is called. See previous post for more details on this function.

    Now the idea is to consume this in an ASP.NET page. First, we have to get the LegoLight object from the application storage. And that’s what we are doing in the first line of code of the Page_Load function. We will later detail the rest of the code.

    public partial class _Default : System.Web.UI.Page
    {
    
        public System.Collections.ArrayList myLegoLight;
        public ParamPage MyParamPage = new ParamPage();
    
        protected void Page_Load(object sender, EventArgs e)
        {
            myLegoLight = (System.Collections.ArrayList)Application.Get("LegoLight");
            int myID = -1;
            bool myLight = false;
            if (Request.Params.Count > 0)
            {
                //Is our paramater present?
                foreach(string mystr in Request.Params.AllKeys)
                {
                    if (mystr == MyParamPage.id)
                    {
                        myID = Convert.ToInt32(Request.Params.Get(MyParamPage.id));
                    }
                    if (mystr == MyParamPage.lg)
                    {
                        myLight = Convert.ToBoolean(Request.Params.Get(MyParamPage.lg));
                    }
                }
                if ((myID >= 0) && (myID < myLegoLight.Count))
                { 
                    ((LegoLight)myLegoLight[myID]).Light = myLight;
                }
            }
           
        }
    }

    There is also some code needed to display the lights on an image. I have done this code directly in the page.

    <%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
        CodeBehind="Default.aspx.cs" Inherits="LegoCityWeb._Default" %>
    
    <asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
    </asp:Content>
    
    <asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
    
    <script src="/Scripts/position.js" type="text/javascript"></script>
    
        <p>
      Click the lamp to switch on or off
        </p>
    <%
        int i = 0;
        string strResp = "";
        for (i=0; i<myLegoLight.Count; i++)
        {
            LegoCityWeb.LegoLight mLegoLight;
            mLegoLight = (LegoCityWeb.LegoLight)myLegoLight[i];
            strResp += "<span style='position:absolute;margin-left:" 
    + mLegoLight.PosX + "px; margin-top:" + mLegoLight.PosY
    + "px;width:26px;height:45px; top:findTop(document.all.MyImage);
    left:findLeft(document.all.MyImage);'>"
    ; strResp += "<a href='/" + MyParamPage.pageDefault
    + MyParamPage.ParamStart + MyParamPage.id + MyParamPage.ParamEqual
    + i + MyParamPage.ParamSeparator + MyParamPage.lg + MyParamPage.ParamEqual
    + !mLegoLight.Light + "'>"; if (mLegoLight.Light) strResp += "<img alt='" + mLegoLight.Name
    + "' border=0 width=26 height=45 src='/lampon.png'>"; else strResp += "<img alt='" + mLegoLight.Name
    + "' border=0 width=26 height=45 src='/lampoff.png'>"; strResp += "</a></span>"; Response.Write(strResp); strResp = ""; } %> <img alt="" id="MyImage" src="/ville.jpg" /> </asp:Content>

    The first part of the code is the default code created by the template. It allow to have a nice menu, the logon part. Real code starts with the script section:

    <script src="/Scripts/position.js" type="text/javascript"></script>
    

    This script is the one I’ve developed and explain in this post to display an overlay image on an image with coordinates. There are 2 functions findLeft and findTop which returns the absolute positioning of an object from the left and top part of the page. This allow to overlay images on a page using span tags with a real positioning. Again, all this explain in the previous post.

    the for loop will go thru each LegoLight object. Each object has a position on the picture in pixel. The following code is creating the necessary code to position the picture:

    strResp += "<span style='position:absolute;margin-left:" 
    + mLegoLight.PosX + "px; margin-top:" + mLegoLight.PosY
    + "px;width:26px;height:45px; top:findTop(document.all.MyImage);
    left:findLeft(document.all.MyImage);'>"
    ;

    The next line create a link which look like http://nameoftheserver/default.aspx?id=0&lg=true. So the main page will take params. those params allow to command the lights. That’s the second part of the code from the Page_Load function. And I’ll explain it just after.

    The rest of the client page display either an image of a light on or off depending of the status.

            if (mLegoLight.Light)
                strResp += "<img alt='" + mLegoLight.Name 
    + "' border=0 width=26 height=45 src='/lampon.png'>"; else strResp += "<img alt='" + mLegoLight.Name
    + "' border=0 width=26 height=45 src='/lampoff.png'>"; strResp += "</a></span>"; Response.Write(strResp); strResp = ""; } %> <img alt="" id="MyImage" src="/ville.jpg" />

    And finally add the main image on which all light objects will be displayed by overlay.

    So back to the page load code, when the main page is called, it can contains parameters. they are “id” and “lg”. The “id” one represents the id of a LegoLight object and the “lg” one the status of the light. Which can be on (true) or off (false).

    In order to get those params, I have done the following code:

    int myID = -1;
    bool myLight = false;
    if (Request.Params.Count > 0)
    {
        //Is our paramater present?
        foreach(string mystr in Request.Params.AllKeys)
        {
            if (mystr == MyParamPage.id)
            {
                myID = Convert.ToInt32(Request.Params.Get(MyParamPage.id));
            }
            if (mystr == MyParamPage.lg)
            {
                myLight = Convert.ToBoolean(Request.Params.Get(MyParamPage.lg));
            }
        }
        if ((myID >= 0) && (myID < myLegoLight.Count))
        { 
            ((LegoLight)myLegoLight[myID]).Light = myLight;
        }

    The Request object contains a class called Params. This class includes all parameters that are in the URL (thru a GET call) and/or thru a POST and in what the browser tells on you (your language, your OS, your IP, etc). So a nice foreach can go thru all this up to find the “id” one. And convert it to a real number as all params are just strings. And it will also find the “lg” one and concerts it to a bool.

    And if the ID is a valid number, it will switch on or off the light. If no value is present, the default value will apply and it will switch off the light. When calling the Light property of the LegoLight object, remember from my last post that it is calling the Netduino hardware thru a web page to actually physically switch the physical light on and off.

    Sol here is the end of the second part. To summarize, in those 2 articles, you’ve seen how to call a web page including parameters from a .Net Microframework Netduino board, getting parameters from this same board, displaying overlay images on it, and many things like that Sourire I hope you’ve enjoy it!

  • Laurent Ellerbach

    ASP.NET and .NET Microframework HTTP web server together (part 1/2)

    • 1 Comments

    I will show in this post how to call a web page from a .NET Microframework board which has implemented a HTTP Web Server and get results from it. The idea is to do a mix of previous posts. You are more and more to follow this blog so you may now be familiar with my implementation of a Web Server on a Netduino board. If not, read first the article which explain how to create such a web server on a board with no OS like Windows or Linux. And also how to create a dynamic management page like ASP.NET or Php or Java.

    When you’ll have read it, you’ll need also to read how to read a setup file in .NET Microframework. This is used to setup the board which will pilot led to light up my Lego city.

    Once you’ve done that, you’ll also need to read the post on how to display overlay images in HTML using Javascript. Yes, I know lots or reading before starting but I don’t want to go again thru all the code. I will only focus on the “new” parts.

    First let start with 2 web pages on the Netduino board. The first one allow to switch on and off one led. The code of the function looks like:

    private static void ProcessSwitch(HttpListenerContext context)
    {
        HttpListenerRequest request = context.Request;
        HttpListenerResponse response = context.Response;
        // decode params
        string strParam = request.RawUrl;
        ParamPage MyParamPage = new ParamPage();
        bool bLight = false;
        int iID = -1;
        Param[] Params = decryptParam(strParam);
        if (Params != null)
            for (int i = 0; i < Params.Length; i++)
            {
                //find both params
                int j = Params[i].Name.ToLower().IndexOf(MyParamPage.id);
                if (j == 0)
                {
                    Convert.ToInt(Params[i].Value, out iID);
                }
                j = Params[i].Name.ToLower().IndexOf(MyParamPage.lg);
                if (j == 0)
                {
                    Convert.ToBool(Params[i].Value, out bLight);
                }
            }
        // if the ID value is valid, just light up the light :-)
        string strResp = strOK;
        if ((iID != -1) && (iID < myLegoLight.Count))
        {
            ((LegoLight)myLegoLight[iID]).Light = bLight;
        }
        else
        {
            strResp = strProblem;
        }
        
        strResp = OutPutStream(response, strResp);
    }

    In previous posts, I’ve explained how to handle parameters from a web query and transform them into real value. That’s what the first part of the code is doing.

    Please note that strOK = “OK” and strProblem = “Problem”. We will need this later on on the ASP.NET side.

    if ((iID != -1) && (iID < myLegoLight.Count))
    {
        ((LegoLight)myLegoLight[iID]).Light = bLight;
    }
    else
    {
        strResp = strProblem;
    }

    Those lines just validate that the ID of the light is in the range of ID. If yes, the OK status will be send out, if no, that the problem which will be sent out. The LegoLight structure contains information on the led, a name and coordinates on a picture. All that is explained in the previous post as a pre reading Sourire

    private static void ProcessLights(HttpListenerContext context)
    {
        HttpListenerRequest request = context.Request;
        HttpListenerResponse response = context.Response;
        string strResp = "";
        LegoLight mLegoLight;
        ParamPage MyParamPage = new ParamPage();
        for (int i = 0; i < myLegoLight.Count; i++)
        {
            mLegoLight = (LegoLight)myLegoLight[i];
            strResp += mLegoLight.Name + ParamSeparator;
            strResp += mLegoLight.ID.ToString() + ParamSeparator;
            strResp += mLegoLight.Light.ToString() + ParamSeparator;
            strResp += mLegoLight.Network.ToString() + ParamSeparator;
            strResp += mLegoLight.PosX.ToString() + ParamSeparator;
            strResp += mLegoLight.PosY.ToString() + strEndFile;
            strResp = OutPutStream(response, strResp);
        }
    }

    The second function is also very simple, it does just “serialize” in the “old” way all the LegoLights objects and send them thru the output which is the web page. ParamSeparator = “&” and strEndFile = “\r”. So similar to what I’ve already explain in the post on how to read (and write) a setup file.

    Of course, when you do code on a very reach and fast platform, you can serialize those object in a nice way with XML and create the schema and all what is needed to look good, nice and reading by a human. Reality is I’m using an embedded platform where resources are expensive, almost no memory is available and it runs very slowly. Just think it’s a PC from the early 1980… And you’ll be close to the reality of what the Netduino can do.

    The output looks like: mairie&0&False&1&158&59 station&1&True&1&208&300 train&2&False&1&10&10 rue&3&False&1&700&550

    It does contain a “serialized” view of the LegoLight array. Now, the question is how to consume this? Answer is: thru an ASP.NET application Sourire

    So let’s go for the code to consume this. First step is to create an ASP.NET  application. I’ve used a simple default template which contains the code to create and manage users, a default page and an about page. So all what is needed to start. First step is to create the LegoLight object.

    public class LegoLight
     {
         private string myName = "";
         private int myPosX = 0;
         private int myPosY = 0;
         private byte myNetwork = 0;
         private bool myLight = false;
         private int myID;
    
         public int ID
         {
             get { return myID; }
             set { myID = value; }
         }
    
         public string Name
         {
             get { return myName; }
             set { myName = value; }
         }
         public int PosX
         {
             get { return myPosX; }
             set { myPosX = value; }
         }
         public int PosY
         {
             get { return myPosY; }
             set { myPosY = value; }
         }
         public byte Network
         {
             get { return myNetwork; }
             set { myNetwork = value; }
         }
         public bool Light
         {
             get { return myLight; }
             set { 
                 // do call the Netduino here :-)
                 // and change the status
    
                 //Create a web client object
                 string strUri = LegoCityWeb.Properties.Settings.Default.NetduinoURL;
                 ParamPage MyParamPage = new ParamPage();
                 strUri += MyParamPage.ParamStart + LegoCityWeb.Properties.Settings.Default.NetduinoID + MyParamPage.ParamEqual + myID;
                 strUri += MyParamPage.ParamSeparator + LegoCityWeb.Properties.Settings.Default.NetduinoLight + MyParamPage.ParamEqual + value;
                 //URL will look like http://ipaddressnetduino/switch.aspx?id=0;lg=true
                 Uri MyUri = new Uri(strUri);
                 string myResponse = GetStringFromURL(MyUri);
                 if (myResponse == LegoCityWeb.Properties.Settings.Default.NetduinoOK)
                     myLight = value;
              }
    
         }
         public string GetStringFromURL(Uri mUri)
         {
             WebClient instanceHTTP = new WebClient();
             const int MAX_BUFFER = 1024;
             string myResponse ="";
             Stream returnValue;     
             try
             {
                 //call the specific URI
                 returnValue = instanceHTTP.OpenRead(mUri);
                 // read the stream. This stream can't be seek, so get every byte "manually"
                 byte[] mybuff = new byte[MAX_BUFFER];
                 int i = 0;
                 int ret = -1;
                 do
                 {
                     ret = returnValue.ReadByte();
                     //if there is nothing to read return -1. Values goes from 0 to 255
                     if (ret > 0)
                     {
                         mybuff[i] = (byte)ret;
                     }
                     else
                     {
                         mybuff[i] = 0;
                     }
                     i++;
                 } while ((ret != -1) && (i < MAX_BUFFER));        
                 //returnValue.Read(mybuff, 0, (int)returnValue.Length);
                 myResponse = System.Text.Encoding.ASCII.GetString(mybuff, 0, i-1);
                 returnValue.Dispose();
             }
             catch(Exception ex)
             {                    
                 return myResponse;                       
             }
             //close the stream
             
             return myResponse;
         }
    
     }

    Nothing really complicated here, you’ll find very basic properties to get and set the ID, the name, the network, the position. Where it gets a bit more complicated it’s for the Light property. Well, remember that when you set the property to false, the idea is to switch off the light and when on true, to switch it to on. The idea is to call the first web method we’ve just write on the Netduino board. Remember, the URL to call looks like http://ipaddressnetduino/switch.aspx?id=0;lg=true

    In the code, I’m using application setting for the URL (NetduinoURL), the name of the paramaters (both for the ID NetduinoID and light status NetduinoLight). And I build the URL with the ID of the LegoLight object and the status of the light (so True or False, will also work with 1 and 0). When it’s done, I call a function called GetStringURL. This function has the only purpose to call the URI and return as a string the result. I’ll explain the function later on. In our case, back to the beginning of the article, this function will return “OK” if everything is correct of “Problem” if not. So I just test if it’s OK or not. And set the new light status if everything works fine.

    So now, let have a look at the GetStringURL function. It does take a URI as an argument and return a string.

    WebClient instanceHTTP = new WebClient();
    const int MAX_BUFFER = 2048;
    string myResponse ="";
    Stream returnValue;     
    First step is to create the variables we will need. We will call a web page, so we need to create a WebClient object. the MAX_BUFFER constant will be used to create a buffer that will contain what is returned by the Netduino. I have limited it to 2048 as it’s the maximum number of characters that will be send. On the Netduino, the original setup file will not exceed 1024 characters. But on the response stream, it will contains the ID and the light status as True and False rather than in text. So it will be a bit longer but there is no chance that the returned page will be larger than 2048.

    the myResponse will be used to put the response text and return it. And the stream object to get the stream from the WebClient object call.

    try
    {
        //call the specific URI
        returnValue = instanceHTTP.OpenRead(mUri);
        // read the stream. This stream can't be seek, so get every byte "manually"
        byte[] mybuff = new byte[MAX_BUFFER];
        int i = 0;
        int ret = -1;
        do
        {
            ret = returnValue.ReadByte();
            //if there is nothing to read return -1. Values goes from 0 to 255
            if (ret > 0)
            {
                mybuff[i] = (byte)ret;
            }
            else
            {
                mybuff[i] = 0;
            }
            i++;
        } while ((ret != -1) && (i < MAX_BUFFER));        

    The next part of the code open the URI and place the result in the stream returnValue. It’s a synchronous call but it will be quick as the Netduino will only return text. So no need here to do an asynchronous call which will be necessary if you have large amount of data to read.

    Now, the specificity with the stream we just get is that it is not seekable. So the only way I found to get the data is to pull every single char after the other. The function ReadByte allow this kind of read and return a byte (so a value between 0 and 255). It return –1 in case of problem. The “do while” loop if here to read the entire buffer. And of course, when you start manipulating stream, you better have to use a try catch section.

    So either when the buffer is full or when you’ve reach the end of the stream, the mybuff byte array will contain all the stream. Next step is to convert if to a string.

    myResponse = System.Text.Encoding.ASCII.GetString(mybuff, 0, i-1);

    That’s what this function is doing for you. In the same class, you find also a function to convert from string to a char array and more. And the conversion will be done only for the right amount of read data.

    So here it is for the LegoLigh object. A bit different that the one on the Netduino but only for the Light part. Which on the Netduino call hardware function to actually light up leds.

    Now it still does not answer the question on how to consume the “serialized” LegoLight array returned by the Netduino. For this, we will need also to read a stream and convert it to a string and “deserialize” the string to rehydrate the objects. The best place to do that is when the web application starts. It suppose that the Netduino is already started. If not, it’s just about adding a reinitialisation fonction which will basically call again the same code. It may be needed after a cold Netduino boot. It can also be checked by the main ASP.NET application on a regular basis like every day, week or hour. We’re not there for the moment.

    void Application_Start(object sender, EventArgs e)
    {
        // Code that runs on application startup
        LegoLight mLegoLight = new LegoLight();
        string strUri = LegoCityWeb.Properties.Settings.Default.NetduinoURLLight;
        ParamPage MyParamPage = new ParamPage();
        //URL will look like http://ipaddressnetduino/lights.aspx
        Uri MyUri = new Uri(strUri);
        string mySetupString = mLegoLight.GetStringFromURL(MyUri);
        int i = mySetupString.IndexOf(MyParamPage.EndFile);
        string mySubstring = "";
        string[] myParam;
        int j = 0;
        int inc = 0;
        try
        {
            char[] mSeparator = MyParamPage.ParamSeparator.ToCharArray();
            while ((i < mySetupString.Length) && (i != -1))
            {
                //split the substring in 3
                mySubstring = mySetupString.Substring(j, i - j);
                myParam = mySubstring.Split(mSeparator);
                mLegoLight = new LegoLight();
                mLegoLight.Name = myParam[0];
                int myint = 0;
                myint = Convert.ToInt32(myParam[1]);
                mLegoLight.ID = myint;
                mLegoLight.Light = Convert.ToBoolean(myParam[2]);
                //Convert.ToInt(myParam[1], out myint);
                myint = Convert.ToInt32(myParam[3]);
                mLegoLight.Network = (byte)myint;
                myint = Convert.ToInt32(myParam[4]);
                //Convert.ToInt(myParam[2], out myint);
                mLegoLight.PosX = myint;
                myint = Convert.ToInt32(myParam[5]);
                //Convert.ToInt(myParam[3], out myint);
                mLegoLight.PosY = myint;
                myLegoLight.Add(mLegoLight);
    
                //next string
                j = i + 1;
                if (j < mySetupString.Length)
                    i = mySetupString.IndexOf(MyParamPage.EndFile, j);
                else
                    i = -1;
                inc++;
            }
            Application.Add("LegoLight", myLegoLight);
        }
        catch
        { 
        
        }
    }

    The code will seat in the Application Start function. This is the first method called when the ASP.NET application starts. So the perfect moment to add those kind of initialization.

    Same as for the LegoLight object for the Light method, it starts with the creation of a URI and the call of the specific page which will return the serialized object. The deserialization is not too complex, it’s about splitting the string. First by finding the “\r” character and then the separators “&”. It’s quite artisanal but it’s perfectly working. Then a simple conversion for int and bool allow to populate the LegoLight object and add it to the Array. And finally, this array is stored into the Application storage to be used later.

    And that’s it for the first part of this article. In the second part, we will see how to call the method to change the light and display this in a nice and sweet ASP.NET page. As always, I’m coding in planes and also write articles in planes with no Internet connection. I don’t know why but I enjoy coding in planes with no way to find better code than the one I write. I’m just a marketing director writing code Sourire. And as always, feedback welcome. Thanks for one I already received, it motivates me to continue. And thanks also for being more and more to read this blog.

  • Laurent Ellerbach

    Creating dynamically a web page using .NET Micro framework

    • 0 Comments

    In a previous post, I’ve explain how to read a file using .NET Microframework, how to create a setup file and load it (and write it also), how to implement a web server using HTTP and managing dynamically web pages and parameters. This post will explain how to generate dynamically a page using files and code. So more or less the same idea but using all components this time.

    And the project is about lighting my Lego city. The idea is to be able to click on an image and a led will switch on or off in the Lego city. I’ll show in this post how to generate dynamically using files and code the page containing the overlay images from this post.

    HttpListenerRequest request = context.Request;
    HttpListenerResponse response = context.Response;
    // decode params
    string strParam = request.RawUrl;
    ParamPage MyParamPage = new ParamPage();
    bool bLight = false;
    int iID= -1;
    Param[] Params = decryptParam(strParam);
    if (Params != null)
        for (int i = 0; i < Params.Length; i++)
        {
            //on cherche le paramètre strMonth
            int j = Params[i].Name.ToLower().IndexOf(MyParamPage.id);
            if (j == 0)
            {
                Convert.ToInt(Params[i].Value, out iID);
            }
            j = Params[i].Name.ToLower().IndexOf(MyParamPage.lg);
            if (j == 0)
            {
                Convert.ToBool(Params[i].Value, out bLight);
            }
        }

    This first part of the code is very similar to what I’ve explained in this post. The page parameters are analyzed, they are converted into real values. Here, each light has an id and a status. They can be on or off. Again, more information in some of my previous posts here.

    // if the ID value is valid, just light up the light :-)
    if ((iID != -1) && (iID < myLegoLight.Count))
    {
        ((LegoLight)myLegoLight[iID]).Light = bLight;
    }

    As it’s a web page and anyone can access it, there are a minimum of integrity to do Sourire I just check if the id is in the limit and load the object. More information on the LegoLight class here.

    string strResp = "<HTML><BODY>netduino Lego City<p>";
    
    // Print requested verb, URL and version.. Adds information from the request.
    strResp += "HTTP Method: " + request.HttpMethod + "<br> Requested URL: \"" + request.RawUrl +
        "<br> HTTP Version: " + request.ProtocolVersion + "\"<p>";
    strResp = OutPutStream(response, strResp);
    //send first part of the HTML File
    SendFile(response, strDefaultDir + "\\page1.ht");

    I create a string with the first part of the HTML page and for debug purpose, I add couple of information and send the string to the response object. Again, everything is explained there.

    The SendFile function is the one described in the post explaining how to read a file. Details here. strDefaultDir contains the directory where the file page1.ht is located. In the emulator it’s WINFS and in the netduino it’s SD. I change it “manually” depending on the environment I’m in. No real need to write code for this. Remember we are running an embedded application, no one will change it!! So things like this one can be written in the marble Sourire

    Page1.ht contains the following:

    <script langague="Javascript">
      // You don't need to worry about this
      function findTop(iobj) { ttop = 0; while (iobj) 
    { ttop += iobj.offsetTop; iobj = iobj.offsetParent; } return ttop; } function findLeft(iobj) { tleft = 0; while (iobj)
    { tleft += iobj.offsetLeft; iobj = iobj.offsetParent; } return tleft; } //This is all you need: //findTop(doucment.all.MyImage); </script> <p> Click the lamp to switch on or off </p>

    As expected, it’s just HTML code Sourire and if you want to understand what is the javascript in the page doing, read this post. By the way, I don’t like javascript, I truly prefer C/C++, C#, VB or even real Java (I say I prefer Java over javascript but it’s far far away from the 3 others Sourire).

    //build array of Span
    LegoLight mLegoLight;
    for (int i = 0; i < myLegoLight.Count; i++)
    {
        mLegoLight = (LegoLight)myLegoLight[i];
        strResp += "<span style='position:absolute;margin-left:" + mLegoLight.PosX +
    "px; margin-top:" + mLegoLight.PosY + "px;width:26px;height:45px;
    top:findTop(document.all.MyImage); left:findLeft(document.all.MyImage);'>"
    ; strResp += "<a href='/" + MyParamPage.pageDefault + ParamStart+ MyParamPage.id +
    ParamEqual + i + ParamSeparator + MyParamPage.lg + ParamEqual + !mLegoLight.Light + "'>"; strResp = OutPutStream(response, strResp); if (mLegoLight.Light) SendFile(response, strDefaultDir + "\\imgon.ht"); else SendFile(response, strDefaultDir + "\\imgoff.ht"); strResp += "</a></span>"; strResp = OutPutStream(response, strResp); }

    The next part of the code displays as a span over the main image all LegoLight object and depending if the state of the light is on or off send a different file. in one case it’s imgon.ht and in the other imgoff.ht. Both code are very similar:

    <img border=0 width=26 height=45 src="/WINFS/lampon.png">
    <img border=0 width=26 height=45 src="/WINFS/lampoff.png">

    Of course the /WINFS here reference the emulator path. In the reality it will be /SD as content will be in an SD card in the real word.

    And to finish, couple of lines:

    //send rest of the file
    SendFile(response, strDefaultDir + "\\page2.ht");
    
    strResp += "</BODY></HTML>";
    strResp = OutPutStream(response, strResp);

    They basically send the rest of the page. page2.ht just contains the image:

    <img alt="" src="/WINFS/ville.jpg" /></p>
    

    Again, here I’m using the emulator. In order to make it work, /WINFS need to be change to /SD to work on the Netduino.

    And you are done, here is a simple example that mix file and dynamic generated code to produce a web page in .NET Microframework Sourire Enjoy the beauty of the code Sourire

Page 1 of 1 (3 items)