Thursday, 18 August 2011

MVC3 tips and practices 3 – EF Code First and Database Initializer


In this article, I’ll explain how to implement sample BlogContext for EF Code First DbContext and database initializer setting.

Web.config connection setting

Let’s change the connectionStrings section of Web.config file. At default, we will use SqlCE for our database. We also change easily MS-SQL database by changing connection string below.

  <connectionStrings>
    <!--<add name="BlogContext"
         connectionString="Data Source=localhost;
         Initial Catalog=MvcBlog; 
         Persist Security Info=True;
         User ID=sa;Password=12345;"
         providerName="System.Data.SqlClient" />-->
    <add name="BlogContext" 
         connectionString="data source=|DataDirectory|\MvcBlog.sdf"
         providerName="System.Data.SqlServerCe.4.0" />
  </connectionStrings>

Model and DbContext Definition

For simple blog system, let’s design three model classes.

    public class Post
    {
        public int Id { get; set; }
        [Required][MaxLength(128)]
        public string UserName { get; set; }
        [Required][MaxLength(128)]
        public string Title { get; set; }
        [MaxLength(256)]
        public string ImageUrl { get; set; }
        [Required][MaxLength(256)]
        public string Summary { get; set; }
        [Required]
        public string Content { get; set; }
        public int CommentCount { get; set; }
        public DateTime DateCreated { get; set; }
        public virtual ICollection<Comment> Comments { get; set; }
        public virtual ICollection<Term> Terms { get; set; }
    }

    public class Comment
    {
        public int Id { get; set; }
        [MaxLength(128)]
        public string UserName { get; set; }
        [MaxLength(128)]
        public string Author { get; set; }
        [MaxLength(128)]
        public string AuthorEmail { get; set; }
        [MaxLength(256)]
        public string AuthorUrl { get; set; }
        [MaxLength(128)]
        public string AuthorIp { get; set; }
        [Required]
        public string Content { get; set; }
        public DateTime DateCreated { get; set; }
        public Nullable<int> ParentCommentId { get; set; }
        public virtual Comment Parent { get; set; }
        public int PostId { get; set; }
        public virtual Post Post { get; set; }
        public virtual ICollection<Comment> Children { get; set; }
    }

    public class Term
    {
        public int Id { get; set; }
        [Required][MaxLength(128)]
        public string Name { get; set; }
        public bool IsClip { get; set; }
        [Required][MaxLength(256)]
        public string Summary { get; set; }
        public Nullable<int> ParentTermId { get; set; }
        public virtual Term Parent { get; set; }
        public virtual ICollection<Term> Children { get; set; }
        public virtual ICollection<Post> Posts { get; set; }
    }

Let’s define BlogContext by inheriting DbContext of EF 4.1.

    public class BlogContext : DbContext
    {
        public IDbSet<Post> Posts { get; set; }
        public IDbSet<Comment> Comments { get; set; }
        public IDbSet<Term> Terms { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
        }
    }

Let’s create BlogDataInitializer class for default data setup.

    public class BlogDataInitializer : DropCreateDatabaseIfModelChanges<BlogContext>
    {
        protected override void Seed(BlogContext context)
        {

            var terms = new List<Term>
            {
                new Term { Name = ".NET", Summary = ".NET Summary" },
                ...
            };

            var posts = new List<Post>
            {
                new Post { UserName = "user1", Title = "MVC3 Overview", Summary = "Summary 1", Content = "Writing 1", 
                    DateCreated = DateTime.Parse("2005-09-01"),Terms = new List<Term>{ terms[0], terms[1]}},
                ...
            };

            terms.ForEach(t => context.Terms.Add(t));
            posts.ForEach(p => context.Posts.Add(p));

        }
    }

Register BlogDataInitializer class to Global.asax

        protected void Application_Start()
        {
            ...
            Database.SetInitializer(new BlogDataInitializer());
        }

Running for test

Let’s add List action method to HomeController to quick test.

 

    public class HomeController : Controller
    {

        private readonly BlogContext context = new BlogContext();

        public ActionResult List()
        {
            var list = context.Posts.ToList();
            return View(list);
        }

        ...
    }
OK. Let’s check the result.

3

We can see full featured database schema including self referencing relation and auto generated many to many mapping table called ‘TermPost’.

4

Conclusion

Through the EF Code First and Database Initializer, we can always setup easily our default database and data records.

Continue reading >>

MVC3 tips and practices 2 – Unity Ioc and per http request lifetime


Current Unity Ioc container doesn't provide per http request dispose function. Unity.MVC3 component provides this function as follows:

“This project includes a bespoke DependencyResolver that creates a child container per HTTP request and disposes of all registered IDisposable instances at the end of the request.” from the project site(http://unitymvc3.codeplex.com/ ).

Setup Unity.MVC3 and Unity 2.0 from NuGet

Let’s start to call NuGet reference window.

1

Let’s input search word ‘Unity’ on Online tab and click Install button to add reference of Unity 2.x and Unity.Mvc3 libraries.

2

Glbal.asax snippet for Bootstrapper

Let’s open Global.asax file and add calling snippet of the Unity.MVC3 Bootstrapper initializer.

    public class MvcApplication : System.Web.HttpApplication
    {
        ...
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

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

            Bootstrapper.Initialise();
        }
    }
We can register types with “new HierarchicalLifetimeManager()” parameter option to set disposable flag after per HTTP Request.
    public static class Bootstrapper
    {
        ...

        private static IUnityContainer BuildUnityContainer()
        {
            var container = new UnityContainer();

            // register all your components with the container here
            // e.g. container.RegisterType<ITestService, TestService>();            
            container.RegisterType<IUpperCaseService, UpperCaseService>();
            container.RegisterType<ILowerCaseService, LowerCaseService>();
            container.RegisterType<IExampleContext, ExampleContext>(
                new HierarchicalLifetimeManager());

            ...
        }
    }

Conclusion

We can dispose exactly our disposable object like DbContext after every HTTP Request through this

Continue reading >>

Wednesday, 17 August 2011

MVC3 tips and practices 1 – Razor, Layout


I’ll explain several hidden and practical tips and practices for ASP.Net MVC3 based on my recent experience and some web resources. In this post, I’ll show you how to handle Razor view and layout clear.

Namespace setting for Razor pages in Web.config

In Web.config file under Your MVC3 project > Views, we can add some additional default namespaces for Razor pages. Please close all Razor pages of your project if you want check it works.

  <system.web.webPages.razor>
    <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    <pages pageBaseType="System.Web.Mvc.WebViewPage">
      <namespaces>
        <add namespace="System.Web.Mvc" />
        <add namespace="System.Web.Mvc.Ajax" />
        <add namespace="System.Web.Mvc.Html" />
        <add namespace="System.Web.Routing" />
        <add namespace="Shuffle.Web" />
      </namespaces>
    </pages>
  </system.web.webPages.razor>

Optional javascript files reference to Layout page

First, let’s add a helper method to generate javascript file reference string as follows.

    public static class Content
    {
        public static MvcHtmlString Script(string scriptName, UrlHelper url)
        {
            string path = string.Format("<script src=\"{0}\" type=\"text/javascript\"></script>", url.Content("~/Scripts/" + scriptName));
            return MvcHtmlString.Create(path);
        }
    }

Open Views > Chared > _Layout.cshtml file and add script reference code lines at the bottom section.

@Content.Script("jquery-1.5.1.min.js", Url)
@Content.Script("MvcBlog.js", Url)
@RenderSection("Script", false)
</body>
</html>

In any Razor page we want to add javascript reference optionally, let’s add following section code.

@model MvcBlog.Models.Post

@{
    ViewBag.Title = "Edit";
}

@section Script{
    @Content.Script("jquery.validate.min.js",Url)
    @Content.Script("jquery.validate.unobtrusive.min.js", Url)
}

Continue reading >>

Tuesday, 19 April 2011

JQuery Accordion Plug-in integration to the MVC3 Razor View


JQuery provides rich UI assets including great Accordion ui plug-in. By using the plug-in, we can make n-depth dynamic menu UI easily. In this post, I will explain how to implement the Accordion based 2-depth menu UI to the MVC3 Razor View with automatic highlighting and selecting functions.

JQuery UI and Accordion widget

Let’s visit http://jqueryui.com/ homepage and http://jqueryui.com/demos/accordion/ to see the demo of Accordion widget. You can download minimized light zipped package for your customized usage. In this post, we will use default jquery-ui package in default MVC3 template project.

Layout Update

Let’s open the _Layout.cshtml master page and add jquey-ui resource files reference.

...
<head>
...
    <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" media="screen"/>
    <script src="@Url.Content("~/Scripts/jquery-1.4.4.min.js")" type="text/javascript"></script>
    <link href="@Url.Content("~/Content/themes/base/jquery-ui.css")" rel="stylesheet" type="text/css" media="screen"/>
    <script src="@Url.Content("~/Scripts/jquery-ui.min.js")" type="text/javascript"></script>
...
</head>
Then, let’s add init JQuery function for Accordion widget.
<head>
...
	<script type="text/javascript">
	    $(function () {
	        $("#accordion").accordion({
	            active: 'h2.menu@(Html.Controller())'
	        });
	    });
	</script>
</head>

Accordion function initializer provides several parameters for dynamic effects. We added active property to display initial selected menu section that matched with current controller name like menuHome or menuPost.

Let’s check real menu item data list.

                <div id="accordion">
                    <h2 class='menuHome'><a href="#">Home</a></h2>
				        <ul class="menulist">
                            @Html.MenuItem("Welcome", "Index", "Home","selected")
                            @Html.MenuItem("LogOn", "LogOn", "Account","selected")
                            @Html.MenuItem("About", "About", "Home","selected")
                            @Html.MenuItem("Sitemap", "Sitemap", "Home", "selected")
				        </ul>
                    <h2 class='menuPost'><a href="#">Post Manager</a></h2>
				        <ul class="menulist">
                            @Html.MenuItem("Post List", "Index", "Post","selected")
                            @Html.MenuItem("Create", "Create", "Post","selected")
				        </ul>
                </div>

We implement Html.MenuItem helper method based on  my prior post.

namespace JQueryAccordionMVC3.Common
{
    public static class HtmlExtensions
    {
        public static MvcHtmlString MenuItem(this HtmlHelper helper, string linkText,
            string actionName, string controllerName, string selectedClass)
        {
            return MenuItem(helper, linkText, actionName, controllerName, selectedClass, false);
        }

        public static MvcHtmlString MenuItem(this HtmlHelper helper, string linkText, 
            string actionName, string controllerName, string selectedClass, bool controllerDesplay)
        {
            string currentControllerName = (string)helper.ViewContext.RouteData.Values["controller"];
            string currentActionName = (string)helper.ViewContext.RouteData.Values["action"];

            var builder = new TagBuilder("li");
            if (controllerDesplay)
            {
                if (currentControllerName.Equals(controllerName, StringComparison.CurrentCultureIgnoreCase))
                    builder.AddCssClass(selectedClass);
            }
            else
            {
                if (currentControllerName.Equals(controllerName, StringComparison.CurrentCultureIgnoreCase) 
                    && currentActionName.Equals(actionName, StringComparison.CurrentCultureIgnoreCase))
                    builder.AddCssClass(selectedClass);
            }

            builder.InnerHtml = helper.ActionLink(linkText, actionName, controllerName).ToHtmlString();
            return MvcHtmlString.Create(builder.ToString(TagRenderMode.Normal));
        }

        public static MvcHtmlString Controller(this HtmlHelper helper)
        {
            return MvcHtmlString.Create((string)helper.ViewContext.RouteData.Values["controller"]);
        }
    }
}

This is final screen of the application of this post.

01.result

 

Conclusion

We can implement JQuery Accordion based categorized dynamic menu UI in MVC3. You can get the source from here.

Continue reading >>

Thursday, 31 March 2011

Silverlight Dynamic user control and assembly loading in xap or dll


Sometimes, we need to load user control page at runtime in Silverlight applications because of saving loading time or making flexible updating environment without re-compiling. The loaded forms also can call the service methods in container. Let’s see how to achieve this scenario with simple pattern and codes.

Step1 : Understanding of simple architecture

Container is main application that implements IContainerService providing communication between Forms and Container. Each forms inherit FormBase class that have IContainerService member.

01.architecture

So, we should have 3 assemblies for this application.

  1. DynamicForm.Core : IContainerService, FormBase
  2. DynamicForm (XAP) : Container.xaml and Container.xaml.cs
  3. DynamicForms.Forms (XAP): Form1, Form2,…



 

Step2 : Make independent forms

We can add forms that call IContainerService in the independent assembly.

using DynamicForm.Core;

namespace DynamicForm.Forms
{
    public partial class Form1 : FormBase
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            MessageBox.Show(Service.CallService("Form1"));
        }
    }
}

 

Step3 : Load assembly from xap or dll

At the constructor of Container page, let’s add dynamic assembly loading logics from xap file. We can also download dll files by changing download path.

...

namespace DynamicForm
{
    public partial class Container : UserControl, IContainerService
    {
        private Assembly _formsAssembly;
        private const string BaseName = "DynamicForm.Forms";

        public Container()
        {
            InitializeComponent();

            //loading
            WebClient downloader = new WebClient();
            string path = string.Format("../ClientBin/{0}.xap", BaseName);
            downloader.OpenReadCompleted += new OpenReadCompletedEventHandler(OnAssemblyOpened);
            downloader.OpenReadAsync(new Uri(path, UriKind.Relative));
        }

        public string CallService(string request)
        {
            return string.Format("Hello {0}!", request);
        }

        private Stream GetStream(Stream resultStream, string baseName, bool isXap)
        {
            if (isXap)
            {
                StreamResourceInfo resourceInfoDLL = Application.GetResourceStream(
                    new StreamResourceInfo(resultStream, null),
                    new Uri(string.Format("{0}.dll", BaseName), UriKind.Relative));
                return resourceInfoDLL.Stream;
            }
            else
            {
                return resultStream;
            }
        }

        private void OnAssemblyOpened(object sender, OpenReadCompletedEventArgs e)
        {
            AssemblyPart assemblyPart = new AssemblyPart();
            _formsAssembly = assemblyPart.Load(GetStream(e.Result, BaseName, true));
        }

        ...
    }
}

 

Step4 : Load form dynamically

Let’s add form hosting tab control, form searching text box, and button to the Container page. We can load the Forms dynamically as follows:

...

namespace DynamicForm
{
    public partial class Container : UserControl, IContainerService
    {
        ...

        private FormBase LoadControl(string name)
        {
            return (FormBase)_formsAssembly.CreateInstance(name);
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            if (string.IsNullOrWhiteSpace(this.textBox1.Text))
            {
                MessageBox.Show("Enter Form Name");
                return;
            }

            string formName = this.textBox1.Text;

            var formBase = LoadControl(string.Format("{0}.{1}", BaseName, formName));
            formBase.Service = this;

            var item = new TabItem();
            item.Header = formName;
            item.Content = formBase;
            formContainer.Items.Add(item);
            formContainer.SelectedItem = item;
        }
    }
}

 

We can see the result screen as follows:

01.result 

Conclusion

This is simple approach to load dynamic forms in Silverlight.

You can download the source code from here.

Continue reading >>