TOP

Preparing for Windows 8

This post is written without any special knowledge about the upcoming release of Windows 8. I’m relying on the already publicly known details that Windows 8 will support tablet devices to the full and enable developers to utilize their web skills building rich applications.

A very good friend of mine, Ingo Rammer, did a talk at NDC 2011 on HTML 5. One of the best tip I got from his talk, was to start using Adobe AIR as the shell for your HTML 5 applications. As you might not be aware of, Adobe AIR includes the WebKit browser engine which more or less supports some of the HTML 5 features.

That means you can build a rich desktop application in HTML 5 which have access to local resources, such as the file system. Another neat feature is the cross-platform support between Windows and Mac. Unfortunately Adobe has quit their support for Linux.

Get the Adobe AIR SDK

First thing first, get the Adobe AIR SDK. After downloading and unpacking, you should add the path to the bin folder to your paths environment variable. this makes it quicker to build your application.

Building your first application

Create a new folder for your application on your computer, preferably you should use a source control, such as Mercurial. This makes it easier to recover from human errors.

To start off, I suggest using the HTML 5 boilerplate. I suggest going through the custom build and remove all the backwards compatibility features, as you are only going to be building for the WebKit browser.

In this folder, you can add your stylesheets, graphics, html, javascript and other resources you will be using in your application.

I suggest creating a file named Launch.bat which can be used during development and testing to launch your application.

Content of Launch.bat: adl.exe “MyIncredibleApp-app.xml”

Then you need to create your MyIncredibleApp-app.xml file, which is the manifest definition for your application. All this really needs, is the default HTML page it should render when starting up. Here is an example from one of my own applications:

<?xml version="1.0" encoding="UTF-8"?>
<application xmlns="http://ns.adobe.com/air/application/2.7">
    <id>FlickrDownloadr</id>
    <versionNumber>0.1</versionNumber>
    <filename>Flickr Downloadr</filename>
    <initialWindow>
        <content>Flickr Downloadr.html</content>
        <visible>true</visible>
        <width>800</width>
        <height>600</height>
    </initialWindow>
  <copyright>Copyright (c) 2006-2011 Sondre Bjellås.</copyright>
  <icon>
    <image16x16>icons/Flickr-Downloadr-16x16.png</image16x16>
    <image32x32>icons/Flickr-Downloadr-32x32.png</image32x32>
    <image48x48>icons/Flickr-Downloadr-48x48.png</image48x48>
    <image128x128>icons/Flickr-Downloadr-128x128.png</image128x128>
  </icon>
</application>

The next very important step, is to copy the Adobe AIR JavaScript files into your folder. Depending on your installation path, you should find the AIRAliases.js and AIRIntrospector.js files located here: AdobeAIRSDK\frameworks\libs\air. Copy these two files into your project and make sure you reference the AIRAliases.js in your web page. The AIRIntrospector you won’t be needing unless you are doing advanced debugging.

<script src=”AIRAliases.js”></script>

Make a wrapper around the JavaScript API

Going forward, with advances in browsers such as Internet Explorer, Chrome, FireFox and Opera – you might see that some actually already today – will support access to local resources. That means you can build web applications that doesn’t required Adobe AIR as a delivery mechanism.

For this reason, I suggest writing your own wrapper around the JavaScript API included with Adobe AIR. That means you won’t be directly dependent on Adobe AIR and it will make the transition to support other platforms and browser much smoother.

Here is an example on how to show a folder dialog using the Adobe AIR JavaScript SDK:

    var file = new air.File();
    file.addEventListener(air.Event.SELECT, dirSelected);
    file.browseForDirectory("Select a directory where you want to save photos.");

Launching your rich desktop web application

Next step is to complete your HTML page, I would suggest downloading libraries such as jQuery UI to add animations and other great features. While this post does not explain how to go from a development environment to releasing your app, I suggest referring to the Adobe AIR SDK documentation for additional features.

This is a starting point on how to get started and possibly preparing for a possible future of building great Windows 8 web applications.

Here is a screenshot of one of my own web based rich desktop applications:

TOP

Configurable Service Routes

configurationOne of the things I don’t like about the default way of working with (URL) routes in ASP.NET MVC, is code in the Global.asax. While this is fine for simple MVC-routing, you don’t want to hard-code all your WCF endpoints inside that class, instead you want to configure using the web.config.

The first part of this code example is based upon code from one of my colleagues (thanks Roy Tore), it’s basically a custom configuration element for your web.config, which allows you to define a list of services and the route it should be registered on.

Second element of this sample, is how the types are defined in the serviceType proprety in the web.config, which does not require a specific type, but support the use of interfaces. There is additional code in the example, which extends the WebServiceHostFactory with support for dependency injection using Autofac.

Walkthrough

Here is a walkthrough on how you can do this from scratch.

  1. Create a new ASP.NET MVC 3 Web Application.
  2. Install the Autofac.MVC3 NuGet package.
  3. Add a reference to System.ServiceModel.dll, System.ServiceModel.Activation and System.ServiceModel.Web.dll
  4. Download the Routing.zip and unpack this into your web project.
  5. Modify the global.asax.cs, inside the Application_Start handler, add the following code in the beginning of the method:
    DependencyResolver.SetResolver(new AutofacDependencyResolver(CreateContainer()));

    And on the bottom of the method, after the ASP.NET MVC routes (RegisterRoutes):

    RouteTableManager.MapRoutes(DependencyResolver.Current.GetService<DynamicWebServiceHostFactory>());

  6. Modify the same file, but this time inside the RegisterRoutes method. We need to make sure the regular ASP.NET MVC routing will ignore our special services URI. See the full example below, and here is the modified default route:

    routes.MapRoute(
        "", 
        "{controller}/{action}/{id}",
       new { controller = "Home", action = "Index", id = UrlParameter.Optional },
       new { controller = "^(?!services).*" } // Important for WCF services to work.
        );
     
  7. Create a new method called CreateContainer inside global.asax.cs, which creates your inversion of control container. Preferbly this should be placed somewhere else in a separate class. The first 3 registrations is to enable Autofac-support for your regular ASP.NET MVC controllers. After the changes, your global.asax.cs should look similar to this:
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
     
        routes.MapRoute(
            "", // Route name
            "{controller}/{action}/{id}",
         new { controller = "Home", action = "Index", id = UrlParameter.Optional },
         new { controller = "^(?!services).*" }
            );
    }



    protected void Application_Start() { // Set the MVC IOC resolver to our Autofac resolver. DependencyResolver.SetResolver(
    new AutofacDependencyResolver(CreateContainer())); AreaRegistration.RegisterAllAreas(); RegisterGlobalFilters(GlobalFilters.Filters); RegisterRoutes(RouteTable.Routes); // Map all the routes configured in web.config. RouteTableManager.MapRoutes(
    DependencyResolver.Current.GetService<DynamicWebServiceHostFactory>()); } private IContainer CreateContainer() { var builder = new ContainerBuilder(); builder.RegisterControllers(typeof(MvcApplication).Assembly); builder.RegisterModule(new AutofacWebTypesModule()); builder.RegisterModelBinderProvider(); builder.RegisterType<DynamicWebServiceHostFactory>(); // Register all the WCF (REST) services. builder.RegisterType<ItemService>().As<IItemService>(); var container = builder.Build(); return container; }

  8. Create your WCF (REST) Services (and modify the CreateContainer).
  9. Modify your web.config with the example below and you are done!

Add the following to your web.config, right after the configuration elemenet:

  <configSections>
    <section name="routingExtention" type="
ConfigurableServiceRoutes.Routing.RouteTableSection, ConfigurableServiceRoutes, 
Version=1.0.0.0, Culture=neutral" />
  </configSections>

  <routingExtention>
    <routes>
      <add route="services/items" serviceType="
ConfigurableServiceRoutes.Services.IItemService, ConfigurableServiceRoutes, 
Version=1.0.0.0, Culture=neutral" />
    </routes>
  </routingExtention>

If you need more services, just keep adding into the routes collection with more add elements.

Next part of the config change, is to enable the ASP.NET Compatability. This is important for the sample to work.

  <system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
  </system.serviceModel>

That’s it!

Benefits

There are multiple benefits from this sample.

  • Service Routing are configured, not compiled in code.
  • Services does no longer require an empty constructor.
  • Services supports dependency injection.
  • WCF Services works fine together with ASP.NET MVC.

And that’s basically it, I hope you enjoy this for your own projects.

Source Code

You can download a fully working sample here: ConfigurableServiceRoutes.zip

When you run the sample, you will get a 404 on the root as it’s based on an empty ASP.NET MVC 3 Web App. If you access the URL with /services/items, you should see the WCF REST Service initialize correctly.

Notes of caution

There is one place in the code, inside the DynamicWebServiceHostFactory where I override the CreateServiceHost method. The logic that replaces the base here, I don’t know what the original code was and there might be special instances where your service instance won’t work properly. It works on my machine!

TOP

Database Provider Factories: EF + SQL Compact

Now that Entity Framework 4.1 has been released and SQL Compact Edition 4.0 was released a while back, you can start using those technologies in your projects. I was working on a MVC 3 project when I discovered a NuGet package for SQL Compact Edition.

You have three option to install SQL Server Compact 4.0, using the Web Platform Installer, direct download, or you can add it as a NuGet package. I would suggest using the NuGet option, as that includes the required files with your source code. Make sure you get the documentation as well.

SqlServerCompact package: http://nuget.org/List/Packages/SqlServerCompact

With this package, you can start building code that queries and stores data in a file-based database. Yet, you still need one more package to make it work properly together with Entity Framework 4.1. Luckily, there is another NuGet package for this, EntityFramework.SqlServerCompact.

The SqlServerCompact package will try to modify your web.config/app.config with the following keys:

<configuration>
  <system.data>
    <DbProviderFactories>
      <remove invariant="System.Data.SqlServerCe.4.0" />
      <add name="Microsoft SQL Server Compact Data Provider 4.0" 
  invariant="System.Data.SqlServerCe.4.0" 
  description=".NET Framework Data Provider for Microsoft SQL Server Compact" 
  type="System.Data.SqlServerCe.SqlCeProviderFactory, System.Data.SqlServerCe, 
  Version=4.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" />
    </DbProviderFactories>
  </system.data>
</configuration>

Also included in the package is the binaries for SQL Server Compact 4.0, located at the same level as your Visual Studio solution file, you should find this folder and within it all the assemblies needed to run: packages\SqlServerCompact.4.0.8482.1. Inside the lib folder is the System.Data.SqlServerCe.dll, which is the .NET assembly you need to work against SQL Server Compact.

The other package includes the assembly System.Data.SqlServerCe.Entity.dll, which contains code that generates proper queries against the SQL Server Compact. Additionally, it will add a source code file to your project inside the App_Start folder, that contains this code:

using System.Data.Entity;
using System.Data.Entity.Infrastructure;

[assembly: WebActivator.PreApplicationStartMethod(
typeof(InTheBoks.Test.Integration.App_Start.EntityFramework_SqlServerCompact), 
"Start")]

namespace InTheBoks.Test.Integration.App_Start {
    public static class EntityFramework_SqlServerCompact {
        public static void Start() {
            Database.DefaultConnectionFactory = 
              new SqlCeConnectionFactory("System.Data.SqlServerCe.4.0");
        }
    }
}
 

What happens here is that the default connection factory of the Entity Framework is changed to the provider specified in the web.config/app.config. While I was working on the previous builds of SQL Server Compact 4 and Entity Framework 4.1 CTPs, I did not have the provider changed in the web.config. The new key in the config made me wonder for what reasons it removed and added the provider again. So I investigated with an integration test project to see what really happens.

The default connection factory is SqlConnectionFactory. That means that we need to change the connection factory in the start up of our application, which is done with the code inside the Start method displayed above, which changes it to SqlCeConnectionFactory.

To investigate what the default configuration is, I had to access a list of factories using the API: DbProviderFactories.GetFactoryClasses(). This will give you a data table with rows for all the factories. I did this to figure out why the NuGet package made the changes to my web.config/app.config and to see if there was any difference to my already installed factory and the one added in the config. Conclusion was, there is no difference. The reason why the package adds the provider, is probably because the factory is not registered on the computer if you don’t install using the manual or Web Platform Installer – so it have to add it manually in the config. My suggestion is to keep the configuration key in place, this ensures that your application will work without the need to install SQL Server Compact.

Reference Table for DbProviderFactory Classes.

Name Description Invariant
Odbc Data Provider .Net Framework Data Provider for Odbc System.Data.Odbc
Type System.Data.Odbc.OdbcFactory, System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
OleDb Data Provider .Net Framework Data Provider for OleDb System.Data.OleDb
Type System.Data.OleDb.OleDbFactory, System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
OracleClient Data Provider .Net Framework Data Provider for Oracle System.Data.OracleClient
Type System.Data.OracleClient.OracleClientFactory, System.Data.OracleClient, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
SqlClient Data Provider .Net Framework Data Provider for SqlServer System.Data.SqlClient
Type System.Data.SqlClient.SqlClientFactory, System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Microsoft SQL Server Compact Data Provider .NET Framework Data Provider for Microsoft SQL Server Compact System.Data.SqlServerCe.3.5
Type System.Data.SqlServerCe.SqlCeProviderFactory, System.Data.SqlServerCe, Version=3.5.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91
SQLite Data Provider .Net Framework Data Provider for SQLite System.Data.SQLite
Type System.Data.SQLite.SQLiteFactory, System.Data.SQLite, Version=1.0.66.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139
Microsoft SQL Server Compact Data Provider 4.0 .NET Framework Data Provider for Microsoft SQL Server Compact System.Data.SqlServerCe.4.0
Type System.Data.SqlServerCe.SqlCeProviderFactory, System.Data.SqlServerCe, Version=4.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91

(Foto by Tim Morgan)

TOP

InTheBoks v2 Preview

I’m currently working hard on the next version of InTheBoks. I wrote about it earlier on my blog, at which time I built it using Silverlight.

New version is being built entirely on HTML 5 and is using the latest of technologies available.

Here is a video preview of the new version, which demonstrates how I’m using AJAX to call the REST API to delete items in your movie catalog.

This new version will be released as open source and be a hosted service, that means you could build your own service just like InTheBoks and there are plenty of good code examples on how you can build modern HTML 5 applications on ASP.NET MVC 3.

Technologies and libraries in use:

  • Entity Framework 4.1 RTW (Code First)
  • SQL Server Compact Edition 4
  • ASP.NET MVC 3 (Razor syntax)
  • WCF 4 REST
  • jQuery
  • jQuery UI
  • jQuery Templating
  • Knockout JS
  • Facebook SDK

You can follow the progress on the Facebook page: http://www.facebook.com/InTheBoks

Remember to also check out the official website where the new version will be released, hopefully sometime in 2011.

http://www.intheboks.com/

TOP

Try Windows Azure for free

You can now try out Windows Azure for free, without credit card. Head over to http://windowsazurepass.com/ and signup for a 30 day pass. This should get you started on developing cloud apps and you’ll quickly realize just how easy it is, if you already know how to develop web apps.

Use the promotion code: CRMIKEA

If you have any questions regarding Windows Azure, please feel free to leave a comment. Additionally, if you live in Norway and have a interest in cloud computing, have a look at the Cloud Computing group at The Norwegian Computer Association: https://www.dataforeningen.no/cloud-computing.160488.no.html

TOP

Microsoft Office 365

Microsoft is about to release it’s latest Office product, the Microsoft Office 365, which is a cloud-based solution that delivers some of the integrated Microsoft Office tools with their server product offerings, such as Microsoft SharePoint and Microsoft Lync.

For small businesses and new startups this is a great product, which gets you started with collaboration tools within minutes, as oppose to expensive investement in servers, software, installation and maintenance. It even integrates

Go and visit the website to signup for the beta!

TOP

Blogging with WordPress

WordPress logo

Recently I started using WordPress for my blogs and today I launched this blog on WordPress, and all my blogs will soon be running on WordPress. It’s a decent blog engine that has been around for a while and is pretty stable. It takes some work to import all your existing items, ensuring permalinks are intact and that photos still works. I imported 77 blog posts from the older blog and I hope all photos should work properly.

Recently I have been using Microsoft WebMatrix for some of my web development needs and for all new WordPress site I’m building, I start out with WebMatrix. It’s simply the easiest and fastest way to get started building your own custom blogs on WordPress.

Unfortunlately the FeedBurner service doesn’t link back to the permalinks but a combination that uses the GUIDs. Unfortunlately that means all the old links in my old feed URL won’t work, but the feed contained the full posts so it shouldn’t really matter much. The new feed URL will be http://sondreb.com/blog/feed

Importing from BlogEngine.NET using the BlogML format does not do categories properly, but it does import comments. Unfortunlately I had to use the RSS import and thus all my old comments on this blog are now gone. I might consider writing a script that imports them sometime in the future, but there was a majority of spam comments so hopefully it’ll be alright.

Until next time, you can take a look at my new front page which is also running on WordPress, sondreb.com.

TOP

Doing Web Development Better Part 2

Since last time, I have come further in the research on how to have more dynamic loading of entities using reflection and I’m displaying the different actions using partial views from my themes folder. That makes it possible for individual themes to override the layout of the generated pages.

Current Status

So the current status is that I have fully dynamic rendering for list of items and details on individual items. I have not yet added support for editing. The end results of what I’m working on, might be somewhat similar to the ASP.NET Dynamic Data technology from Microsoft. It does scaffolding of your data automatically. The difference obviously will be that mine are built on ASP.NET Web Pages and next version of Entity Framework. Other than sharing some general concepts, there are no similarities between my code and ASP.NET Dynamic Data.

Status Quo

Mikael Söderström made a good example on how you can combine Entity Framework and ASP.NET Web Pages, so I won’t bother doing the same. Check a bit down on this thread: http://forums.asp.net/t/1580303.aspx

What I want to avoid is the specific repositories, I want a single repository that is dynamic and can handle any entity type. I also want to avoid any logic inside the .cshtml that relates to the creation/reading of the entities. His example is still decent for those who want to go the “new, old route” of doing web development with Web Matrix. I’m on a mission to simplify this pattern.

Get Started

What I want to show today is how to dynamically create an instance of your entity and return that from your database. Create a new empty WebMatrix website and start writing some code.

Before we begin, make sure you have the latest version of Microsoft WebMatrix, SQL Server Compact Edition and Entity Framework CTP.

First you need to go through the example by Mikael that I linked too earlier, but you can replace the GuestbookRepository.cs with the code below and the default.cshtml will be different as well.

1. Create a new interface and call it IEntity. Just keep this empty for now.

2. Create a new class and call it Repository. Copy the code below:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
using System.Web.Helpers;

/// <summary>
/// Generic repository for all of your entity types.
/// </summary>
public class Repository<TContext> where TContext : DbContext
{
    private TContext _context;
    private string _entityTypeName;
    private Type _entityType;

    public Repository(string entityTypeName)
    {
        _entityTypeName = entityTypeName;
    }

    public TContext Context
    {
        get
        {
            if (_context == null)
            {
                _context = CreateContext();
            }

            return _context;
        }
    }

    private TContext CreateContext()
    {
        _entityType = Type.GetType(_entityTypeName);

        // Make sure that only IEntity objects are returned for security reasons. You don't want
        // code that allows users to initiate any objects on the server.
        if (!_entityType.Implements(typeof(IEntity)))
        {
            throw new ApplicationException("The specified entity does not implement the required IEntity interface.");
        }

        // Create an instance of the DbContext.
        var context = Activator.CreateInstance<TContext>();

        return context;
    }

    private dynamic GetSet()
    {
        // Get an instance of the DbSet.
        var set = Context.Set(_entityType);

        // Load all the values.
        set.Load();

        // Get the query values.
        return set.Local;
    }

    public void Load(IEntity entity)
    {
        
    }

    public void Add(IEntity entity)
    {
        
    }

    public dynamic LoadAll()
    {
        return GetSet();
    }

    public void Delete(IEntity entity)
    {
        
    }
}

Unfortunately this code only does listing of all the entities, through the LoadAll method. In one of my later blog posts, I will provide example that does all the normal CRUD operations for your entities.

3. Create a new .cshtml file and call it what you want. Paste the following code into the new file:

@{
    var entityType = UrlData[0];
    var action = UrlData[1];
    var id = UrlData[2];
    
    if (string.IsNullOrEmpty(entityType))
    {
        Response.Write("There is nothing to see here... - Jim Carrey, \"Lifeguard on Duty\"");
        Response.End();
    }
    
    var repository = new Repository<BlogCatalog>(entityType);
    var result = repository.LoadAll();
    Page.Model = result;
    
    var grid = new WebGrid(Page.Model);    
}

@grid.GetHtml()

The code has been simplified a bit, it doesn’t handle multiple types of listing. The “BlogCatalog” is the DbContext you created in the example by Mikael. Change that to whatever your own context is named.

Screenshot of the end result, this is the listing of my Author table.

Result

The Beginning of By Convention

That’s the early beginning of the framework that will make it even easier and better to develop web apps using Microsoft WebMatrix and ASP.NET Web Pages. The combination of ASP.NET Web Pages with Entity Framework and doing the code by convention, gives us a powerful tool where we avoid duplicate code and we don’t have to repeat yourselves too often.

TOP

Doing Web Development Better Part 1

For a while now, I have been developing my own blogging framework using Microsoft WebMatrix and ASP.NET Web Pages. As these technologies are still in beta releases, I’m not prepared to release any beta version of my own blogging framework. What I would like to do, is share some of my experience writing the web app on this new platform. This is the first post in a series where I will explain some of my experience and hopefully give some pointers and hints.

In The Beginning

Initially I was amazed with the incredible speed and power of the ASP.NET Web Pages Razor syntax and the Microsoft WebMatrix editor, in combination with the new IIS Express. Modifications was super quick to do, no compilation involved, it just worked and it rendered fast. I started out prototyping the web app and wrote lots of code inside the .cshtml files. Even included SQL code straight in the view files, this was the beginning of web development for me when I started out on classic ASP (Active Server Pages). After a while, I moved most of my SQL queries into classes that I kept in my App_Code folder. The Microsoft Data Helpers relied heavily upon the new dynamic type. All methods returned just a dynamic type, which I initially consider to be great and powerful, I could easily extend my types with any additional properties.

It was both easy and powerful to build my web app in this manner, but as my web app kept growing I realized I needed to make some improvements. From early on, I made a very conscious decision to not rely on any ORM (Object Relational Mapping). I didn’t want the requirement to compile or generate any code. Generated code is always bad. So there was no LINQ to SQL or Entity Framework for me… but that was until…

A New Beginning

… Microsoft released a CTP (Customer Technology Preview) for the next version of Entity Framework (EF). And off I went refactoring my code into relying on the Code-First capabilities of EF CTP. Instead of manually writing my SQL scripts, which I had done up until now, I relied on the Entity Framework to generate my tables automatically. Instead of writing SQL statements, I now wrote entity types, just simple Plain Old CLR Objects (POCO). For me, it’s much more natural to write simple C# objects than SQL statements and I get better type safety which avoids some bugs, but obviously removes the benefits of working with dynamic types as I did earlier.

Here is a typical example of one of my earlier entity types:

Author

As I continued with my refactoring, a pattern started to emerge in my code base. I had my entity types, I had my catalog objects (DbContext), I had my static helper methods for all my entities and I still had a bunch of logic inside my .cshtml files to handle new elements, editing of existing elements, deletion of elements, validation of the model (user input) and often some other parts, such as the notification text to display when a save succeeded.

I started thinking that this is pointless, no developer should ever be put to write tedious repetitive code. I have lots of entities that I need the standard CRUD (Create, Read, Update, Delete) actions for and there is no chance I’m willingly going to write every single page for all of my entities. There is not legacy database, no legacy object types and no legacy requirement of any sort in my blogging framework, so I figured it was time to do more by-convention.

Don’t Repeat Yourself

So I started out thinking about how I could avoid repeating myself. I needed a convention for URLs, I came up with this current solution, will possibly change in the future, but for now it sticks:

http://url/Admin/EntityTypeName/View/FriendlyNameOrId

One example then, would be for the authors:

http://url/Admin/Author/View/admin

The type of actions I added was View, Edit, Delete, Create. View was planned to be used in the future if I add permission control that disabled the ability to edit the entity, but it’s not used much in the administration interface. Some of the guidance from REST is added here, but not all the concepts. The Delete action is only possible to do when you do a POST (or HTTP DELETE).

Here is a really simple example on how you can get the 3 input values from the URLs. All you have to do is create an Admin.cshtml file and then the above URL pattern will work just fine. UrlData won’t throw exceptions when you try to access index values that doesn’t exists, so there is no need to validate before you read the URL input.

Url

Final Thoughts

One obvious question would be why I didn’t choose to do this in ASP.NET MVC 3? It already supports the HTTP verbs, good separation of views, models, etc. The simple answer is that I think ASP.NET Web Pages in combination with WebMatrix is simpler and I wanted to do this project to learn the new technologies. I’m already doing lots of ASP.NET MVC development on my daily job, so this was a fun experience to learn something new.

I’m currently researching how I can automate the views for all my entities, by configuration or simply by reflecting over my DbContexts? Right now, I’m investigating with reflection over my DbContext types, I’ll keep you updated in the next part on this blog series.

TOP

Code Like A Girl

code_like_a_girl

It’s a well established fact that our industry (software development) has a majority of male programmers. I think it’s important that we all promote the software engineering field towards girls, ensuring the future will have a higher percentage of girls who write code.

Today, the majority of software are developed by 20+ year old boys who develops software used by approx. 50% female users, often at twice the age of the developers. It’s one of the root causes of a lot of user frustration.

Writing Beautiful Code

Software developers care to little about beauty and elegance. We often stretch ourselves towards writing good unit tests and follow established object oriented best-practices. But we rarely think about how to make our architecture, design and code look beautiful. It’s not exactly in our nature, sort of speak.

As you can read in the excellent post on the same topic on the Creating Passionate Users blog:

“Because caring about things like beauty makes us better programmers and engineers. We make better things. Things that aren’t just functional, but easy to read, elegantly maintainable, easier–and more joyful–to use, and sometimes flat-out sexy. “

We should never forget that we rarely look at our own code more than once or twice, but eventually the code we write will be read by many others. It’s important to always recognize this fact and position ourselves in the minds of our fellow programmer.

Simplicity and Beauty

One of my mantra’s whenever I communicate with people through presentations and in my daily job, is to focus on simplicity. Making things simple is important, as a means to reduce complexity and improve communication.

Though it’s important to not forget about beauty and making things beautiful is similarly as hard as making things simple.

If you achieve simplicity and beauty you will be successful.

So from now on, try more to Code Like A Girl!

(This post is not meant to be sexist in any way, it’s a natural fact that females have a genetic advantage on beauty, one which we can learn from.)

Get your Code Like A Girl stuff from http://www.zazzle.com/code+like+a+girl+gifts.