Apr 14

Written by: Michael Washington
4/14/2012 5:42 PM  RssIcon

image

Visual Studio LightSwitch (In Visual Studio 11 Beta) allows you to access your LightSwitch application via OData. This provides access to the security and business rules of your LightSwitch application.

In this article we will demonstrate using JQuery, DataJs and KnockoutJs to create a page that will cover Creating, Reading, Updating, and Deleting data (otherwise known as CRUD) in LightSwitch. As described in the article: LightSwitch Architecture: OData (John Rivard), OData allows CRUD using the following HTTP verbs:

Create : POST
Read: GET
Update: PUT
Delete: DELETE

Many may find that communication with LightSwitch is easer when using the server side methods shown in the articles: Calling LightSwitch 2011 OData Using Server Side Code and A Full CRUD LightSwitch JQuery Mobile Application. However, an advantage of using client-side JavaScript is:

  • You do not need to create a service reference
  • You can place the code on a normal .html or .htm page

This disadvantage is that the code does not compile at design-time, and one small typo can cause the page not to work.

The HTML Page In Action

image

When we run the application and navigate to the page, security (if enabled) is enforced.

image

The page will display the Products and the edit and delete buttons to any valid user…

image

But, if a non-administrator tries to insert, edit or delete records, LightSwitch server-side security in the OData feed, will enforce all business rules, and in this case prevent the user from performing the action.

image

Also, LightSwitch returns end-user understandable messages (you will want to parse the entire response to just show the Message tags) for all validation errors.

DataJs and KnockoutJs

image

This sample uses DataJs and KnockoutJs (in addition to JQuery).

Here are some links on DataJs and KnockoutJs:

DataJs – This JavaScript library is used to make the OData calls into LightSwitch. You can find documentation and samples at this link. Their Simple CRUD Sample is used as the basis for this article.

KockoutJs – This JavaScript library is used to display the data from DataJs. It is recommended that you go through these interactive tutorials to understand how it works.

LightSwitch OData Security

The sample consists of a page that allows an administrator to perform CRUD operations on the Product table in the Flower Shop application used in the article: Calling LightSwitch 2011 OData Using Server Side Code .

image

First we need to prevent non-administrators from updating the Products entity (table). We open the Products entity and select the CanUpdate method.

We use the following code:

        partial void FlowerShopProducts_CanUpdate(ref bool result)
        {
            result = this.Application.User.HasPermission(Permissions.SecurityAdministration);
        }

We do the same for the CanDelete  and CanInsert methods:

        partial void FlowerShopProducts_CanDelete(ref bool result)
        {
            result = this.Application.User.HasPermission(Permissions.SecurityAdministration);
        }
        partial void FlowerShopProducts_CanInsert(ref bool result)
        {
            result = this.Application.User.HasPermission(Permissions.SecurityAdministration);
        }

The HTML Page

image

The next thing we do is to switch to File View mode and add the dataJs.htm page and the .js files required to support DataJs and KnockoutJs. We also need to unload the LightSwitch project and add the pages to the project manifest. That process is covered in the article: Calling LightSwitch 2011 OData Using Server Side Code.

The Code

image

For the top of the dataJa.htm page we use the following code:

<!DOCTYPE html>
<html>
<head>
<title>Products</title>
    <style type="text/css">
    body {
        color: #444444;
        font-family: Calibri, Verdana;
    }
    .titleSpan {
        font-weight: bold;
    
    }
    .sectionArea {
        border: 1px solid gainsboro;
        padding: 8px;
        margin-bottom: 8px;
        background-color:  #f1edb9;
        width: 50%;
    }
    .ideaBox {
        cursor: pointer;
        padding-top: 8px;
    }
    #modelArea {
        border: 1px solid gainsboro;
        padding: 8px;
        margin-bottom: 8px;
    }
    button, input, textarea { font-family: Calibri, Verdana; font-size: 100%; }
</style>
</head>
<body>
<h1>Products</h1>
<p>
This page shows how to create / read / update / delete information from a LightSwitch OData service.
</p>

 

image

Next, we add a DIV that will display a message when the page is busy communicating with LightSwitch:

<div id='newproductArea' class="sectionArea">

 

image

Then we put in the Refresh button. This is a normal HTML button except for the KnockoutJs attributes that will trigger the “loadproductsJavaScript method:

<button id="refreshButton" data-bind="click: loadproducts, disable: communicating">Refresh</button>

 

We see that loadproducts is a JavaScript function that calls the LightSwitch OData service:

        // Discards all products and reloads them from the server.
        this.loadproducts = function () {
            makeRequest({ requestUri: serviceUri + "FlowerShopProducts" }, function (data) {
                that.products().splice(0, productsViewModel.products().length);
                $.each(data.results, function (index, value) {
                    that.products.push(productModelToViewModel(value));
                });
            });
        };

 

This is the makeRequest method that the loadproducts method invokes:

    // Make a request, setting the 'communicating' flag.
    var makeRequest = function (request, success) {
        productsViewModel.communicating(true);
        $("#messageBar").text("Contacting server...").show();
        return OData.request(request, function (data) {
            productsViewModel.communicating(false);
            $("#messageBar").hide();
            success(data);
        }, function (err) {
            productsViewModel.communicating(false);
            $("#messageBar").hide();
            alert("Error while contacting server: " + err.message + " - " + JSON.stringify(err));
        });
    };

 

image

The following is the DIV and the template used to display the products:

<div id="productsArea" 
        data-bind="template: { name: 'productTemplate', foreach: products }" 
        class="sectionArea">
</div>
<script type="x-jquery-tmpl" id="productTemplate">
<div class='productBox'>
{{if editing}}
  <input type="text" data-bind="value: ProductName" size="80" /><br />
  <textarea data-bind="value: Description" cols="80" rows="4"></textarea><br />
  <input type="text" data-bind="value: Price" size="80" /><br />
  <button data-bind="click: saveproduct, disable: communicating">Save</button>
{{else}}<br />
  <span class='titleSpan'>${ProductName}</span><br />
    ${Description}<br />
    $${Price}<br />
  <button data-bind="click: editproduct, disable: communicating">Edit</button>  
{{/if}}
<button data-bind="click: deleteproduct, disable: communicating">Delete</button>
<br />
</div>
</script>

(notice there are really two possible templates, a display template and an edit template, separated by the {{if editing}} value)

image

When the Edit button is clicked, the following code runs and sets the editing flag to true, and the edit template is displayed for the Product:

        // Start editing an product.
        model.editproduct = function () {
            this.editing(true);
        };

 

When the Save button is pressed this code runs:

        // Save the changes to the product.
        model.saveproduct = function () {
            var that = this;
            var data = productViewModelToModel(that);
            var request = {
                requestUri: data.__metadata.uri,
                headers: { "If-Match": " *" },
                method: "PUT",
                data: data
            };
            makeRequest(request, function (data) {
                that.editing(false);
            });
        };

 

When the Delete button is pressed this code runs:

        // Deletes this product from the server and removes it from the view model.
        model.deleteproduct = function () {
            var that = this;
            var request = {
                requestUri: that.__metadata.uri(),
                headers: { "If-Match": " *" },
                method: "DELETE"
            };
            makeRequest(request, function (data) {
                productsViewModel.products.remove(that);
            });
        };

 

When a Product is Inserted, this code runs:

        // Adds the newproduct placeholder to the list and saves to the server.
        this.addNewproduct = function () {
            var request = {
                requestUri: serviceUri + "FlowerShopProducts",
                Accept: "application/json",
                method: "POST",
                data: {
                    Id: that.newproduct.id(),
                    ProductName: that.newproduct.productName(),
                    Description: that.newproduct.description(),
                    Price: that.newproduct.price()
                }
            };
            makeRequest(request, function (newItem) {
                that.newproduct.id("Id");
                that.newproduct.productName("New product");
                that.newproduct.description("Product description");
                that.newproduct.price("Price");
                that.products.push(productModelToViewModel(newItem));
            });
        };

 

An Important Note About SSL

A production application must run on a webserver that has SSL enabled. Otherwise, a hacker with a packet sniffer can easily get the data and the usernames and passwords of your users who are connecting to your site using public Wi-Fi access points or other unsecure networks.

Still… Use The Silverlight Screens When You Can

Silverlight is not “dead”. In fact it provides the best, most efficient user experience. You will want to use the normal Silverlight screen whenever you can. For example, allow users to place and track orders using a web page, but use the LightSwitch Silverlight screens for customer service, inventory management, and other administration functions.

The advantage of using LightSwitch is that all business rules and security are maintained in one place.

Also See

A Full CRUD LightSwitch JQuery Mobile Application

Calling LightSwitch 2011 OData Using Server Side Code

Using The OData Explorer with LightSwitch OData

Learn How To Make OData Calls In LightSwitch 2011

Accessing Your Visual Studio 2011 LightSwitch Application Using OData

Download Code

The LightSwitch project is available at:

http://lightswitchhelpwebsite.com/Downloads.aspx

Tags: OData
Categories:

9 comment(s) so far...


Gravatar

Re: A Full CRUD DataJs and KnockoutJs LightSwitch Example Using Only An .Html Page

Congratulations Michael on yet another great LightSwitch - oData post. I especially like the se of Knockout for data binding.

By Delordson on   4/14/2012 8:55 PM
Gravatar

Re: A Full CRUD DataJs and KnockoutJs LightSwitch Example Using Only An .Html Page

@Delordson - Thanks for the feedback!

By Michael Washington on   4/14/2012 9:04 PM
Gravatar

Re: A Full CRUD DataJs and KnockoutJs LightSwitch Example Using Only An .Html Page

Nice article. Really help me in my new project

By Avinash on   9/18/2012 7:22 AM
Gravatar

Re: A Full CRUD DataJs and KnockoutJs LightSwitch Example Using Only An .Html Page

you can also do a post using jquery,
this is how I save a game

var data = {
PlayerName: self.playerName(),
Score: self.currentScore()
};
$.post("/games/gameover/", data, function (returnedData) {
if (returnedData) {
self.isSaved(true);
}
});

By wordsearch on   10/1/2012 9:01 AM
Gravatar

Re: A Full CRUD DataJs and KnockoutJs LightSwitch Example Using Only An .Html Page

Great article,

you have to remove the reference to the id when inserting products, otherwise you can only insert one product.

The ID is set automatic

By StePro on   10/22/2012 6:57 AM
Gravatar

Re: A Full CRUD DataJs and KnockoutJs LightSwitch Example Using Only An .Html Page

hi,

i have front end code HTML page but using only back end code from light switch HTML client
if it is possible?

By sekar kandan on   12/20/2012 5:05 AM
Gravatar

Re: A Full CRUD DataJs and KnockoutJs LightSwitch Example Using Only An .Html Page

@sekar kandan - It may be but I have no examples.

By Michael Washington on   12/20/2012 5:06 AM
Gravatar

Re: A Full CRUD DataJs and KnockoutJs LightSwitch Example Using Only An .Html Page

Are there any examples of using two-way binding and dependency chains like in knockout (http://knockoutjs.com/documentation/computedObservables.html) to make LS computed properties work in HTML client? or better yet, does anyone know how soon MS may include such functionality?

By joshbooker on   1/11/2013 8:47 AM
Gravatar

Re: A Full CRUD DataJs and KnockoutJs LightSwitch Example Using Only An .Html Page

@joshbooker - Sorry no.

By Michael Washington on   1/11/2013 8:47 AM

Your name:
Gravatar Preview
Your email:
(Optional) Email used only to show Gravatar.
Your website:
Title:
Comment:
Security Code
CAPTCHA image
Enter the code shown above in the box below
Add Comment   Cancel 
Microsoft Visual Studio is a registered trademark of Microsoft Corporation / LightSwitch is a registered trademark of Microsoft Corporation