Modify or Override the default t4 templates in MVC

When you create a new View or Controller in a mvc project. It is T4 templates to generate the piece of code for a new view or controller.

image

image

The templates are located in

C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\ItemTemplates\CSharp\Web\MVC 3

or

C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\ItemTemplates\CSharp\Web\MVC 3

We can bring these templates to our local project by dragging the “CodeTemplate” folder to Visusal Studio from Windows File Explorer.

image

You will see some compilation errors, these will be fixed after you have clear all the templates’ property “CustomTool”. Just clear the string out.

You can add your own templates as well. Next time when you add a new view, or controller, you will see the project is using your local templates to create them.

This is very helpful and I have Learned this trick from Scott Hanselman.

Here is the blog entry from him, if you want to read more about it.

http://www.hanselman.com/blog/ModifyingTheDefaultCodeGenerationscaffoldingTemplatesInASPNETMVC.aspx

Windows Live Writer, the best plugin to insert source code

I have been having problems for publishing blogs from WLW (Windows Live Writer) when there are source codes embedded into the blog. It is always formatted poorly or messed up in html.

Here is the syntax we need to use for WordPress to format our source codes.

image

And it doesn’t look right if I post the blog using WLW (Windows Live Writer), and I figure out I need to modify the codes in the source view.

image

It is quite annoying that I have to do this every time. I have tried a bunch of plugins from WLW and none of them works right for me. Until I found this ONE! http://richhewlett.com/wlwsourcecodeplugin/

What you need to do is, copy the codes from Visual Studio and paste into the plugin box. And configure a few settings. It will make it right for you. Problem solved!!!! HOOYA.

It is version 1.3.0, please download from here

Version 1.3.0  (Recommended)
More Details
Download Now

An extension method to create a SelectList, make your code neat & clean in MVC

When you have an IEnumerable model list bind to a select list items, you always need to write

var Items = Service.FindAll().Select(p => new SelectListItem() { Text = p.Name, Value = p.Id });

Here I create a extension method of IEnumerable<T> called “ToSelectList”,

    public static class SelectListExtensions
    {
        public static IEnumerable<SelectListItem> ToSelectList<T>(this IEnumerable<T> items,
            Func<T,string> text, Func<T,string> value = null, Func<T,Boolean> selected = null)
        {
            return items.Select(p => new SelectListItem
            {
                Text = text.Invoke(p),
                Value = (value==null? text.Invoke(p): value.Invoke(p)),
                Selected = selected == null? false: selected.Invoke(p)
            });
        }
    }

When you read the list from database and bind to a select list, you can write this way,

var Items = Service.FindAll().ToSelectList(p=>p.Name, p=>p.Id);

Extend the Razor view engine, MVC 3

I come cross a project that integrated a CMS publishing system into a MVC web application. The CMS content is published into an application folder. We don’t publish them into the View folder, or any of the MVC folders (controllers, models, content, etc.) is because we need to give write permission to the targeted folder. Due to the security reason, it is a better idea to publish to a particular folder and using our custom view engine to let controllers render them correctly.

Here I created a sample application for the demonstration purpose.

1. I create a folder call “StaticContent”, and we assume the CMS will publish contents to this folder. Then I created a few content files, like 101.cshtml, 102.cshtml, 103.cshtml.

image

Here you may notice, there are two files included in the folder, _ViewStart.cshtml and Web.config.

Because we want to make sure all the views in StaticContent folder are using the same layout. I copied the _ViewStart.cshtml file from “Views” folder into this folder. So when the controller will use the same _Layout.cshtml to render these views.

The web.config is copied from “Views” folder as well. Basically the purpose is to prevent access to your views by any means other than the controllers.

2. Create a “StaticPageViewEngine” class to implement RazorViewEngine

	public class StaticPageViewEngine : RazorViewEngine
	{
		public StaticPageViewEngine()
		{
base.ViewLocationFormats = base.ViewLocationFormats.Concat(new string[] { "~/StaticContent/{0}.cshtml" }).ToArray();
		}
	}

In the constructor, add the new location of the views in ViewLocationFormats. It is a string[], by default it has 4 values, after we added the new location, it becomes 5.

image

3. Next step is to register this view engine in Application_Start() in Global.asax.

protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();

RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);

ViewEngines.Engines.Add(new StaticPageViewEngine());

}

4. Create a controller and action method to render the views. And you can test it by going to “/Home/Test001”

public ActionResult Test001()
{
return View("101");
}

5. To make it dynamically rendered by a controller action method, we can register a special route in Global.asax

Global.asax

public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

// Static page
routes.MapRoute(
"Page", // Route name
"Page/{viewName}", // URL with parameters
new { lang = "en", controller = "Home", action = "StaticDetail" } // Parameter defaults
);

routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);

}

Controller method,

public class HomeController : Controller
{
//
// GET: /Home/

public ActionResult Index()
{
return View();
}

public ActionResult Test001()
{
return View("101");
}

public ActionResult StaticDetail(string viewName)
{

return View(viewName);

}
}

And it is all done. You can test all the static content views by using route “/Page/101”, “/Page/102”, etc.

The Sample source code can be downloaded from google code: https://extending-razor-view-engine.googlecode.com/svn/trunk/

Nuget commands to find packages and install them

I have been using Nuget in Visual Studio 2010, it is a time saver and make my life a lot easier.

To use Nuget, open visual studio 2010 => Tools => Library Package Manager => Package Manager Console.

So in the console, you can type your nuget shell commands to list available packages and install them to particular project.

To list packages,


PM> get-package –listavailable Elmah

You will get a list of available packages,

image

To install a package, (such as Elmah.MVC)

PM> install-package Elmah.MVC 

Nuget will install Elmah and its all dependencies. It also setup the settings in web.config

Isn’t that awesome!

For a full reference of Nuget shell commands, check out this link

http://docs.nuget.org/docs/reference/package-manager-console-powershell-reference

 

MVC mini profiler, a simple effective profiler for mvc

Use Nuget to download mini profilder,

install-package miniprofiler

To use it, start the profiler in Global.asax, Application_BeginRequest()

protected void Application_BeginRequest()

{

    if (Request.IsLocal)

    {

        MiniProfiler.Start();

    }

}

Write a condition to start the profiler, for Local Request, for special users, etc.

To use profiler for your code,

var profiler = MiniProfiler.Current; // it's ok if this is null

using (profiler.Step("Set page title"))
{
    for(int i=0;i<100;i++){

//do something

}

}

To display on the page, you need to include the profiler to _Layout.cshtml,

    @MvcMiniProfiler.MiniProfiler.RenderIncludes()

To end a profiler, end it in Global.asax, Application_EndRequest(),

protected void Application_EndRequest()

{

    MiniProfiler.Stop();

}