yysun's space

Posts Tagged ‘webmatrix

Recently I have made some improvements to the Rabbit Framework. I figured out how to inject a base class between WebPage and the Razor page, so that to create a Web Form or a MVC controller is just to inherit from the base classes.

@inherits Rabbit.WebForm
@functions {
         void button_click(string name)
         {
         }
}

Or

@inherits Rabbit.MvcController
@functions {  
    [Get("/")]
    void Index() {
}

Another interesting thing I did is to sync data between C#, JavaScript and HTML inputs.

1. C# fields (both public and non-public) are populated with HTML inputs.

<input type=”text” name=”txtEmail” value=”@txtEmail”/>

@functions {
    string Email = “”; // it will have the value user typed after post.
}

This is similar to the model binding concept found in ASP.NET MVC. The difference is here we bind to fields, where ASP.NET MVC binds to action parameters (actually, we do that too).

2. C# public fields are synced with JavaScript through a JavaScript object, called webForm.

@functions {
      public int count = 20;
}

<script>
alert(webForm.count); // it shows 20
<script>

And vice versa, if changed the value in JavaScript, the C# field has the new value after post.

The C# data are serialized into JSON. On the client side, it can be rendered into HTML using jQuery template or jsrender.

It also could be a solution to view state to some degree I think.

Download the sample site to see how it works.

I found myself hitting F5 in IE like crazy. Every time after modified the web files, in order to preview the result, I need F5 to refresh IE.

So, I created a small Windows Forms application that monitors the web site folder (using FileSystemWatcher). When web file changed, it searches all IE browsers that are from the web site. and send key F5 (actually post message via p-invoke).

It works very well especially on two monitors. Saving files on one monitor, browser refreshes on the other.

image

It is very convenient. After saved the files, I will see the result immediately. It is not only useful for developing UI. It is also great for unit testing.

After modified and saved the tests in the Rabbit Framework, the test runner page refreshes automatically.

I didn’t make it a Visual Studio Plug-in, because I need it when using Visual Studio Express and WebMatrix.

I have built Web Forms on top of ASP.NET Web Pages.

The HTML is clean and unobtrusive. It uses HTML 5 data attributes. No messed up Ids. No view state. It supports multiple forms on a page.

image

The server side event handler has meaningful parameters. My Web Forms engine will feed the parameters with data comes in the HTML form posted.

image

Nice and simple. I will release it in the Rabbit Framework.

After Part I and Part II, here comes the part of making a dynamic site.

I am always impressed by PHP based CMS, like Joomla, Drupal, Wrodpress and etc. Nothing from .NET comes close to them.

With the WebMatrix, I want give it a try myself to build a dynamic and extensible site. It is going to have features of

  • Modules
  • Plugins
  • Templates
  • NuGet Package

 

Modules are a deployment packages of certain functionality. E.g. Pages, Blog, News, User Management … Modules are deployed as NuGet Packages. Modules can be enable and disable at runtime.

Many CMS have the concept of module (Drupal, XOOPS, DotNetNuke, Orchard…). It is called Component in Joomla.

Module functions are extensible. Modules publish extension points to allow other modules to extend functions.

The concept of Extension points is famous in Eclipse. MEF uses Import and Export. WordPress uses Hooks. Inspired by WordPress, I will use Hooks.

Hooks are a loosely coupled event publication and subscription. From anywhere of the site modules, you can request to run a hook (like fire a event). If any module has added (registered) the hook implementation, it will be invoked. The result of all hooks are chained.

E.g. In the _PageStart, there is a line.

Layout = Site.RunHook("get_layout") as string;

The template module responses to the hook get_layout and return the layout file name.

That’s it. The core mechanism of a dynamic site is that modules request hooks and as well as implement the hooks. Hooks glue all program pieces together.

Put it all together I will create a framework, the Rabbit Framework for WebMatrix.

Name it Rabbit, just because rabbit are small, light, fast, delicate … and this year is the Year of Rabbit.

Continuing from Part I, here are more fun – using .NET 4 dynamic.

  • Extension methods for creating dynamic objects
  • Validation of dynamic objects (declarative / DSL style)
  • Unit Testing within web site
  • Mock, stub, fake all in one 

Extension methods for creating dynamic objects

To create DTO from database and/or screen (html form), I developed two extension methods.

image

They made it very easy to create DTO in model.

image

From the controller, this is how to let the model create a new DTO from screen and save it to database.

image

The convention here is, table column name = object property name = html input name. And they are case sensitive.

 

Validation of dynamic objects

Since the DTO is dynamic object, there are no re-defined class to use metadata attributes (data annotations). I think it’s a good thing. It gives me a chance to do validation declaratively. The example below is self-explanatory enough because of its declarative style.  It looks like I invented a validation DSL.

image

 

Unit Testing

One limitation of web sites is that you cannot create a unit test project and reference to the web site to test classes in the web site. I created in the Rabbit Framework a Testing Module. It provides a familiar way of writing unit tests using TestClass, TestMethod attributes, and an Assert class.

image_thumb[7]

It also has a test runner page.

image_thumb[5]

The test runner page is REST/MVC style. It has URL patterns below.

~/Test the entry page to unit testing
~/Test/All lists all test classes and test methods
~/Test/TestClass runs test methods within the test class
~/Test/TestClass/TestMethod runs a test method within the test class

 

Mock, stub, fake all in one

Mocking an interface is difficult. It requires emitting classes dynamically, like what Moq does. Mocking a concrete class is more difficult.

Mocking using dynamic object is very easy. The Mock class in Rabbit Framework probably is the world’s simplest mock implementation. 160 Lines in total. No dependency to any 3rd party library.

image_thumb[9]

The Mock class is derived from the DynamicObject. It allows to,

  • Verify the sequence of methods to be called
  • Verify the times of methods to be called
  • Verify the parameter count being passed to methods
  • Verify each parameter’s type being passed to methods
  • Verify each parameter’s value being passed to methods

I really enjoyed running unit tests with mocking feature on a web page especially with the auto refresh tool.

ASP.NET Web Pages is a new Microsoft technology for web development. But the built-in template is misleading. It lets new / first time user think it is just an ASP with the Razor syntax. But it is much powerful than that. After all, I created a few fun stuffs with it.

Simple MVC

ASP.NET Web Pages’ Razor engine is the foundation of ASP.NET MVC 3. I found it is possible to do a kind of simple MVC w/o using MVC 3, thanks to ASP.NET Web Pages’ built-in magic routing. For a request like http://…/a/b/c/d/e, it routes to /a.cshtml. a.cshtml then can be used as controller. I created the Get and Post attributes for cshtml page methods to make it Sinatra style.

image

The RenderPage function invokes a view and pushes data to the view at the same time.

Fluent Service API (Monad)

Unlike traditional models / services, where the functions usually return object(s) of some class. My service here returns itself instead, so that the operations can be chained. Exception handling, unit of work and transaction are all easier by chaining. This is inspired by the concept of Monad. Does it looks similar to jQuery.

var service = new Service(selector).Op1().Op2().Op3()…..

The only question is how to spit out the object from the operation chain at the end. It could be a get function, a property and etc. I chose to have an index property just for fun (looks like jQuery).

service[0] // this is the object (DTO, data transfer object) to be displayed in the view.

Dynamic DTO

Back to the age of C/C++, the functions and classes require to be defined in separated .h files. In Java/C#, this is not required. Things get simplified. But the compilers still require the classes to be bound to some interfaces in order to link them. Now in the era of .NET 4 dynamic, world is further simplified.

DTO, the objects that services operate on, can be dynamic. My service class has a dynamic object as DTO. When the object was created from the Request Form, all the properties are created on the fly w/o pre-defining classes and interfaces.

image

If passed the dynamic object to the view via then RenderPage function, we can retrieve the data within the view via the Page property.

image

BTW, the Page property of an ASP.NET Web Page is also a dynamic property bag. We can push data and retrieve data like regular properties.e.g. Page.hasError.

After used above tricks in my GitWeb project on Github. I am really happy with ASP.NET Web Pages so far.

UPDATE: Put it all together I created a framework, the Rabbit Framework.



    • Pk: The horizontal view is a pleasure to use! Good thinking
    • randyburden: A valiant and commendable effort. Your use of Tuple is a little weird but it offers a feature that most other microORMs don't. Your use of a static Gu
    • reav: great work done on Rabbit Framework. just started to learning it, and by now i think it will solve all my problems and questions, that i had in webpag

    Categories