Click here to Skip to main content
Click here to Skip to main content

Developing Web 2.0 User Interface for Self Hosted WCF Services using HTML5, CSS3 and JQuery

, 24 Jul 2011
Rate this:
Please Sign up or sign in to vote.
Devloping Web 2.0 user interface for self hosted WCF services using HTML5, CSS3 and JQuery
WCFWebApp Image - maximum width is 600 pixels

Introduction

This article describes a method to utilize WCF self hosted services to be able to serve web 2.0 user interface as well as web services.

By using this method tools or applications can be built using web 2.0 technologies like HTML5, CSS3 with self hosted WCF service as backend business layer. Thus developers can benefit from advanced JavaScript libraries like JQuery or Underscore, etc.. to build user interface. This eliminates need to install .NET Framework on client machines.

Traditionally, self hosted WCF services has user interface built using WinForms and WPF technologies. And to be able to use browser as UI platform ASP.NET and IIS become hard dependencies. For tools and applications which typically are executed out of a single machine or intranet with limited users, IIS is considered as an overkill. Thus browser as a UI platform with HTML5, CSS3 and backed by powerful JavaScript engines is a very promising option for self hosted WCF services.

Background

Initial versions of WCF could only work with SOAP messages. With bindings like WebHttpBinding from .NET 3.5 onwards WCF could offer direct support to consume web services from Ajax calls from JavaScript. However consuming dataformats like JSON is still not so much so an out of the box experience. Effort to write DataContracts for every argument and return types is quite high. And with other data formats like XML, client end couldn't directly benefit from JavaScript libraries due to the extra step involved to convert from XML to JSON.

This method considers 'Stream' as input and out type for UI interfacing operations. It also supports basic authentication which can be extended for advanced usage. And no customization is done at any layer and just works based on out of box features of WCF in .NET 3.5. This can also be used with .NET 4.0. However JSON.Net is used to format json objects.

Using the Code

Download and build the source. You can use Visual Studio 2010 or VS command line. (Code is built for .NET 4.0, but can be used with .NET 3.5 also.)

  1. Start WCFWebApp.exe. If port 2011 is not free, change to a different port. And you need admin privileges.
  2. When server is running, open any browser with JavaScript support and navigate to "http:/:/index.htm".
  3. Enter username # 'user' and password # 'pass' and click on login. You will login and an About page is loaded.
  4. Click on States link.
  5. Check on visited option for any state and click on Update.
  6. Change page to About and come back to States and observe that last selection is persisted.
  7. Click on 'Logout' on right top corner.

All these operations are run out of a self hosted WCF service. And this demonstrated features like authentication, fetching static files, getting as well as setting and data. Following sections walk through code.

Server Code

Main class just starts a WCF service using WebHttpBinding and WebServiceHost.

  class Program
  {
    static void Main(string[] args)
    {
      string baseAddress = "http://" + Environment.MachineName + ":2011/";
      using (WebServiceHost host = 
		new WebServiceHost(typeof(WebApp), new Uri(baseAddress)))
      {
        WebHttpBinding binding = new WebHttpBinding();
        host.AddServiceEndpoint(typeof
		(IWCFWebApp01), binding, "").Behaviors.Add(new WebHttpBehavior());
        host.Open();
        ... other lines left for brevity
      }
    }
  }

Service contract defines a method 'Files' to serve all static HTML files, another method 'Links' serves all linked files like JavaScript, stylesheets and data. Other resources like login. logout, States and State are service operations. Observable point here is 'Stream' data type for input as well as output.

  [ServiceContract]
    public interface IWCFWebApp01
    {
      [OperationContract, WebGet(UriTemplate = "/{resource}.{extension}")]
        Stream Files(string resource, string extension);

      [OperationContract, WebGet(UriTemplate = "/{path}/{resource}.{extension}")]
        Stream Links(string path, string resource, string extension);

      [OperationContract, WebInvoke(Method = "POST", UriTemplate = "/login")]
        Stream Login(Stream request);

      [OperationContract, WebInvoke(Method = "POST", UriTemplate = "/logout")]
        Stream Logout(Stream request);

      [OperationContract, WebGet(UriTemplate = "/states")]
        Stream States();

      [OperationContract, WebInvoke(Method = "POST", UriTemplate = "/state")]
        Stream State(Stream request);
    }

Now coming to service implementation. As this method is primarily intended for self hosted WCF services, singleton instance with concurrent threads is good enough. Consider sessions as applicable. But unlike IIS hosted services, self hosted services would normally serve limited users and thus default concurrency is good enough. And on functional line constructor is just loading data onto local member.

  [ServiceBehavior(InstanceContextMode = 
	InstanceContextMode.Single,ConcurrencyMode=ConcurrencyMode.Multiple)]
    public class WebApp : IWCFWebApp01
  {
    JObject states;

    public WebApp()
    {
      if (states==null)
        states = JObject.Parse(File.ReadAllText("web\\data\\states.json"));
    }

    ... other lines left for brevity

  }

Now that the server is running, when user tries to access for the first time, several HTM, CSS and JavaScript files are served. These are handled by methods 'Files' and 'Links'. Links are files referred in index.htm in head section like JQuery. And in 'Files' method, different types of files are picked up from separate folders based on extension. Switch cases can be extended based types of files.

    public Stream Links(string path, string resource, string extension)
    {
       ... other lines left for brevity
    }

    public Stream Files(string resource, string extension)
    {
      switch (extension)
      {
        case "htm":
           ... other lines left for brevity
        case "js":
           ... other lines left for brevity
      }
    }

When user makes a login request, basic authentication token is sent in standard header "Authorization". That is validated in a separate method 'Authenticate' described later. Also username is sent as JSON object in request stream which is parsed into JSON object using JSON.Net library. Logout method is similar to login.

    public Stream Login(Stream request)
    {
      if (!Authenticate()) return null;
         ... other lines left for brevity
      JObject o = JObject.Parse(data);
    }

When user clicks on 'States' request reaches the following method. As this resource doesn't have any extension, request will not go through 'Files' method. Here request is authenticated and data is sent from member variable.

    public Stream States()
    {
      if (!Authenticate()) return null;

      WebOperationContext.Current.OutgoingResponse.ContentType = "application/json";
      return new MemoryStream(Encoding.ASCII.GetBytes(states.ToString()),false);
    }

When user does a modification and clicks on 'Update', the following method would be invoked. This parses state id and update class member variable and returns updated list back to client.

    public Stream State(Stream request)
    {
      ... other lines left for brevity
      JObject data = JObject.Parse(new string(buffer));
      int id = ((int)data["id"]) -1;
      states["states"][id]["visited"] = true;

      return States();
    }

Authentication methods which require authorization invoke the following method:

    public bool Authenticate()
    {
      string userName = "user";
      string password = "pass";

      string basicAuthCode = Convert.ToBase64String 
	(Encoding.ASCII.GetBytes (string. Format ("{0}: {1}", userName, password)));
      string token = WebOperationContext.Current.IncomingRequest.Headers["Authorization"];
      if (token.Contains(basicAuthCode))
      {
        return true;
      }
      else
      {
        WebOperationContext.Current.OutgoingResponse.StatusCode = 
					HttpStatusCode.Unauthorized;
        return false;
      }
    }

Client Code

Client code is placed in separate folder by name 'web'. At the root of this folder, all static HTM files are placed. And separate sub-folders are included for images, JavaScript and stylesheets. These are referred from 'Files' method in server code based on extension.

Client follows Single Page Application design. Thus only 'index.htm' is a full HTML page. Other HTML files are filled into 'content' division using Ajax calls as shown below for states:

function StatesPage () {
  this.loadStatesPage = function (data) {
    content = undefined;
    $.each (data, function (index, value) {
      if (data[index]["id"]=="content") {
        content = data[index].innerHTML;
        $("#content")[0].innerHTML = content;
        $("#b_update")[0].onclick = updateStates;
        loadStatesTable();
      }
    });
    if (content == undefined) {alert("Failed to load page: Content missing"); return;}
  }
      ... other lines left for brevity
}

Authentication: Client side authentication token is in login class. This token is added in header section in 'beforeSend' function of each call after login. Other code in client requires understanding about Jquery, JavaScript and Ajax concepts which are well explained on the web.

Points of Interest

If windows authentication is required, service host can be customized.

More structured JavaScript libraries with MVC architecture can also be used without making any change to server side code.

Consider using JQuery UI plugins for common look and feel.

As UI is browser based, extending UI for handheld devices becomes quite easy.

History

  • 2011-07-22: First version
  • 2011-07-23: Article updated

License

This article, along with any associated source code and files, is licensed under The MIT License

Share

About the Author

Sriharsha Vardhan
Architect
India India
No Biography provided

Comments and Discussions

 
QuestionWeb server & sql server PinmemberLopezd24-Sep-13 11:31 
QuestionHow to assume /index.htm ? PinmemberJeremy Bradshaw9-Mar-13 2:23 
AnswerRe: How to assume /index.htm ? PinmemberSriharsha Vardhan19-Mar-13 7:44 
QuestionUpdating the data directly to the json file PinmemberNazha Harb8-Nov-12 5:06 
AnswerRe: Updating the data directly to the json file PinmemberSriharsha Vardhan19-Mar-13 7:48 
QuestionPath for download link moved by codeproject PinmemberSriharsha Vardhan20-Sep-12 6:25 
GeneralMy vote of 5 Pinmemberbukwa78-Aug-12 0:18 
QuestionAttached source code link broken Pinmemberbspengr14-Jun-12 6:27 
AnswerRe: Attached source code link broken Pinmemberbukwa78-Aug-12 0:21 
GeneralRe: Attached source code link broken PinmemberSriharsha Vardhan20-Sep-12 6:22 
QuestionFile Not Found PinmemberFarhan Ghumra6-Jun-12 2:11 
GeneralMy vote of 4 PinmemberCuteD34th22-Feb-12 19:00 
QuestionWindows Authentication Pinmemberrmbrunet25-Jul-11 7:58 
QuestionHow to handle deeper pathing? Pinmemberkgoulding25-Jul-11 4:06 
AnswerRe: How to handle deeper pathing? PinmemberSriharsha Vardhan26-Jul-11 20:46 
QuestionAddressAccessDeniedException was Unheled Pinmemberkrishna_goluguri24-Jul-11 23:46 
AnswerRe: AddressAccessDeniedException was Unheled Pinmemberkgoulding25-Jul-11 11:52 
GeneralRe: AddressAccessDeniedException was Unheled PinmemberSriharsha Vardhan26-Jul-11 20:18 
GeneralRe: AddressAccessDeniedException was Unheled [modified] PinmemberJeremy Bradshaw8-Mar-13 23:27 
GeneralRe: AddressAccessDeniedException was Unheled PinmemberSriharsha Vardhan19-Mar-13 8:00 
QuestionMore to follow? PinmemberSkif21-Jul-11 13:06 
AnswerRe: More to follow? PinmemberSriharsha Vardhan21-Jul-11 15:54 
It's not just login page. Once you login it covers scenarios to fetch and update data. That is more or less the base for GET and POST requests.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140821.2 | Last Updated 24 Jul 2011
Article Copyright 2011 by Sriharsha Vardhan
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid