OpenLightGroup Blog

rss

Blogs from OpenLightGroup.net


How Does A LightSwitch HTML Client Application Work?

image

After using the Visual Studio LightSwitch HTML Client, you may wonder, how does it work? How does it turn the program we designed into an actual web application?…

image

After using the Visual Studio LightSwitch HTML Client, you may wonder, how does it work? How does it turn the program we designed into an actual web application?

image

We will explore the application created in the tutorial: Online Ordering System (An End-To-End LightSwitch Example).

image

The tool that will be most helpful will be Fiddler, available here: http://fiddler2.com. This program will allow us to monitor the traffic that is transmitted between the web server running the LightSwitch application and our web browser.

image

When we run Fiddler and monitor the web traffic created by the End-To-End application (running at: https://endtoendexample.lightswitchhelpwebsite.com/HTMLClient), we  see that is loads a number of files.

Note: the 404 errors in the image above are due to the sample application not employing any Localization.

image

All of these files are required to display the first page. We will also see that as we use the application, it will transmit only a small amount of information. Primarily, only the data required to display or update the application.

 

The HTML Page

image

Everything starts with the HTML page.

 

image

When we look at the contents of the page, we see that it loads the .css files and .js scripts that the LightSwitch application requires.

The JavaScript library files that it loads are:

  • jquery/ jquery.mobile
    • JavaScript libraries that provide cross browser functionality
  • msls
    • The primary LightSwitch framework library that provides the application functionality
  • winjs
    • A helper library for things such as Promise objects that handle asynchronous calls
  • datajs
    • Used to provide OData communication

 

msls.js and winjs.js

image

The msls.js library is the heart of the LightSwitch framework. There is an enormous amount of functionality in this file. Much of it you can reference in your custom code.

 

image

The best way to explore it, is to open the msls-vsdoc.js file in the Scripts directory and read the comments.

There is a project by Soft Landing, inc that is documenting this library. You can get more information about that project at this link: http://softlandingcanadaforums.com/yaf_postsm49_HTML-Client-API-Discovery-and-Extension-Framework.aspx.

 

GetAuthenticationType

image

During the application start-up process, the msls.js library makes a call to the SecurityData.svc service to determine what the authentication type for the application is. If Forms Authentication is detected, the LightSwitch client will display the logout button.

 

generatedAssets.js / usercode.js

image

The generatedAssets.js file is referenced in the default.htm page.

It contains code that loads other required JavaScript libraries and files.

 

image

The usercode.js file (loaded by the generatedAssets.js file) loads the JavaScript files that contain custom code that we have created.

 

model.json

image

In the LightSwitch Silverlight client, the structure of the application is contained in .lsml files. In the running LightSwitch HTML Client, the structure of the application is contained in the model.json file.

 

image

The model.json file is created each time we build the LightSwitch application.

 

image

The file is in JSON format and describes the entire application. When this is loaded, the application has all the information it needs to run, except for the data.

 

The Screen

image

When we look at a screen in the LightSwitch designer, we see that it consists of Properties, Collections and Commands. This is consistent with the MVVM (Model-View-View Model) structure of the Silverlight Client.

image

When we look at the same screen in the model.json file we see that it defines the structure of the screens.

 

image

The viewModel.js library defines the JavaScript representation of the screens and allows programmatic access to the screens.

 

 

The Data

image

The data.js library contains a representation of all the data assets in the LightSwitch application.

It also contains the location of the .svc services that are used to actually retrieve the data from the server.

 

image

The msls.js library, at this point, has access to all the information needed to obtain the data needed by the application.

In this example, it knows from the model.json library that the first page contains the orders collection. It constructs a query using properties from the data.js library to retrieve the data.

 

Updating Data

 

image

The application is very efficient at this point. It only needs to contact the server to retrieve data and images.

Clicking the save button, when adding a single order detail…

image

… causes only one small request to the server.

image

Inserting, or updating in the application requires only a small data payload.

image

After inserting and updating several records, only the data service calls are needed.

 

Special Thanks

A very special thanks to LightSwitch team member Stephen Provine for his valuable assistance.


Growth on The LightSwitchHelpWebsite.com

image

The best way to measure growth on the LightSwitchHelpWebsite.com is by looking at the number of members who join each month. Currently there are over 6000 members.

As you can see from the chart, growth was declining for years. I attribute this to the uncertainty around Silverlight. In the past, LightSwitch only created Silverlight applications.

This year, the Visual Studio LightSwitch team released the LightSwitch HTML Client.

As you can see from the chart, things have changed dramatically Smile


Understanding The LightSwitch HTML Client

image

The Microsoft Visual Studio LightSwitch team was a bit disappointed when I finally walked through the door. I was late to the invite only meeting where they revealed the beta of the new Visual Studio LightSwitch HTML Client. Yes, as long suspected, Visual Studio LightSwitch, the tool that previously only created Silverlight applications (Silverlight by this time was already facing huge challenges in its adoption because it did not run on any of the popular mobile devices), will now create HTML pages.

My flight from Los Angeles to Seattle was a bit late. I was so late in fact that the group was on their scheduled break. The team rolled back the slides and got me caught up. We get to the part about the HTML Client and I think the first words out of my mouth were, “Wow, that is great!” followed by “What about desktop?”.

The LightSwitch team is too nice to actually slap their palms to their foreheads in front of me and yell “Doh! he doesn’t get it!” but, really they should have. I didn’t get it. They calmly explained that they were “targeting mobile devices” because mobile is growing and creating applications that work well on mobile devices is really important. This may seem obvious now, however this conversation took place years ago.

What Is Different?

I have worked with the LightSwitch HTML Client for a few years now (today is was finally released). What I am only now understanding is that my desire to have it create a desktop HTML application was misguided. It’s like a person who only understands steam engines trying to understand a car (“That’s nice but it is too small to carry enough coal!”).

The main thing I needed to realize, was that if the primary purpose is to create the best HTML applications for the end user, their design is the best way to achieve that… whether you are using a mobile or a desktop HTML web browser.

The articles that you want to read are: A New User Experience (Heinrich Wendel) and: Designing for Multiple Form Factors (Heinrich Wendel).

image

This article shows how a LightSwitch application allows the end user to click on a screen element and quickly display a popup that allows them to view details or edit data. In a desktop application, the end-user will see the screen greyed out behind the popup. This allows the user to easily mentally track where they came from (and where they will return to).

image

If the user is using a tablet or a phone, the application will display only the popup (it will display the previous screen when they close the popup).

Also note that if a user is using a tablet, it will display the entire popup with both its columns, however, if the user is using a phone, it will display only one column at a time. The user will scroll down to get to all the information.

image

This is important, because we can create one application that works on all devices!

Single Page Application (because faster is better)

The Visual Studio LightSwitch HTML Client creates Single Page Applications. This design essentially means that when a end-user arrives at your LightSwitch application, a thin JavaScript framework loads and it communicates with the back-end services using OData.

Most importantly, you don’t have the slow postbacks that while they are merely annoying on a desktop application, make the same application practically unusable on a mobile device (because they move so slow due to being run on less powerful web browsers and slower internet connections). Instead of postbacks, only the data is transferred back and forth when a user views and saves data. The screen is not redrawn each time. This makes for a much faster application.

Desktop Apps Waste Space

image

Let’s look at an example of what I am talking about. I have a popular open source help desk ticket tracking application project called ADefHelpDesk. My plan is to make a new version using the LightSwitch HTML Client. My original thinking was to recreate the existing HTML screens. Now, it can be done, but I no longer believe it is a good idea and that is not what I plan to do.

Looking at the screen above, there are a lot of things on the page that do not need to be there. The reason they are there is that it takes so long for data to be displayed, I want to display as much information as possible. I also want all possible buttons and switches available without the need for the user to click-click-click to get to a needed button to perform a function.

The first thing LightSwitch does is move fast, very fast. Don’t take my word for it, see for yourself with the Live Demo: https://endtoendexample.lightswitchhelpwebsite.com/Client/default.htm (use your username and password from http://LightSwitchHelpWebsite.com).

So, from the beginning I need to remove anything that is not needed. If you want to search, click a button and do a search, otherwise hide all the search controls. When I do that 50% of all the items on the page go away!

image

When editing a help desk ticket, I have screen real estate used for things like the Description, Notes, Estimated Hours, Start and Compete boxes. The LightSwitch HTML Client is designed to allow a person to tap on an item and quickly edit it in a popup. Now I can eliminate the huge input boxes and show the data in much smaller text.

Changing The Look

image

Don’t worry, every LightSwitch application does not have to look like a LightSwitch app. We can use JavaScript plug-ins to create rich user interfaces.

image

LightSwitch also has a built-in Knockout-like JavaScript data binding framework that allows the user interface to update without requiring the end-user to explicitly save the page.

image

You can also use Themeroller to help you create new themes because LightSwitch uses standard .css style sheets.

Purpose Based Applications

An application has a purpose, a task that the end-user needs to accomplish. We want to create applications that allow a user to accomplish that task as fast and as efficiently as possible. The LightSwitch HTML Client creates applications that do that.


Forms Authentication with SignalR Using Web Forms and Windows Forms

image

A Method To Provide Some Security With SignalR

SignalR is a fantastic tool for creating real-time applications. It is not just limited to making chat applications, but we will use a chat application to demonstrate how you can implement Forms Authentication with SignalR.

The reason you would want to use Forms Authentication, is that most websites use Forms Authentication now. Forms Authentication also works with all web browsers and most devices.

SignalR

According to www.ASP.net:

SignalR is an open-source .NET library for building web applications that require live user interaction or real-time data updates. Examples include social applications, multiuser games, business collaboration, and news, weather, or financial update applications. These are often called real-time applications.

You can find more about SignalR at this link: http://signalr.net/.

The Sample Application

image

When we run the LightBulbSignalRService project we see a simple SignalR application that uses Persistent Connections (rather than the Hubs that most examples use).

When the application starts, we are not logged in so our connection GUID shows with a message that we are connected.

image

If we click the Login as TestUser button, we are given a cookie and SignalR detects that we are authenticated.

SignalR also puts us in a group that has the same name as our user name.

image

We can open up another Tab, log in again as TestUser, enter a message and click the broadcast button…

image

When we return to the first Tab, it will see the Group Message because it is in the same group. This is just to demonstrate that you can authenticate a user and keep data in sync across multiple instances,  and as will be demonstrated in the next step, multiple devices.

For example, imagine a user is working with your application on a web page and then wants to pick up from where they left off on their tablet or cell phone (or any other device).

image

Now, we run the LightBulbSignalRClient project and set the connection and click the Connect button.

image

We are now logged in via a Windows Forms Application using Forms Authentication!

The Web Application

image

We will first cover the Web Application (the LightBulbSignalRService project).

The first place we want to start is the web.config file. It is there that we want to turn Forms Authentication on by setting the authentication tag to mode=”Forms”:

xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5" />
    <authentication mode="Forms"/>
  system.web>
configuration>

image

Next, we use NuGet to pull in SignalR.

We create a Global.asax file and add the following code to the Application_Start:

image

This simply indicates that we will have a SignalR Persistent Connection called MyConnection that can be accessed by the end point “echo”.

To implement the MyConnection class, we use the following code in the MyConnection.cs file:

 

using System.Collections.Generic;
using System.Security.Principal;
using System.Threading.Tasks;
using System.Web;
using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Hosting;
public class MyConnection : PersistentConnection
{
    protected override Task OnReceived(IRequest request, string connectionId, string data)
    {
        // Broadcast to all instances of the user 
        // (that user is in a group that matches their user name)
        Groups.Send(getClientDescription(request, connectionId), "Group Message: " + data);
        // Broadcast to all clients
        return Connection.Broadcast("User: " 
            + getClientDescription(request, connectionId) + " Sent: " + data);
    }
    protected override Task OnConnected(IRequest request, string connectionId)
    {
        // Add the user to a group that matches their user name
        // If they are not logged in, their group will be their
        // Connection ID
        Groups.Add(connectionId, getClientDescription(request, connectionId));
        return Connection.Broadcast("User: " 
            + getClientDescription(request, connectionId) + " connected");
    }
    protected override Task OnReconnected(IRequest request, string connectionId)
    {
        // User Reconnected (they come back)
        return Connection.Broadcast("User: " 
            + getClientDescription(request, connectionId) + " re-connected");
    }
    protected override Task OnDisconnected(IRequest request, string connectionId)
    {
        // User Disconnected (they may come back)
        return Connection.Broadcast("User: " 
            + getClientDescription(request, connectionId) + " disconnected");
    }
    // Utility
    private static string getClientDescription(IRequest request, string connectionId)
    {
        // Note: Using HttpContext.Current is a no no with SignalR, 
        // so get the IPrincipal from the SignalR IRequest via IRequest.User
        IPrincipal objIPrincipal = request.User;
        if (objIPrincipal != null)
        {
            // If user is authenticated get user name
            // otherwise use connectionId
            var name = objIPrincipal.Identity.IsAuthenticated
                    ? objIPrincipal.Identity.Name
                    : connectionId;
            return name;
        }
        else
        {
            return connectionId;
        }
    } 
}

image

Next, we create a Default.aspx page.

 

It uses the following markup:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>SignalR Testtitle>
    <script src="Scripts/jquery-1.9.1.min.js" type="text/javascript">script>
    <script src="Scripts/json2.js" type="text/javascript">script>
    <script src="Scripts/jquery.signalR-1.0.0.min.js" type="text/javascript">script>
    <script type="text/javascript">
        $(function () {
            // For IIS deployment use: $.connection('echo');
            var connection = $.connection('/echo');
            // This is fired when a message is received
            connection.received(function (data) {
                $('#messages').append('<li>' + data + 'li>');
            });
            // Start the connection
            connection.start().done(function () {
                $("#broadcast").click(function () {
                    connection.send($('#msg').val());
                });
            });
        });
    script>
head>
<body>
    <form id="form1" runat="server">
        <div>
            <input type="text" id="msg" />
            <input type="button" id="broadcast" value="broadcast" /> 
            <asp:Button ID="btnLoginAsTest" runat="server" 
                OnClick="btnLoginAsTest_Click" Text="Login as TestUser" />
             
            <asp:Button ID="btnLogout" runat="server" 
                OnClick="btnLogout_Click" Text="Logout" />
             <ul id="messages">
            ul>
        div>
    form>
body>
html>

 

And the following code behind:

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace LightBulbSignalRService
{
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
        }
        #region btnLoginAsTest_Click
        protected void btnLoginAsTest_Click(object sender, EventArgs e)
        {
            // *************************
            // Insert user validation here
            // For example, check the username and password in the database
            // *************************
            // Log the user into the site
            FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1,
              "TestUser",
              DateTime.Now,
              DateTime.Now.AddDays(30),
              false,
              "SignalR",
              FormsAuthentication.FormsCookiePath);
            // Encrypt the ticket.
            string encTicket = FormsAuthentication.Encrypt(ticket);
            // Create the cookie.
            Response.Cookies.Add(new HttpCookie(FormsAuthentication.FormsCookieName, encTicket));
        } 
        #endregion
        #region btnLogout_Click
        protected void btnLogout_Click(object sender, EventArgs e)
        {
            FormsAuthentication.SignOut();
        } 
        #endregion
    }
}

 

To authenticate remote users, we create a file CreateCookie.aspx with the following code:

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Security;
namespace ODataSample
{
    public partial class CreateCookie : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            string strUserName = Request.QueryString["UserName"];
            string strPassword = Request.QueryString["Password"];
            // *************************
            // Insert user validation here
            // For example, check the username and password in the database
            // *************************
            // Create cookie and return it
            FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1,
                strUserName,
                DateTime.Now,
                DateTime.Now.AddDays(30),
                false,
                "SignalR",
                FormsAuthentication.FormsCookiePath);
            // Encrypt the ticket.
            string encTicket = FormsAuthentication.Encrypt(ticket);
            // Create the cookie.
            Response.Write(encTicket);
            Response.End();
        }
    }
}

The Windows Forms Client

image

The Windows Forms Client has to have the ASP.NET SignalR Client installed.

image

We use NuGet to pull in the .NET SignalR Client.

We use the following code for the Connect button:

            // Connect to the service
            connection = new Connection(txtSignalRWebsite.Text);
            // Fire connection_Received when message comes in
            connection.Received += connection_Received;
            // Create a Cookie
            Cookie objCookie = new Cookie();
            // Set the values
            objCookie.Domain = txtDomain.Text;
            objCookie.Expires = DateTime.Now.AddMinutes(20);
            objCookie.HttpOnly = false;
            objCookie.Name = ".ASPXAUTH";
            objCookie.Path = @"/";
            objCookie.Secure = false;
            objCookie.Value = GetCookie(); // The Forms Auth Ticket
            // Create a Cookie container and put the Cookie inside
            connection.CookieContainer = new CookieContainer();
            connection.CookieContainer.Add(objCookie);
            // Start the connection
            connection.Start().Wait();

 

The following is the code that connects to the CreateCookie.aspx file and gets the cookie:

 

        private string GetCookie()
        {
            WebClient client = new WebClient();
            // Add a user agent header in case the 
            // requested URI contains a query.
            client.Headers.Add("user-agent", 
                "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)");
            
            string strWebRequest = 
                String.Format("{0}?UserName={1}&Password={2}", 
                txtAuthWebsite.Text, txtUserName.Text, txtPassword.Text);
            Stream data = client.OpenRead(strWebRequest);
            StreamReader reader = new StreamReader(data);
            string strCookie = reader.ReadToEnd();
            data.Close();
            reader.Close();
            return strCookie;
        } 

 

SignalR Authentication

image

This method was created because this is what it appears that one of the SignalR creators, David Fowler indicated was the way it should be handled (http://stackoverflow.com/questions/11488461/forms-authentication-with-signalr).

Download Sample Code

You can download the code from this link:

http://silverlight.adefwebserver.com/Files/SignalrRWindowsFormsAuth.zip


My 8 Year Old Cousin Creates A Computer Game

image

My 8 year old cousin just completed his first Android game today. It is called Pet Brawl. He actually wrote it himself. I have been tutoring him for 1 1/2 hours each month for over a year, but he wrote all the code himself.

image

Originally I started working with him after he had completed a computer camp where they taught him how to use the computer programming application called Scratch. It is a great program and I recommend it highly as an entry level programming language for all ages.

Our sessions would start with a task I would assign him at the end of the previous session. Things like “make the cat pick up four objects in order”. They were designed to be too hard and when we got together I would explain how to solve the problem.

image

Next we moved to App Inventor. Another programming language and application builder created by some of the same people that created Scratch. The nice thing about App Inventor is that you can run the programs you create on your Android device.

image

This time I set an ambitious goal. He would complete an entire program and we would distribute it. Originally he wanted the game to have you to pick a “pet” and then you would “brawl” against the computer.

First we started by learning how to move the character around the screen (I had to figure it out myself and I led the Google session, and after finding an example I would provide guidance and encouragement and he worked it out). I only touched the keyboard less than 2 minutes a session (usually to find the element I wanted him to try next).

As time went on he scaled the game back a bit (he actually wanted to finish it), so the final game just has you trying to survive (don’t let the Phoenix touch you, the Dragon) until the clock runs down.

image

The game is actually quite challenging. He programmed it himself, and he is only eight years old.

image

The picture above is Carter showing his father the game he just created running on his father’s Galaxy Note.

You can download the .apk at the link below. It will run on most any Android device.

Download: PetBrall.apk