Dec
31
Written by:
Michael Washington
12/31/2012 3:01 PM
The LightSwitch HTML Client (currently in preview) brings a new feature called ServerApplicationContext. It is covered in the article: A New API for LightSwitch Server Interaction: The ServerApplicationContext (Joe Binder). In that article MVC is used. Here is an example that uses a ASP.NET Web Form page to create CRUD (Create, Read, Update, and Delete).
The Application
Basic CRUD functionality is demonstrated in the example application. It allows you to create new call records in the form at the bottom, and display them in the grid at the top. You can update and delete the items in the grid.
LightSwitch has many features that allow you to easily implement business rules, security rules, and business types. In this example, the Phone Number business type, is set for the PhoneNumber field in the PhoneCall table in LightSwitch.
Without the need to write a single line of code, the business type is enforced.
Creating the Web Page
The first step is to switch to File View.
Next, we select Add then New Item… in the Web folder of the Server project.
We add a new Web Form page.
We use the the following code in the .aspx file:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="LightSwitchApplication.Web.Default" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>Phone Calls</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<style type="text/css">
.style1
{
font-weight: normal;
}
</style>
<asp:DataList ID="dlPhoneCalls" runat="server" GridLines="Both">
<HeaderTemplate>
</td><td>
<strong>Description</strong> </td>
<td>
<strong>Person Calling</strong>
</td>
<td>
<strong>Phone Number</strong>
</td>
<td>
<strong>Call Type</strong>
</HeaderTemplate>
<ItemTemplate>
<asp:Button ID="btnDelete" runat="server" Text="Delete"
CommandArgument='<%# Eval("Id") %>' OnClick="btnDelete_Click" />
<asp:Button ID="btnUpdate" runat="server" OnClick="btnUpdate_Click"
Text="Update" CommandArgument='<%# Eval("Id") %>' />
</td><td>
<asp:TextBox ID="Description" runat="server" Text='<%# Eval("Description") %>' />
</td>
<td>
<asp:TextBox ID="PersonCalling" runat="server" Text='<%# Eval("PersonCalling") %>' />
</td>
<td>
<asp:TextBox ID="PhoneNumber" runat="server" Text='<%# Eval("PhoneNumber") %>' />
</td>
<td>
<asp:Label ID="lblCallType" runat="server" Text='<%# Eval("CallType") %>' Visible="False" />
<asp:DropDownList ID="ddlGridCallType" runat="server"
OnDataBound="ddlCallType_DataBound">
<asp:ListItem>Sales</asp:ListItem>
<asp:ListItem>Service</asp:ListItem>
<asp:ListItem>Other</asp:ListItem>
</asp:DropDownList>
</ItemTemplate>
</asp:DataList>
<p>
</p>
<h2 class="style1">Insert New:</h2>
<table>
<tr>
<td align="right">
<strong>Description</strong>
</td>
<td>
<asp:TextBox ID="txtDescription" runat="server"></asp:TextBox>
</td>
</tr>
<tr>
<td align="right">
<strong>Person Calling</strong>
</td>
<td>
<asp:TextBox ID="txtPersonCalling" runat="server"></asp:TextBox>
</td>
</tr>
<tr>
<td align="right">
<strong>Phone Number</strong>
</td>
<td>
<asp:TextBox ID="txtPhoneNumber" runat="server"></asp:TextBox>
</td>
</tr>
<tr>
<td align="right">
<strong>Call Type</strong>
</td>
<td>
<asp:DropDownList ID="ddlCallType" runat="server">
<asp:ListItem>Sales</asp:ListItem>
<asp:ListItem>Service</asp:ListItem>
<asp:ListItem>Other</asp:ListItem>
</asp:DropDownList>
</td>
</tr>
<tr>
<td align="right">
</td>
<td align="right">
<asp:Button ID="btnSubmit" runat="server" OnClick="btnSubmit_Click" Text="Submit" />
</td>
</tr>
</table>
<asp:Label ID="lblError" runat="server" EnableViewState="False" ForeColor="Red"></asp:Label>
</div>
</form>
</body>
</html>
Next, we paste the following code in the .aspx.cs file:
using System.Xml.Linq;
using System.IO;
using System.Text;
namespace LightSwitchApplication.Web
{
public partial class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
RefreshGrid();
}
}
}
}
Server Context
The server context is automatically cached in the Current property, we use the following code to only create it when needed:
#region GetServerContext
private static ServerApplicationContext GetServerContext()
{
ServerApplicationContext serverContext =
(LightSwitchApplication.ServerApplicationContext)ServerApplicationContext.Current;
if (serverContext == null)
{
serverContext =
(LightSwitchApplication.ServerApplicationContext)ServerApplicationContext.CreateContext();
}
return serverContext;
}
#endregion
Display Data
To display data, we use the following method:
private void RefreshGrid()
{
// Get all PhoneCalls
using (var serverContext = GetServerContext())
{
var result = from PhoneCalls in serverContext.DataWorkspace.ApplicationData
.PhoneCalls.GetQuery().Execute()
select PhoneCalls;
dlPhoneCalls.DataSource = result;
dlPhoneCalls.DataBind();
}
}
Also, to set the dropdown in each row to the proper value, we use the following code:
protected void ddlCallType_DataBound(object sender, EventArgs e)
{
// Get an instance of the DropDownList
DropDownList objDropDownList = (DropDownList)sender;
// Get the selected value from the hidden Label
Label objLabel = (Label)objDropDownList.Parent.FindControl("lblCallType");
// Set the selected value in the DropDownList
objDropDownList.SelectedValue = objLabel.Text;
}
Insert Data
To insert data, we use the following code:
protected void btnSubmit_Click(object sender, EventArgs e)
{
using (var serverContext = GetServerContext())
{
try
{
// Create a new PhoneCall
var objPhoneCall = serverContext.DataWorkspace.ApplicationData.PhoneCalls.AddNew();
// Set values
objPhoneCall.CallType = ddlCallType.SelectedValue;
objPhoneCall.Description = txtDescription.Text;
objPhoneCall.PersonCalling = txtPersonCalling.Text;
objPhoneCall.PhoneNumber = txtPhoneNumber.Text;
objPhoneCall.MessageTakenBy =
(this.User.Identity.Name != "") ? this.User.Identity.Name : "[unknown]";
// Save changes
serverContext.DataWorkspace.ApplicationData.SaveChanges();
// Refresh the Grid
RefreshGrid();
}
catch (Exception ex)
{
ShowError(ex);
return;
}
}
}
Update Data
To update data, we use the following code:
protected void btnUpdate_Click(object sender, EventArgs e)
{
// Get an instance of the Button
Button UpdateButton = (Button)sender;
// Get the ID of the current record from the CommandArgument
int intID = Convert.ToInt32(UpdateButton.CommandArgument);
using (var serverContext = GetServerContext())
{
try
{
// Get the record
var result = (from PhoneCalls in serverContext.DataWorkspace.ApplicationData
.PhoneCalls.GetQuery().Execute()
where PhoneCalls.Id == intID
select PhoneCalls).FirstOrDefault();
if (result != null)
{
// Get the values
TextBox Description =
(TextBox)UpdateButton.Parent.FindControl("Description");
TextBox PersonCalling =
(TextBox)UpdateButton.Parent.FindControl("PersonCalling");
TextBox PhoneNumber =
(TextBox)UpdateButton.Parent.FindControl("PhoneNumber");
DropDownList ddlGridCallType =
(DropDownList)UpdateButton.Parent.FindControl("ddlGridCallType");
// Update the record
result.Description = Description.Text;
result.PersonCalling = PersonCalling.Text;
result.PhoneNumber = PhoneNumber.Text;
result.CallType = ddlGridCallType.SelectedValue;
// Save changes
serverContext.DataWorkspace.ApplicationData.SaveChanges();
// Refresh the Grid
RefreshGrid();
}
}
catch (Exception ex)
{
ShowError(ex);
return;
}
}
}
Delete Data
To delete data, we use the following method:
protected void btnDelete_Click(object sender, EventArgs e)
{
// Get an instance of the Button
Button DeleteButton = (Button)sender;
// Get the ID of the current record from the CommandArgument
int intID = Convert.ToInt32(DeleteButton.CommandArgument);
using (var serverContext = GetServerContext())
{
try
{
// Get the record
var result = (from PhoneCalls in serverContext.DataWorkspace.ApplicationData
.PhoneCalls.GetQuery().Execute()
where PhoneCalls.Id == intID
select PhoneCalls).FirstOrDefault();
if (result != null)
{
// Delete the record
result.Delete();
// Save changes
serverContext.DataWorkspace.ApplicationData.SaveChanges();
// Refresh the Grid
RefreshGrid();
}
}
catch (Exception ex)
{
ShowError(ex);
return;
}
}
}
Validation Errors
To show validation errors, we use the following method:
private void ShowError(Exception ex)
{
string strError = "";
Microsoft.LightSwitch.ValidationException ValidationErrors = ex as Microsoft.LightSwitch.ValidationException;
if (ValidationErrors != null)
{
StringBuilder sbErrorMessage = new StringBuilder();
foreach (var error in ValidationErrors.ValidationResults)
{
sbErrorMessage.Append(string.Format("<p>{0}</p>", error.Message));
}
strError = sbErrorMessage.ToString();
}
else
{
// This is a simple error -- just show Message
strError = ex.Message;
}
lblError.Text = strError;
}
Display The Web Page
When we run the application, we have to navigate to /web/Default.aspx to see the page.
LightSwitch Help Website Articles
Using Promises In Visual Studio LightSwitch
Retrieving The Current User In The LightSwitch HTML Client
Writing JavaScript That Implements The Binding Pattern In Visual Studio LightSwitch
Implementing The Wijmo Radial Gauge In The LightSwitch HTML Client
Writing JavaScript In LightSwitch HTML Client Preview
Creating JavaScript Using TypeScript in Visual Studio LightSwitch
Theming Your LightSwitch Website Using JQuery ThemeRoller
Using Toastr with Visual Studio LightSwitch HTML Client (Preview)
LightSwitch Team HTML and JavaScript Articles
Enhancing LightSwitch Controls with jQuery Mobile (Michael Zlatkovsky)
Custom Controls and Data Binding in the LightSwitch HTML Client (Joe Binder)
Creating Screens with the LightSwitch HTML Client (Joe Binder)
The LightSwitch HTML Client: An Architectural Overview (Stephen Provine)
Writing JavaScript Code in LightSwitch (Joe Binder)
New LightSwitch HTML Client APIs (Stephen Provine)
A New API for LightSwitch Server Interaction: The ServerApplicationContext
Building a LightSwitch HTML Client: eBay Daily Deals (Andy Kung)
Download Code
The LightSwitch project is available at http://lightswitchhelpwebsite.com/Downloads.aspx
(you must have HTML Client Preview 2 or higher installed to run the code)
10 comment(s) so far...
So, we are using this to recreate what Silverlight used to do perfectly, except now in HTML so that it's cross-browser and phone/tablet capable?
By MyTatuo on
1/1/2013 6:49 AM
|
@MyTatuo - It is just another option to communicate with the LightSwitch application :)
By Michael Washington on
1/1/2013 6:49 AM
|
Thanks for another greater article, Michael!
By Joe Binder on
1/2/2013 9:18 PM
|
@Joe Binder - Thanks Joe, I really appreciate all you have done to help me out.
By Michael Washington on
1/2/2013 9:19 PM
|
Great article, and very timely for me. Thanks for taking your New Year's eve to produce this :)
Question: what tool(s) do you use to create such wonderful tutorials? Thanks.
By dan houck on
1/8/2013 3:46 PM
|
@dan houck - Thanks. I use PicPick for the screen grabs and Windows Live Writer to write the Blogs. Everything is posted on a DotNetNuke website using the standard DotNetNuke Blog Module.
By Michael Washington on
1/8/2013 3:48 PM
|
There is little ‘Server Application Context’ for using DataWorkspace in HTTP handlers, WebForms or other server parts for LS 2010:
http://stackoverflow.com/questions/23864608/lightswitch-2010-server-application-context
By Polach on
5/27/2014 3:44 AM
|
Thanks for the brief demonstrations this is awesome!!!
By christian tua on
6/9/2014 2:44 PM
|
Great information. Since last week, I am gathering details about asp experience. There are some amazing details on your blog which I didn’t know. Thanks.
By Amanda Chua on
8/1/2018 4:34 AM
|
It's very useful for me. I think that I can improve my ability and resolve my problem.Thank you so much
By ux agency on
8/22/2019 8:14 PM
|