Main Contents

Dynamic Dot Less Css With Asp.net MVC 2

Schotime @ July 2, 2010

.NET | Comments (5)

I have been having a look at the best way to theme a asp.net mvc website in the last few weeks. I heard about dot less css late last year but hadn’t had time to integrate it into a project until now.

Integrating dot less css is pretty easy by default, as shown on its home page however I wanted something that could be configured by application users. We want to be able to specify the link html tag like the following.

<link href="/public/css/sites.less" rel="stylesheet" type="text/css" />

There are few steps involved in the solution I have come up with so bare with me as I go through them. Firstly we’ll start with the web.config:

        <compilation>
            <buildProviders>
                <add extension=".lessx" type="System.Web.Compilation.PageBuildProvider" />
            </buildProviders>
        </compilation>

Insert the builderProviders block inside the compilation section. The compilation section will be under the system.web section. This will enable us to use code blocks in our lessx files.

Secondly, is the routing.

        //Special Route for css so that images are relative to it
        routes.MapRoute("css",
                           "public/css/{filename}.less",
                           new { controller = "Css", action = "Index” },
                           new[] { "eLearning.Controllers" });

This specifies that any url matching /public/css/{filename}.less should be routed to the CssController passing the filename as the parameter to the Index method.

    public class CssController : BaseController
    {
        [OutputCache(Duration = 10, VaryByParam = "")]
        public ActionResult Index(string filename)
        {
            if (string.IsNullOrEmpty(filename))
                throw new ArgumentException("A filename must be supplied");

            ViewData["baseColor"] = "#aabbcc";

            var less = RenderViewToString(filename + ".lessx", null);
            var css = LessCss.Generate(less, true);
            return Content(css, "text/css");
        }
    }

    public static class LessCss
    {
        public static string Generate(string less, bool minify)
        {
            var lessEngine = new EngineFactory();
            lessEngine.Configuration.MinifyOutput = minify;
            var output = lessEngine.GetEngine().TransformToCss(less, null);
            return output;
        }
    }

This is the css controller class. It receives the filename as the input, finds the corresponding .lessx file and returns the file with appropriate view data replaced. Is then takes the less formatted string and runs it through the dot less parser to return a css string. This is then returned to the browser with the appropriate content-type. One method I have not shown is the RenderViewToString() and how the .lessx file is located. This method is located on the base controller class that the css controller inherits from. I have also turned Caching on so that it will cache the result for 10seconds.

        protected string RenderViewToString(string viewName, object model)
        {
            if (string.IsNullOrEmpty(viewName))
                viewName = ControllerContext.RouteData.GetRequiredString("action");

            ViewData.Model = model;

            using (StringWriter sw = new StringWriter())
            {
                ViewEngineResult viewResult = ViewEngines.Engines.FindView(ControllerContext, viewName, null);
                ViewContext viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
                viewResult.View.Render(viewContext, sw);

                return sw.GetStringBuilder().ToString();
            }
        }


This method finds the .lessx file and returns the result as a string. Now usually the view engine will take controller name and method name and by convention look in the /Views/css/index.aspx file. It doesn’t quite make sense to put it in the views folder so I have overridden the default web forms view engine so that they can be placed in the /Public/Css folder. This can be configured to your liking (convention).

    public class CustomViewEngine : WebFormViewEngine
    {
        public CustomViewEngine()
        {
            var locs = new List<string>(base.ViewLocationFormats);
            locs.Add("~/Public/{1}/{0}"); //My personal choice
            locs.Add("~/Views/{1}/{0}");  //An alternative choice
            base.ViewLocationFormats = locs.ToArray();
        }
    }

Once your Custom View Engine has been overridden, you will need to add it to the ViewEngines.Engines collection in the application start method in the global.asax.cs.

        ViewEngines.Engines.Clear();
        ViewEngines.Engines.Add(new CustomViewEngine());

This will then allow us to write a *.lessx file like the following; you can also pass a strongly typed model to the .lessx file if you so wish in the same way you would to a regular aspx view.

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %>

@basecolor: <%= ViewData["baseColor"] %>;

body {
    background: @basecolor;
}

Which will be rendered to the browser as:

body {
    background: #aabbcc;
}

And that’s it. I’m still working on the finer details but I am liking how it works at the moment. If you have any thoughts or suggestions, please leave a comment.

Adam


book mark Dynamic Dot Less Css With Asp.net MVC 2 in del.icio.us submit Dynamic Dot Less Css With Asp.net MVC 2 to digg.com


NoRM, MongoDb and Complex Queries

Schotime @ May 14, 2010

.NET | Comments (2)

In my last post I told you about how you can use Regular Expressions to do complex queries in mongodb. In this post I will show you some more features of the Linq Provider.
Updated: 16th May 2010 after some feedback
Take these two classes for example:

public class User
[...]


book mark NoRM, MongoDb and Complex Queries in del.icio.us submit NoRM, MongoDb and Complex Queries to digg.com


NOSQL, NoRM (mongoDB) and Regular Expressions

Schotime @ April 29, 2010

.NET | Comments (1)

Over the past few weeks I have got quite involved in the development of the Open Source NoRM project started by Andrew Theken which is a MongoDB driver for C#. In particular I have been refactoring and adding new functionality to the LINQ provider.
It currently supports a lot of functionality including deep queries, regex, datetime [...]


book mark NOSQL, NoRM (mongoDB) and Regular Expressions in del.icio.us submit NOSQL, NoRM (mongoDB) and Regular Expressions to digg.com


Poor sound performance on the Asus U80V

Schotime @ January 17, 2010

Misc | Comments (1)

I just got hold of a new laptop. The Asus U80V. So far i have been pretty happy with it except for one thing. The sound was horrible. It was tinny, with poor range even for a laptop. I remember my laptop from 1998 having better audio than this was exhibiting.
Naturally I went looking for [...]


book mark Poor sound performance on the Asus U80V in del.icio.us submit Poor sound performance on the Asus U80V to digg.com


FluentValidation Xval Integration

Schotime @ June 13, 2009

.NET | Comments (4)

After a few months of using FluentValidation I asked its author Jeremy Skinner if it were possible to integrate this with xVal. At that time it was not possible because there were no easy way to access the properties needed by xVal. After submitting a few patches, we now have a solution which enables xVal [...]


book mark FluentValidation Xval Integration in del.icio.us submit FluentValidation Xval Integration to digg.com


Fluent Validation Model Binder – Asp.net MVC

Schotime @ May 11, 2009

.NET | Comments (2)

A few weeks ago I found the Fluent Validation framework by Jeremy Skinner. I needed to conditionally validate a model depending on an application setting. eg. Description field mandatory / not mandatory depending on the clients business requirements. I loved the simplicity of the framework and the separation from the model it provided.
Since then I [...]


book mark Fluent Validation Model Binder – Asp.net MVC in del.icio.us submit Fluent Validation Model Binder – Asp.net MVC to digg.com


Integrating xVal Validation with Linq-to-Sql

Schotime @ March 31, 2009

.NET | Comments (0)

In a previous post I showed you how you can use xVal and the IDataErrorInfo class to add validation to your Asp.net MVC website. In this post I will extend that to Linq-to-Sql and the classes it generates.
The northwind database has a suppliers table. The info contained below is using that table with linq-to-sql.
After [...]


book mark Integrating xVal Validation with Linq-to-Sql in del.icio.us submit Integrating xVal Validation with Linq-to-Sql to digg.com


Custom Validation Attributes

Schotime @ March 11, 2009

.NET | Comments (0)

In my last post I showed you how to use Validation attributes on your model for validation. Today I will show how you can create your own attributes that can provide custom validation for you.
To accomplish this we need to inherit from ValidationAttribute. We’ll create an attribute today that will only [...]


book mark Custom Validation Attributes in del.icio.us submit Custom Validation Attributes to digg.com


Validation with Asp.net MVC, xVal & IDataerrorInfo

Schotime @ March 5, 2009

.NET | Comments (8)

I’ve been playing around with lots of different Validation concepts recently and I think I have come up with something that will be very useful. Hopefully you will also find it useful.
Firstly I have been looking at Steve Sanderson’s new open source project xVal and decided that it was a good place to start. I [...]


book mark Validation with Asp.net MVC, xVal & IDataerrorInfo in del.icio.us submit Validation with Asp.net MVC, xVal & IDataerrorInfo to digg.com


Custom Authorization With Asp.net MVC

Schotime @ February 17, 2009

.NET | Comments (14)

The whole advantage with MVC over webforms is extensibility at every point. Extensibility, Extensibility, Extensibility.
Authorization is a very important and every web project has there own needs and requirements. Full customisation is paramount.
Here I will show you a simple way to customise your authorization.
In MVC attributes are used to protect a controller method, so we [...]


book mark Custom Authorization With Asp.net MVC in del.icio.us submit Custom Authorization With Asp.net MVC to digg.com



Feed
6,652 spam comments
blocked by
Akismet