Introduction.

It is often said that key advantage of ASP.NET MVC over usual ASP.NET is that MVC applications are testable, it is not fully true. ASP.NET is just a presentation framework and it is our fault if we mix UI event handlers and business logic. To be fully clear, ASP.NET MVC is a technology to make applications whereas ASP.NET is a technology to make presentation. MVC does right thing - it uses ASP.NET for presentation and provides additional layer of abstraction for business logic, it is logical, it is simple and that's why it is so popular. The only problem with ASP.NET MVC is that it force us to drop many good features ASP.NET provides, such as reusable controls, state model, events, visual designer and so forth. What a wonderfull world would it be if there were a framework which would not and at the same time give us testability, separation of concerns, friendly urls... Now there is one.

Problems LiveUI solves

Testability

Usually ASP.NET application is a set of .aspx pages. These pages contain control hierarchy and event handlers, all application logic is typically implemented in these handlers.  LiveUI allows to split this logic into application logic and presentation logic, so instead of one thick presentation layer there are application layer and presentation layer. LiveUI application layer consists of testable Components which have hierarchycal structure similar to Controls' structure. 

There is no strict constraints for how View and Component will interact with each other. You can follow any MVC, MVP or MVVM pattern, whatever you wish. LiveUI just binds View and Component, it's up to you to decide what will they do. Shortly, LiveUI provides component model for application logic and lightweight dependency injection for dependencies management.

JavaScript Objects Management

LiveUI allows server side code to manipulate client  side objects. There is Js class which records client side methods' calls and then produces JavaScript to be performed on client side.  For example, at server side we run

Js.Call("alert", Js.Const("Hello world"));

and following JavaScript runs at client side

alert("Hello world");

This approach allows wrapping any JavaScript Components into ASP.NET controls and these controls turns out to be more simple and flexible than built in usual ASP.NET manner. For example if we have JavaScript Calendar, there is how ASP.NET Wrapper can look like

public class Calendar : ControlBase
{
  public DateTime? Value
  {
    get { return ClientState.GetValue<DateTime?>("value"); }
    set { ClientState.SetValue("value", value); }
  }

  public override void OnRender(JsCreationSection section)
  {
    base.OnRender(section);
    if (!IsRendering)
      return;

    JsObject calendar = Js.New("Calendar");

    ClientState.Synchronize("value",
      () => calendar.Call("getValue"),
      (value) => calendar.Call("setValue", value));
  }
}

Client-Server Interaction

LiveUI allows calling methods of server side controls and components from client side JavaScript. For example, when user clicks button we can call any method of any server side control. This request can be sent using Ajax or using PostBack. Server side methods can have any serializable arguments. For example, if we have RequestSamplePage.aspx with imput and button

<input type="text" id="textBox" /><br />
<button id="button">Click me</button>

We can make textValue sent to Page's method:

  1. public partial class RequestSamplePage : System.Web.UI.Page
  2. {
  3.   public Js Js { get { return jsManager.Js;} }
  4.  
  5.   protected void Page_Load(object sender, EventArgs e)
  6.   {
  7.     var button = Js.Call("document.getElementById", Js.Const("button"));
  8.     var textBox = Js.Call("document.getElementById", Js.Const("textBox"));
  9.  
  10.     button["onclick"] = Js.Function(delegate {
  11.       var request = requestManager.CreateControlMethodRequest(this, "ShowMessage", textBox["value"]);
  12.       request.Send();
  13.     });
  14.   }
  15.  
  16.   public void ShowMessage(string text)
  17.   {
  18.     Js.Call("alert", Js.Const("Received " + text));
  19.   }
  20. }

 

User Friendly Urls

LiveUI provides simple flexible solution for Url parsing and generation. Shortly, LiveUI provides api for converting any object to url and back. This makes urls user friendly and url generation code looks natural and simple. Url's format can be set in configuration section and does not affect application logic, all work with urls goes in object oriented manner. For example, there are BugtrackerDemo urls configuration

  1. <LiveUI.Routing>
  2.   <routes>
  3.       <add name="bugtracker" format="//{Content}" targetType="Demo.BugTracker.Model.BugTrackerTabList, Demo.BugTracker"handler="~/Default.aspx">
  4.       <routes>
  5.         <add name="userCreate" format="Users/New" targetType="Demo.BugTracker.Model.UserCreateForm, Demo.BugTracker" handler="~/BugTracker.aspx" />
  6.         <add name="userEdit" format="Users/{UserID}?grid={GridRoute}" targetType="Demo.BugTracker.Model.UserEditForm, Demo.BugTracker" handler="~/BugTracker.aspx" />
  7.            ...
  8.       </routes>
  9.     </add>
  10.   </routes>
  11. </LiveUI.Routing>

 

Web Applications Reusability

LiveUI allows sharing .ascx user controls and resources between asp.net web applications; With LiveUI Any asp.net application can be plugged to other asp.net application and its resources and user controls would be accessible through virtual path and by url. This allows making reusable components and encourages better application design.  Currently LiveUI itself includes 4 modules which can be plugged to you application. To plug application it typically enough to add one line to application's configuration file:

  1. <LiveUI>
  2.     <Modules>
  3.       <add moduleName="extjsControls" moduleAssembly="Xtensive.Extjs2.Controls" location="../../Modules/Xtensive.Extjs2.Controls" />
  4.       <add moduleName="extjs" moduleAssembly="Xtensive.Extjs2.Forms" location="../../Modules/Xtensive.Extjs2.Forms" />
  5.       <add moduleName="webforms" moduleAssembly="Xtensive.Web.Forms" location="../../Modules/Xtensive.Web.Forms"/>
  6.       <add moduleName="demoBrowser" moduleAssembly="Demo.Browser" location=""/>
  7.       <add moduleName="accountManager" moduleAssembly="Demo.AccountManager" location="../../Demos/Demo.AccountManager"/>
  8.       <add moduleName="fileBrowser" moduleAssembly="Xtensive.FileBrowser" location="../../Modules/Xtensive.FileBrowser"/>
  9.    </Modules>
  10. </LiveUI>

LiveUI also provides unified initialization model and allows modules to configure each other.

Rapid Forms Development

Built in LiveUI modules allow to create forms almost declaratively. You can write a few lines of C# code and get tree with dynamically loaded nodes or grid with sorting columns. For example, there is code for file uploading form:

  1. public class UploadingFormSample
  2.   : Form
  3. {
  4.   public override void OnInitializing()
  5.   {
  6.     Fields.Add(new TextField {Label = "Document Title"});
  7.     Fields.Add(new FileSelectField {Label = "File"});
  8.     Footer = new OkCancelButtonSet();
  9.     base.OnInitializing();
  10.   }
  11. }