An application cache helper class

CacheHelper class contains a few methods with generic object parameter.  There are 4 methods, Add, Clear, Exists and Get.

You can pass in value pairs into Add method to add to application cache.

And retrieve it by using Get method by passing the string key.

    public static class CacheHelper
    {
        public static void Add(T o, string key, DateTime expiry) where T : class
        {
            HttpContext.Current.Cache.Insert(
                key,
                o,
                null,
                expiry,
                System.Web.Caching.Cache.NoSlidingExpiration);
        }

        public static void Add(T o, string key) where T : class
        {
            HttpContext.Current.Cache.Insert(
                key,
                o,
                null,
                DateTime.Now.AddHours(1),
                System.Web.Caching.Cache.NoSlidingExpiration);
        }

        public static void Clear(string key)
        {
            if (Exists(key))
                HttpContext.Current.Cache.Remove(key);
        }

        public static bool Exists(string key)
        {
            if (HttpContext.Current != null)
                return HttpContext.Current.Cache[key] != null;
            else
                return false;
        }

        public static T Get(string key) where T : class
        {
            try
            {
                return (T)HttpContext.Current.Cache[key];
            }
            catch
            {
                return null;
            }
        }

An example of using it,

I am reading the contract plans from repository and save into the application cache. Then check if it is in the cache before read the database again.

            const string key = "AllContractPlans";
            if (CacheHelper.Exists(key))
            {
                return CacheHelper.Get<List>(key);
            }
            else
            {
                var plans = _contractRepo.FindAll().ToList();
                CacheHelper.Add<List>(plans, key, DateTime.Now.AddMonths(2));
                return plans;
            }

Application cache can speed up you application, but please be mindful that cache is shared across the whole application. And the data in your database may change as well, in that case, you need to clear your cache when you modify you data against database.

FunnelWeb, a .NET MVC blog engine

I hope it will be something to fight against WordPress!!!

FunnelWeb is an open source blog engine, built by developers for developers. Instead of fancy quotes and oodles of widgets, we focus on letting you post beautiful code samples, keeping your markup clean and valid, and encouraging collaboration with rich comments. FunnelWeb is easy to install.

Download from : http://www.funnelweblog.com/

image

Create a MVC 3 web solution template – Part 3, Create a new solution using template

Create a new project from Visual Studio. Find your template from Visual C# templates.

image

It will ask you to configure to use IIS express

image

Because template contains no “packages” folders and the pre-installed nuget packages have no references. Project won’t compile.

Now right click solution and select “Enable Nuget Package Restore”

image

When you build your solution, packages will be downloaded and your nuget package references will be ok to resolve.

image

From time being, pre-installed nuget packages will have updates.

Right click Solution, select “Manage Nuget Packages for Solution…”

Select Updates Tab, to update packages

image

 

It is almost flawless, but….

You need to add project reference “Business”,”Data” to your “Web” project. And “Data” to your “Business” project.

———————————————————————

Download the sample vstemplate from http://mvc3projecttemplate.codeplex.com/

Create a MVC 3 web solution template – Part 2, Create VS template and grouping projects

From part 1, I have talked about my project template structure. Now I want to talk about how do I create the VS templates and group them into one solution.

Visual Studio only allow you to create a template from one single project. So we need to write some vstemplate scripts to group our projects all together into one solution. And save the below script as “Template.vstemplate”.

</pre>
<VSTemplate Version="3.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" Type="ProjectGroup">
 <TemplateData>
 <Name>Web MVC 3 Template</Name>
 <Description>MVC 3 web application template</Description>
 <ProjectType>CSharp</ProjectType>
 <TemplateGroupID>MyApplication</TemplateGroupID>
 <NumberOfParentCategoriesToRollUp>1</NumberOfParentCategoriesToRollUp>
 <SortOrder>1000</SortOrder>
 <CreateNewFolder>false</CreateNewFolder>
 <DefaultName>MVC3Application</DefaultName>
 <ProvideDefaultName>true</ProvideDefaultName>
 <LocationField>Enabled</LocationField>
 <Icon>__TemplateIcon.png</Icon>
 <PreviewImage>__PreviewImage.png</PreviewImage>
 <EnableLocationBrowseButton>true</EnableLocationBrowseButton>
 <PromptForSaveOnCreation>true</PromptForSaveOnCreation>
 <RequiredFrameworkVersion>4.0</RequiredFrameworkVersion>
 </TemplateData>
 <TemplateContent>
 <ProjectCollection>
 <ProjectTemplateLink ProjectName="$safeprojectname$.Business">
 Business.Template\MyTemplate.vstemplate
 </ProjectTemplateLink>
 <ProjectTemplateLink ProjectName="$safeprojectname$.Web">
 Web.Template\MyTemplate.vstemplate
 </ProjectTemplateLink>
 <ProjectTemplateLink ProjectName="$safeprojectname$.Data">
 Data.Template\MyTemplate.vstemplate
 </ProjectTemplateLink>
 </ProjectCollection>
 </TemplateContent>

</VSTemplate>
<pre>

If you use “Export Template” wizard from VS, export all projects from your solution, and unzip them into one folder.

image_thumb

In my example I have three projects, Data, Business and Web. Here is the folder structure.

image_thumb1

Now zip all the files and folders into one single package. Put it into your Visual Studio template folder.

{Documents}\Visual Studio 2010\Templates\ProjectTemplates

Or change your template location to your folder. Open VS -> Tools -> Options -> projects and solutions

image_thumb4

Now if you open VS and create a new project, you can find the template under C# projects.

—————————————————————————————–

Download the sample vstemplate from http://mvc3projecttemplate.codeplex.com/

Create a MVC 3 web solution template – Part 1, Create template projects

I am implementing a web application visual studio 2010 template at work. So it saves everyone’s time on a fresh start project. I decide to have 3 layers, presentation layer – web mvc3, business layer, and data access layer.

I have created a MVC3.WebTemplate solution with 3 projects, Business.Template , Data.Template and Web.Template. Let’s see what I have included in the three layers solution.

image

1. Web.Template

image

1.1 CodeTemplates

This folder contains the t4 templates to generate codes for views and controllers. I have included this in the project and it overrides the MVC default one. For more information, please read this blog https://kevww.wordpress.com/?s=t4+template

Have done this provides me ability to create my own t4 templates in the future, eg. in this template, I have modified the default template to make all controllers inherit a BaseController. When you create a new controller using the scaffolding template, it will create YourController : BaseController.

In the future I will create some view templates to make use of Twitter.Bootstrap and save you some time on styling the views.

1.2 Nuget Packages

I have included the latest packages for Jquery, Modernizr, Elmah, Ninject, Twitter.Bootstrap, etc.

<packages>
  <package id="elmah" version="1.2.0.1" />
  <package id="elmah.corelibrary" version="1.2.1" />
  <package id="Elmah.MVC" version="1.3.2" />
  <package id="EntityFramework" version="4.3.0" />
  <package id="jQuery" version="1.7.1" />
  <package id="jQuery.UI.Combined" version="1.8.17" />
  <package id="jQuery.Validation" version="1.9" />
  <package id="jQuery.vsdoc" version="1.6" />
  <package id="Microsoft.Web.Infrastructure" version="1.0.0.0" />
  <package id="Modernizr" version="1.7" />
  <package id="Ninject" version="2.2.1.4" />
  <package id="Ninject.MVC3" version="2.2.2.0" />
  <package id="Twitter.Bootstrap" version="2.0.0" />
  <package id="WebActivator" version="1.4.4" />
</packages>

Of course, you know Nuget will download all the packages in a Package folder in your solution folder. You don’t need to include those files into your template. You can easily restore the Nuget packages to a new solution thsi is created from the template.

image

2. Business.Template

image

Not much to talk about for this project, really it should contain all your business logics.

3. Business.Template

image

3.1 DataContext

For data access, I am using EntityFramework 4.3. I have included a empty context edmx file with t4 templates to generate DbContext & POCOs.

If you want do CodeFirst, you can remove my stuff under Data folder and put your POCOs there.

3.2 Repositories

I have included a generic base repository. To help you start building your repositories. It has the default CRUD operation methods which you can inherit from.

————————————————————————————-

This is all about my project template, please refer to blog part 2 for the VS Template Creation.

Download the sample vstemplate from http://mvc3projecttemplate.codeplex.com/

Using Ninject in MVC 3

Previously I have chatted about how to use Structured Map and Unity for Dependency Injections. Here is the link

https://kevww.wordpress.com/tag/dependency-injection/

Today I am going to discuss how to use Ninject for your DI container.

First of all, let’s add Ninject and Ninject.MVC3 to our web application using Nuget. Here is the command you can use to install them in Package Manager Console in VS2010.

PM> Install-Package Ninject

PM> Install-Package Ninject.MVC3 -Version 2.2.2.0

Then let’s get started. And modify the Global.asax to use NinjectHttpApplication instead of HttpApplication. It overrides CreateKernel to create a kernel and load all the modules.

public class MvcApplication : NinjectHttpApplication
{
   public static void RegisterGlobalFilters(GlobalFilterCollection filters)
   {
       filters.Add(new HandleErrorAttribute());
   }
 
   public static void RegisterRoutes(RouteCollection routes)
   {
       routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
 
       routes.MapRoute(
           "Default", // Route name
           "{controller}/{action}/{id}", // URL with parameters
           new
           {
               controller = "Home",
               action = "Index",
               id = UrlParameter.Optional
           });
   }
 
   protected override IKernel CreateKernel()
   {
       var kernel = new StandardKernel();
       kernel.Load(Assembly.GetExecutingAssembly());
       return kernel;
   }
 
   protected override void OnApplicationStarted()
   {
       base.OnApplicationStarted();
 
       AreaRegistration.RegisterAllAreas();
       RegisterGlobalFilters(GlobalFilters.Filters);
       RegisterRoutes(RouteTable.Routes);
   }
}

The only thing that has to be done is to add dependencies for controller constructor and configure the Ninject bindings for its dependencies. The controller itself will be found by Ninject even without adding a binding.

public class HomeController : Controller
{
    private readonly IWelcomeMessageService welcomeMessageService;
 
    public HomeController(IWelcomeMessageService welcomeMessageService)
    {
        this.welcomeMessageService = welcomeMessageService;
    }
 
    public void Index()
    {
        ViewModel.Message = this.welcomeMessageService.TodaysWelcomeMessage;
        return View();
    }
}
 
public class WelcomeMessageServiceModule : NinjectModule
{
    public override void Load()
    {
         this.Bind().To();
    }
}

Ninject provides contextual bindings. It allows you to register more than one binding for a type. There are 3 ways.

1. add condition to the bindings.

interface ICondition {
  bool Matches(T obj);
}

Bind().To();
Bind().To().Only(When.Context.Service.Name.StartsWith("Foo"));

2. Create Attribute

public class RangeAttribute : Attribute {}

public class Swordsman {
  [Inject] public IWeapon Weapon { get; set; }
}

public class Ninja {
  [Inject] public IWeapon MeleeWeapon { get; set; }
  [Inject, Range] public IWeapon RangeWeapon { get; set; }
}

3. Create Tags

public class Ninja {
  [Inject] public IWeapon MeleeWeapon { get; set; }
  [Inject, Tag("range")] public IWeapon RangeWeapon { get; set; }
}

Bind().To();
Bind().To().Only(When.Context.Tag == "range");

Here are some references you can read more about Ninject.

http://www.planetgeek.ch/2010/11/13/official-ninject-mvc-extension-gets-support-for-mvc3/ ( This blog post shows you how to use Ninject for Attribute bindings.)

http://bradwilson.typepad.com/blog/2010/07/service-location-pt4-filters.html

http://ninject.codeplex.com/wikipage?title=User%20Guide&referringTitle=Home (Ninject Home)

EntityFramework 4.1 Extensions for batch Delete and Update

A great library that extends the functionality of EF. It provides the features to do batch updates, delete and future queries and audit log.

PM> Install-Package EntityFramework.Extended

Use the Package Manager Console in VS2010 to install it. And you can find the source in Github.

http://nuget.org/packages/EntityFramework.Extended

https://github.com/loresoft/EntityFramework.Extended

Make sure you import the Extensions namespace. Then you will see the extension methods of batch delete/update. Here are a few lines of code to demonstrate how to delete, update.

using EntityFramework.Extensions;

context.Users.Delete(u => u.FirstName == "firstname");

context.Tasks.Update(
    t => t.StatusId == 1, 
    t => new Task {StatusId = 2});
 

For future query usage, you can use an IQueryable as the filter for the update


var users = context.Users
   .Where(u => u.FirstName == "firstname");

context.Users.Update(
   users, 
   u => new User {FirstName = "newfirstname"})

Pretty cool is it! To read more documentations go to the github site. https://github.com/loresoft/EntityFramework.Extended

A JQuery plugin for OpenID selector & DotNetOpenAuth integration in MVC

JQuery OpenId selector can be downloaded here http://code.google.com/p/openid-selector/

DotNetOpenAuth can be downloaded here http://www.dotnetopenauth.net/ or install using Nuget  http://nuget.org/packages/DotNetOpenAuth/3.4.7.11121

PM> Install-Package DotNetOpenAuth -Version 3.4.7.11121

Here is what the JQuery openId selector looks, and there are two files you can configure: openId-en.js & openid-jquery.js

OpenID selector

To modify the UI, in openid-en.js, change the variable of “providers_large” and “providers_small” to make your own look and feel.

To modify the settings of this plugin, such as image path, cookie name, etc. Open openid-jquery.js, it is in the openid definition section.

openid = {
	version : '1.3', // version constant
	demo : false,
	demo_text : null,
	cookie_expires : 6 * 30, // 6 months.
	cookie_name : 'openid_provider',
	cookie_path : '/',

	img_path : '../openid/images/',
	locale : null, // is set in openid-.js
	sprite : null, // usually equals to locale, is set in
	// openid-.js
	signin_text : null, // text on submit button on the form
	all_small : false, // output large providers w/ small icons
	no_sprite : false, // don't use sprite image
	image_title : '{provider}', // for image title

	input_id : null,
	provider_url : null,
	provider_id : null,

In the MVC View, you need to have


    $(document).ready(function () {
        openid.init('openid_identifier');
    });

    function facebook_click() {
        alert("wwaaa");
    }


@using (Html.BeginForm("Login", "Account", new {ReturnUrl = Request.QueryString["ReturnUrl"] },FormMethod.Post, new { id = "openid_form" }))
{     <input type="hidden" name="action" value="verify" />
	<fieldset>
		<legend>Sign-in or Create New Account</legend>
		<div id="openid_choice">
			<p>Please click your account provider:</p>
			<div id="openid_btns"></div>
		</div>
		<div id="openid_input_area">
			<input id="openid_identifier" name="openid_identifier" type="text" value="http://" />
			<input id="openid_submit" type="submit" value="Sign-In"/>
		</div>
		<noscript>
			<p>OpenID is service that allows you to log-on to many different websites using a single indentity.
			Find out <a href="http://openid.net/what/">more about OpenID</a> and <a href="http://openid.net/get/">how to get an OpenID enabled account</a>.</p>
		</noscript>
	</fieldset>
}

In the controller, we need to have Login & Register action methods using DotNetOpenAuth to implement the authentication process.

[AcceptVerbs(HttpVerbs.Post | HttpVerbs.Get), ValidateInput(false)]
        public ActionResult Login(string openid_identifier, string returnUrl)
        {
            var response = _openId.GetResponse();
            if (response == null)
            {
                if (string.IsNullOrEmpty(openid_identifier))
                    return View();
                return SendRequestToOpenIdProvider(openid_identifier);
            }
            else 
            {
                switch (response.Status)
                {
                    case AuthenticationStatus.Authenticated:
                        string identifier = response.ClaimedIdentifier;

                        var user = _userRepo.GetUser(identifier);
                        if (user != null)
                        {
                            IssueFormsAuthenticationTicket(user);
                            if (string.IsNullOrEmpty(returnUrl))
                                return RedirectToAction("Index", "Home");
                            else
                                return Redirect(returnUrl);
                        }
                        else
                        {
                            var registrationModel = new RegistrationViewModel(identifier)
                            {
                                ReturnUrl = returnUrl
                            };
                            var simpleReg = response.GetExtension();
                            if (simpleReg != null)
                            {
                                if (!string.IsNullOrEmpty(simpleReg.Email))
                                    registrationModel.Email = simpleReg.Email;

                                if (!string.IsNullOrEmpty(simpleReg.FullName))
                                    registrationModel.FullName = simpleReg.FullName;

                                if (!string.IsNullOrEmpty(simpleReg.Nickname))
                                    registrationModel.Username = simpleReg.Nickname;
                            }
                            return View("Register", registrationModel);
                        }
                    case AuthenticationStatus.Canceled:
                        ModelState.AddModelError("openid_identifier", "Authetication canceled");
                        break;
                    case AuthenticationStatus.Failed:
                        ModelState.AddModelError("openid_identifier", "Authetication failed");
                        break;
                }
            }
            return View();
        }

        public ActionResult Register()
        {
            return RedirectToAction("Login");
        }

        [HttpPost]
        public ActionResult Register(User user, string identifier, string returnUrl)
        {
            //The registration form has been submitted
            try
            {
                if (ModelState.IsValid)
                {
                    var feed = _feedRepo.Create(new Feed(){
                        Id = Guid.NewGuid(),
                        Name = "Default"
                    });
                    user.OpenId = identifier;
                    user.ApiKey = Guid.NewGuid();
                    user.FeedUsers.Add(new FeedUser(){
                        IsOwner = true,
                        FeedId = feed.Id
                    });
                    _userRepo.Create(user);

                    // Now let's login out user to out application
                    IssueFormsAuthenticationTicket(user);

                    // We're done, let's get back to where we started from.
                    if (string.IsNullOrEmpty(returnUrl))
                        return RedirectToAction("Index", "Home");
                    else
                        return Redirect(returnUrl);
                }

                var registrationModel = new RegistrationViewModel(identifier)
                {
                    Username = user.Username,
                    Email = user.Email,
                    FullName = user.FullName,
                    ReturnUrl = returnUrl
                };

                return View(registrationModel);
            }
            catch
            {
                var registrationModel = new RegistrationViewModel(identifier)
                {
                    Username = user.Username,
                    Email = user.Email,
                    FullName = user.FullName,
                    ReturnUrl = returnUrl
                };

                return View(registrationModel);
            }
        }

A complete example can be downloaded at https://github.com/gligoran/mvcopenid

Implement dynamic service route for WCF, just like what you do in MVC

Implementing an MVC-style route for WCF

Let’s call this thing DynamicServiceRoute. The goal of it will be to achieve a working ServiceRoutewhich supports route data and which allows you to create service routes of the format “MyService/{mycustomdata}”, like you would do in ASP.NET MVC.

First of all, let’s inherit from RouteBase and IRouteHandler. No, not from ServiceRoute! The latter is so closed that it’s basically a no-go if you want to extend it. Instead, we’ll wrap it! Here’s the base code for our DynamicServiceRoute:

    public class DynamicServiceRoute
        : RouteBase, IRouteHandler
    {
        private string virtualPath = null;
        private ServiceRoute innerServiceRoute = null;
        private Route innerRoute = null;

        public static RouteData GetCurrentRouteData()
        {
            if (HttpContext.Current != null)
            {
                var wrapper = new HttpContextWrapper(HttpContext.Current);
                return wrapper.Request.RequestContext.RouteData;
            }
            return null;
        }

        public DynamicServiceRoute(string pathPrefix, object defaults, ServiceHostFactoryBase serviceHostFactory, Type serviceType)
        {
            if (pathPrefix.IndexOf("{*") >= 0)
            {
                throw new ArgumentException("Path prefix can not include catch-all route parameters.", "pathPrefix");
            }
            if (!pathPrefix.EndsWith("/"))
            {
                pathPrefix += "/";
            }
            pathPrefix += "{*servicePath}";

            virtualPath = serviceType.FullName + "-" + Guid.NewGuid().ToString() + "/";
            innerServiceRoute = new ServiceRoute(virtualPath, serviceHostFactory, serviceType);
            innerRoute = new Route(pathPrefix, new RouteValueDictionary(defaults), this);
        }

        public override RouteData GetRouteData(HttpContextBase httpContext)
        {
            return innerRoute.GetRouteData(httpContext);
        }

        public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
        {
            return null;
        }

        public System.Web.IHttpHandler GetHttpHandler(RequestContext requestContext)
        {
            requestContext.HttpContext.RewritePath("~/" + virtualPath + requestContext.RouteData.Values["servicePath"], true);
            return innerServiceRoute.RouteHandler.GetHttpHandler(requestContext);
        }
    }

GetRouteData is used by the routing engine to check if a route matches. We just pass that call to the inner route which is able to handle this. GetVirtualPath will not be important here, so simply return null there. If you really really feel this is needed, it would require some logic that creates a URL from a set of route data. But since you’ll probably never have to do that, null is good here. The most important thing here is GetHttpHandler. It is called by the routing engine to get a HTTP handler for a specific request context if the route matches. In this method, I simply rewrite the requested URL to the internal, ugly “MyServiceNamespace.MyServiceType-guid” URL and ask the inner ServiceRoute to have fun with it and serve the request. There, the magic just happened.

Register it in your Global.asax file

            var factory = new DataServiceHostFactory();
            RouteTable.Routes.Add(new DynamicServiceRoute("nuget/{customername}", null, factory, typeof(Packages)));

Reference:  http://blog.maartenballiauw.be/post/2011/05/09/Using-dynamic-WCF-service-routes.aspx

Setup a private Nuget server, host your own Nuget feed

Before I start talking about how to create a private Nuget server, I need to show you how do you create a Nuget package by yourself.

To create a Nuget package, you can either use Nuget.exe command line tool to do it, or use Nuget Package Explorer. Nuget Package Explorer provides the nice neat interface to allow you create a nuget package without any knowledge of command-lines syntax. To download them both, from

http://nuget.codeplex.com/releases/view/58939 (Nuget.exe)

http://nuget.codeplex.com/releases/view/59864 (Nuget Package Explorer)

After you have created your own packages, you can now setup the private Nuget feed.

1. Create a web application in Visual Studio. I am using MVC as my Nuget server application.

2. Install “NuGet.Server” package from “Package Manager Console”.

3. Configure the package folders and ApiKey

  <appSettings>
    <add key="webpages:Version" value="1.0.0.0" />
    <add key="ClientValidationEnabled" value="true" />
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />
    <add key="apiKey" value="1234" />
    <add key="packagesPath" value="C:\MyLocalNugetFeed" />
  </appSettings>

4. Deploy your application to IIS. And you server is running.

To view the feed and download packages.

Right click “Reference” folder of your project, Click “Manage Nuget Packages”.

image

Then add “http://youdomain.com/nuget” as your feed address.

Adding new feed to package sources

You will be able to see your feeds in the list.

To publish a package

You can use Nuget Package Explorer or Nuget.exe.

Nuget.exe

image

Nuget Package Explorer, enter your publish Url and ApiKey then click Publish.

image

What are you waiting for to get your own Nuget feed and share code snippets or libraries with your mates!!

Here are some reference links may help you.

http://docs.nuget.org/docs/creating-packages/hosting-your-own-nuget-feeds

http://docs.nuget.org/docs/reference/command-line-reference