Blog updated!

Welcome back to my blog, I am in the process of migrating all my older posts so please be tuned.

UPDATE:

if ¬†you can’t find an older post, try removing .aspx from the url or use the search.

Posted in My Site | Leave a comment

Cairo Code Camp 2010 and my MEF session

Earlier this week on the 27th and 28th  of February DotNetWork user group organized the biggest dot net event in Egypt  ”CairoCodeCamp“; it was held in the German University in Cairo (GUC) was sponsored by some leading technology companies as Microsoft the complete list is on the CairoCodeCamp website.

The Camp started with a Keynote by the awesome Scott Hanselman and then was followed by 5 parallel sessions for the two days, concluding 40 awesome sessions.

On the other hand, I had the chance to be a speaker in that awesome event, my session was titled ” When MEF meets silverlight ” and was mainly an introduction to MEF in Silverlight, and here I share my materials.

 

When MEF meets Silverlight
100301175253-phpapp02&stripped_title=when-mef-meets-silverlight” />

View more presentations from AmrElsehemy.

 

The slides 

Mef-Legoized.pptx (2.58 mb)

Can’t wait for the next Cairo Code Camp, see you then.

Posted in Community | 5 Comments

Learning Silverlight : The plan and Introduction

In my previous post, I mentioned my interests and things I want to talk about in 2010, the first thing I mentioned is Silverlight, my knowledge about Silverlight now on a scale from 0 to 10 is just 0.5, actually I know nothing except that it I want to know everything, so here by I show all the topics I want to learn; not in any order.

Silverlight learning mindmap

So other than the titles, a small introduction on Silverlight needs to be done then next parts will start the actually good things,

Silverlight Introduction

I thought the best way to introduce what is Silverlight is to ask the usual WH questions and here are they;

What?

Silverlight is a cross-browser (works on any browser Internet Explorer, FireFox, Safari, Opera and recently Chrome), cross-platform (Windows, Mac and Linux) plugin for building and delivering the rich interactive applications for the web. It only needs a plugin to be installed.

When?

Silverlight 1.0 was first released in 2007, in November 2008 the second release of Silverlight 2, 6 months later Silverlight 3 was out there, and now here we are with Silverlight 4 beta

Where?

If you are running Windows install the runtime from here.

If you are on a Mac download and install from here.

 

How?

To start building silverlight applications you can install the developer tools for Silverlight. If you don't have Visual Web Developer, download both using Web Platform Installer. This will install the SDK, developer runtimes, and Visual Studio project templates. If you already have Visual Studio, download the tools directly (the Silverlight 3 SDK is also available as a standalone download). For additional information, read the Overview and the Silverlight 3 Release Notes

For Silverlight 4 download the tools from here 

 

Until now I have not finalized the plan so I would love to hear whats your opinion. Is something missing? Is something not needed?

Posted in Silverlight | 3 Comments

Happy new year, Happy 2010

First of all, Happy new year to all, hope that 2010 will be more successful that the previous years. It has been almost a year and I haven't wrote anything on my blog, and even more than a year since the last technical blog post, I know it has been a bad year for me; well I have some reasons but mostly just because I got lazy, but I was wanting to get back to the community as I gained a lot from it, I think its time to payback a very small portion of what I have learned from them.

So, I think no time is better than the very first day of the year for this turnover and getting back, after more than a year away from blogging, new technologies have came out, and my interests changed too.

Whats new for Amr Elsehemy in 2010 :

As a starter, I need a new blog theme; I won't let this take my time but I will be working on one these days.

What you will see regularly in my blog (hopefully Smile ) in general is anything technology related, but specifically one of the following topics:

Silverlight

I was an early adopter of this great new technology I even remember when me and moses where reading the very poor (that time) SDK; oh yes and it was called WPFe for Windows Presentation Foundation Everywhere, it didn't even have a Z-index property in Elements. But now all my knowledge about Silverlight that its API's are written in managed  code, rather than Javascript, and also the latest version out there is the Silverlight 4 beta which was announced at the PDC.

I have been looking around silverlight for a very small time now, and I collected some topics or just outlines for me to work on, or you can call this as a learning plan; I will also blog what I have learned along the way with many resources and links which I used and helped me along the way. 

ASP.NET MVC 

I also was an early fan of the great new framework when it came out in its 5 RC's!! :) then betas, I also started a series which unfortunately I haven't finished, I was building a very simple but complete blog engine, it was for learning purposes and not meant to be used professionally. So, my 2010's years resolution is to learn more and more about this framework also finish or rather restart the jBlogMvc series but this time with the new versions of (ASP.NET MVC, jQuery).

As I mentioned I will re-write my small blog engine to get the most of it. 

Mac world

mmm, 2009 I first got my iPhone 3G in February and soon in August I had my MacBookPro, and so fast I am being a fan of ObjectiveC and XCode, and wanting to build iphone apps and Mac Os applications as well, I expect that I blog from time to time the latest things I have known in this great world. 

Information Retrieval

I mentioned many times my Masters studies, I talked about the courses and so, but now I am in a new phase; the thesis phase, so I will also frequently write about topics in my research.

 

Finally, my next post will most probably be my silverlight learning plan, and the first lesson I learned, so wish me luck. 

Posted in My Site | 4 Comments

Happy Birthday MyBlog

Hello all, I know this blog has been idle for a long time, the reason is not I am becoming lazy or I don’t have any more new ideas and topics to write about it just so happens I was quite *very* busy and unstable in my work the past few months.

But anyway I am still busy, but I think more stable and its time to manage my time more accurately to come back to the blogo-sphere again.

One year ago, 3rd of January 2008 I decided to buy the domain amrelsehemy.net to be my blog, before that I wasn’t an active community member, after this year has gone I might have not participated much towards the community but at least I gained some valuable knowledge from it.

In 2008,

My top posts, I started my blog with a tutorial series to help custom controls developers to give their controls a rich design time support through 15 parts,  I will list them here.

Also, my jBlogMvc small series had some audience and gained a lot of traffic, here are the posts.

2008 also witnessed some big change in my MCP transcript, after working with .net and Microsoft techs for a few years this summer I decided to get some certificates [MCPD : Enterprise and Web Developer] plus 4 other MCTS SharePoint certificates.

(https://mcp.microsoft.com/authenticate/validatemcp.aspx , Transcript ID (758580) and the Access Code (sehemyxx))

Other than studying and self improvement, I finished my post graduate studies and starting my masters point, I am researching around something related to the knowledge extraction from the web which will be very  related to web semantics and web ontology.

Career wise, I worked for SCS for three quarters then left to ITWorx . In parallel I also became a teaching assistant at my faculty (Faculty of Computer and Information Sciences – Ain Shams University), I thought till now 2 courses one on Digital Image Processing and the other on Basic Data Structures using C++, I also learned alot during this semester and built some basic data structures which I will find some time to share what I learned also built an image processing package a mini photo shop which also I will share one day.

About 2009,

The first thing on my mind is to get a new theme, to stand up with the new me.

For the time being, I think whenever I start blogging again it would be something near ASP.NET MVC or jQuery which both are considered the new kids on the block of the .NET web world.

I also have an application in my mind, I wish I have the time to do it and share my experience.

Happy new year all, and happy birthday my blog.

Posted in My Site | 3 Comments

jBlogMvc : part 3 Themable View Engine, Archive and Filtering by year, month and day

NOTE: In this series I build a blogengine using ASP.NET MVC and jQuery from scratch in order to learn more about these new technologies. If you haven’t read the first post in this series, I would encourage you do to that first, or check out the jBlogMvc category. You can also always subscribe to the feeds.

jBlogMvc is converted to be used on ASP.NET MVC Beta 1 if you haven’t downloaded it yet you can find it here, to read about the changes and additions in the beta 1 I do recommend reading ScottGu’s asp net mvc beta1 announcement if you haven’t already read it.

This part had witnessed a big change in project structure hence the new release of the beta1 and building a themable folder structure as shown in the pic.solutionExplorer  [more]

I built a ThemableWebFormViewEngine which now is responsible to find and create the Views to be rendered, the following listing shows the Theme View Engine

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Globalization;

namespace jBlogMvc.Utils
{
    public class ThemableWebFormViewEngine : WebFormViewEngine
    {
        public ThemableWebFormViewEngine()
        {
            base.ViewLocationFormats = new string[] {
                "~/Themes/{2}/{0}.aspx",
                "~/Themes/{2}/{0}.ascx",
                "~/Views/{1}/{0}.aspx",
                "~/Views/{1}/{0}.ascx",
                "~/Views/Shared/{0}.ascx",
                "~/Views/Shared/{0}.aspx"
            };

            base.MasterLocationFormats = new string[] {
                "~/Themes/{2}/{0}.master",
                "~/Views/{1}/{0}.master"
            };

            base.PartialViewLocationFormats = ViewLocationFormats;
        }

        public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName)
        {
            if (controllerContext == null)
            {
                throw new ArgumentNullException("controllerContext");
            }
            if (string.IsNullOrEmpty(viewName))
            {
                throw new ArgumentException("Value is required.", "viewName");
            }

            string themeName = GetTheme(controllerContext);

            string[] searchedViewLocations;
            string[] searchedMasterLocations;

            string controllerName = controllerContext.RouteData.GetRequiredString("controller");

            string viewPath = this.GetPath(this.ViewLocationFormats, viewName, controllerName, themeName, out searchedViewLocations);
            string masterPath = this.GetPath(this.MasterLocationFormats, viewName, controllerName, themeName, out searchedMasterLocations);

            if (!(string.IsNullOrEmpty(viewPath)) && (!(masterPath == string.Empty) || string.IsNullOrEmpty(masterName)))
            {
                return new ViewEngineResult(this.CreateView(controllerContext, viewPath, masterPath), this);
            }
            return new ViewEngineResult(searchedViewLocations.Union<string>(searchedMasterLocations));
        }

        public override ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName)
        {
            if (controllerContext == null)
            {
                throw new ArgumentNullException("controllerContext");
            }
            if (string.IsNullOrEmpty(partialViewName))
            {
                throw new ArgumentException("Value is required.", partialViewName);
            }

            string themeName = GetTheme(controllerContext);

            string[] searchedLocations;

            string controllerName = controllerContext.RouteData.GetRequiredString("controller");

            string partialPath = this.GetPath(this.PartialViewLocationFormats, partialViewName, controllerName, themeName, out searchedLocations);

            if (string.IsNullOrEmpty(partialPath))
            {
                return new ViewEngineResult(searchedLocations);
            }
            return new ViewEngineResult(this.CreatePartialView(controllerContext, partialPath), this);
        }

        private string GetTheme(ControllerContext controllerContext)
        {
            string theme = controllerContext.HttpContext.Request.QueryString["theme"];
            if (controllerContext.RouteData.Values["Action"].ToString() == "ThemePreview" &&
             !string.IsNullOrEmpty(theme))
            {
                return theme;
            }
            else return Config.Instance.Theme;
        }

        private string GetPath(string[] locations, string viewName, string controllerName, string themeName, out string[] searchedLocations)
        {
            string path = null;

            searchedLocations = new string[locations.Length];

            for (int i = 0; i < locations.Length; i++)
            {
                path = string.Format(CultureInfo.InvariantCulture, locations[i], new object[] { viewName, controllerName, themeName });
                if (this.VirtualPathProvider.FileExists(path))
                {
                    searchedLocations = new string[0];
                    return path;
                }
                searchedLocations[i] = path;
            }
            return null;
        }

    }
}

This code is based on the work Chris Pietschmann of here.

The theme folder should contain the following views

  1. site.master “the overall look and feel”
  2. Index.aspx “for multi posts page”
  3. archive.aspx “archive page”
  4. login.aspx “login page”
  5. single.aspx “single post page”
  6. _postview.acsx “for the post template”

I also added in the Blog General Settings an option list for querying all themes available.

I also added a ThemePreview action which you can preview how themes look with your posts without applying it, you can test the theme using a url like this http://localhost:2113/themepreview?theme=Transparentia as you can see in the code above line 85, the method that decides which theme to render check first if the action themepreview is used and if there is a theme parameter in the query string.

 

Aslo jBlogMvc now supports the Archive page, when the posts get more and more readers like to have a page that has all the posts, and this is the description of the archive page, with an action like the following,

public ActionResult Archive()
{
    var posts = _repository.GetPostList();
    return View(posts);
}

and a simple view, that renders a table of posts titles and dates.

<%@ Page Title="" Language="C#" MasterPageFile="~/Themes/Indigo/Site.Master" AutoEventWireup="true" CodeBehind="Archive.aspx.cs" Inherits="jBlogMvc.Themes.Indigo.Archive" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
    <h1>Archive</h1>
    <div class="item">
    <%if (ViewData.Model == null || ViewData.Model.Count <= 0)
      {%>
    <h2>No Posts published yet.</h2>
    <% }
      else{%>
    <table width="100%">
    <thead><tr><th align="left">Title</th><th >Date</th></tr></thead>
    <tbody>
    <%
        foreach (var post in ViewData.Model)
        {%>
            <tr>
            <td style="width:80%"><h3><a href="<%=post.RelativeLink %>"><%=post.Title%></a></h3></td>
            <td style="width:20%" align="right"><h3><%=post.CDate.ToString("dd.MMM yyyy")%></h3></td>
            </tr>
        <%}
    %>
    </tbody></table>
    <%} %>
    </div>
</asp:Content>

Filtering Posts by Date using url

Also I added date filtering in url so that you can query posts by date like this

http://localhost:2113/posts/2008/9/24

Or

http://localhost:2113/posts/2008/9

Or

http://localhost:2113/posts/2008/

This was done by adding the following route in the route table at application start

routes.MapRoute(
    "Calendar",
    "posts/{year}/{month}/{day}",
    new { controller = "Home", action = "Index", id = "", year = "", month = "", day = "" }
);

 

Some Changes

PostBinder class is no longer used, I grabbed this part from Scott’s announcement

Preview 5 introduced the concept of “model binders” – which allow you to map incoming form post values to complex .NET types passed as Controller action method parameters.  Model binders in preview 5 were extensible, and you could create custom binders and register them at multiple levels of the system.  Preview 5 didn’t ship with any “pre-built” binders, though, that you could use out of the box (you instead had to build your own).  Today’s beta now includes a built-in, pre-registered, binder that can be used to automatically handle standard .NET types – without requiring any additional code or registration.

You can see how the AddPost action in the AdminController accepts a Post parameter just as before now with now binders, however, you can see me using Bind attribute on the post with a parameter Prefix so why?, the out of box implementation will use parameter name “p” in this case and find in the form post collection for p.body, p.title, p.slug and so on, so the developer can override this default behavior by using this attribute, here I am sending an empty prefix so it should find form post variables named body, title and so on.

public ActionResult AddPost([Bind(Prefix="")]Post p)
{
    if (!ViewData.ModelState.IsValid)
        return View("WritePost", p);

    try
    {
        _repository.InsertPost(p);
        return RedirectToRoute("Posts", new { slug = p.Slug });
    }
    catch
    {
        Helpers.UpdateModelStateWithViolations(p, ViewData.ModelState, System.Data.Linq.ChangeAction.Insert);
        return View("WritePost", p);
    }
}

Summary

So what do you think? you are most welcomed to leave comments.

Download version one : jBlogMvc_version_3.zip

If you liked this blog post then please subscribe to this blog.

Posted in jBlogMvc | 3 Comments

jBlogMvc : part 2 Editing, Deleting, Paging Posts and Rss feeds

NOTE: In this series I build a blogengine using ASP.NET MVC and jQuery from scratch in order to learn more about these new technologies. If you haven’t read the first post in this series, I would encourage you do to that first, or check out the jBlogMvc category. You can also always subscribe to the feeds.

What about new features this part will cover :

  1. Configuration is saved in the database.
  2. Managing Posts (Editing, Deleting).
  3. Posts are now paged.
  4. Some jquery magic is used.

So, lets have a tour in the project one more time. [more]

Database

Database has now a new table to read and write the blog settings.

The project design has changed I applied the Repository Pattern (as recommended in some feedback) , so know I have an extra layer I don’t plan on supporting other data stores but its a good practice (anyway this series is to learn).

Helpers

Pagination is added it has been discussed many times I will not repeat the code I got over here, for more about paging in ASP.NET MVC check the following excellent posts

Models

IBlogRepository and its implementation were added to this folder, the IBlogRepository is as listed here

public interface IBlogRepository
{
    #region Posts
    Post GetPostBySlug(string slug);
    Post GetPostByPemalink(Guid premalink);
    PagedList<Post> GetPostList(int pageIndex, int pageSize);

    void InsertPost(Post p);
    void UpdatePost(Post p);
    void DeletePost(Post p);
    #endregion

    #region Settings
    void SaveSetting(Setting s);
    Setting GetSetting(string settingKey);
    #endregion
}

 

Controllers

Still having the main two controllers (Home and Admin)  but many changes have came through, due to changing the structure and using repository.

Home Controller now sends a PagedList rather an ordinary List to the View, and I added a feed action which returns rss feeds of the blog as shown below

public ActionResult Feed()
{
    XDocument document = new XDocument(
        new XDeclaration("1.0", "utf-8", null),
            new XElement("rss",
                    new XElement("channel",
                        new XElement("title", Config.Instance.BlogName),
                        new XElement("link", "http://www.northwindtraders.com"),
                        new XElement("description", Config.Instance.BlogDescription),

                        from post in _repository.GetPostList(0, Config.Instance.BlogSyndicationFeeds)
                        orderby post.CDate descending
                        select new XElement("item",
                            new XElement("title", post.Title),
                            new XElement("description", post.Body),
                            new XElement("link", Request.Url.GetLeftPart(UriPartial.Authority) + post.RelativeLink)
                            )
                       ), new XAttribute("version", "2.0")));
    StringWriter sb = new StringWriter();
    document.Save(sb);

    return Content(sb.ToString(), "text/xml", Encoding.UTF8);
}

Admin Controller has a lot of additions as shown in the code listing.

[AcceptVerbs("GET")]
public ActionResult EditPost(Guid? id)
{
    if (!id.HasValue) return RedirectToAction("ManagePosts");
    Post p = _repository.GetPostByPemalink(id.Value);
    if (p == null) return RedirectToAction("ManagePosts");
    return View(p);
}

[AcceptVerbs("POST")]
public ActionResult UpdatePost(Guid id)
{
    Post p = _repository.GetPostByPemalink(id);
    if (!ViewData.ModelState.IsValid)
        return View("ManagePosts", p);

    try
    {
        UpdateModel(p, new string[] { "Title", "Body", "Slug", "CDate" });
        _repository.UpdatePost(p);
        return RedirectToRoute("Posts", new { slug = p.Slug });
    }
    catch
    {
        Helpers.UpdateModelStateWithViolations(p, ViewData.ModelState, System.Data.Linq.ChangeAction.Update);
        return View("ManagePosts", p);
    }
}

[AcceptVerbs("GET")]
public ActionResult DeletePost(Guid? id)
{
    if (!id.HasValue) return RedirectToAction("ManagePosts");
    Post p = _repository.GetPostByPemalink(id.Value);
    if (p == null) return RedirectToAction("ManagePosts");
    return View(p);
}

[AcceptVerbs("POST")]
public ActionResult RemovePost(Guid id)
{
    Post p = _repository.GetPostByPemalink(id);
    if (!ViewData.ModelState.IsValid)
        return View("ManagePosts", p);

    try
    {
        _repository.DeletePost(p);
        return RedirectToAction("ManagePosts");
    }
    catch
    {
        Helpers.UpdateModelStateWithViolations(p, ViewData.ModelState, System.Data.Linq.ChangeAction.Insert);
        return View("ManagePosts", p);
    }
}

public ActionResult ManagePosts(int? page)
{
    var posts = _repository.GetPostList(page ?? 0, 25);
    return View(posts);
}

public ActionResult GeneralSettings()
{
    return View();
}
public ActionResult ReadingSettings()
{
    return View();
}

Views

A lot of views were added in this part 2 other nested master pages have been added Admin_Manage and Admin_Settings for managing blog content and settings respectively some content views were added too.

  1. ManagePosts : Grid for all posts.
  2. EditPost : editing a post.
  3. DeletePost : confirm deleting a post.
  4. GeneralSettings : Blog Name, Blog description.
  5. ReadingSettings : Posts per page, syndication count.

I will not copy and paste code here, please take a look at the attached project.

jQuery

This part didn’t miss some of the jQuery magic as well, I found another interesting plugin called jEditable which allows ajax inline editing, its pretty cool and small, all you need to start using it, is an Action that accepts POST verbs and returns some value.

I used it here with the (Settings) panel to read and write blog settings, the following code snippet is from the GeneralSettings.aspx view page defined in the document ready event.

 

$("#blogname").editable('<%=Url.Action("UpdateSettings","Admin") %>', {
               submit: 'ok',
               cancel: 'cancel',
               cssclass: 'editable',
               width: '99%',
               placeholder: 'emtpy',
               indicator: "<img src='../../Content/img/indicator.gif'/>"
           });

 

<p>
    <label for="blogname">Blog Name</label>
    <span class="edt" id="blogname"><%=Html.Encode(jBlogMvc.Config.Instance.BlogName)%></span>
</p>

Its clear that this code snippet assigns the textbox with id blogname to an action called UpdateSettings found in the Admin controller, shown in the next code snippet

 

[AcceptVerbs("POST")]
public ActionResult UpdateSettings(string id, string value)
{
    foreach (var item in this.GetType().GetProperties())
    {
        if (item.Name.ToLower().Equals(id, StringComparison.InvariantCultureIgnoreCase))
            item.SetValue(Config.Instance, value, null);
    }
    return Content(value);
}

inline editing

So, in the action I accept two parameters sent id and value, sent by default by the jEditable plugin which can be configured to change the variable names, the action is expecting that there is a blogsetting  in the Settings table having a key macthing the id parameter for example (blogname), which I also expect having a matching Property name in the Config class (built using the singleton pattern).

I am pretty sure that this is not the best practice for this case, thats why I am in need for constructive feedback.

Summary

And that’s all for this part, I have more and more features coming while writing this engine I have learned much till now, hope someone is learning with me too.

In this part, I used some features of the ASP.NET MVC to complete the administration area I started last, jQuery too was used to make inline editing (jEditable plugin) so what do you think? you are most welcomed to leave comments.

Download version one : jBlogMvc_version_2.zip

If you liked this blog post then please subscribe to this blog.

Posted in jBlogMvc | 7 Comments

jBlogMvc : part 1 Building the Administration Area

NOTE: In this series I build a blogengine using ASP.NET MVC and jQuery from scratch in order to learn more about these new technologies. If you haven't read the first post in this series, I would encourage you do to that first, or check out the jBlogMvc category. You can also always subscribe to the feeds.

In this part of the series, I build the administration area of the blog engine I am building using the ASP.NET MVC and jQuery, in this part I will cover more basic features used in any blog engine, so lets get started.

What will part 1 cover ?

Basically it will cover how to build an administration area, I chose the wordpress blog engine and tried to clone its structure and some look and feel of it, the operations I will implement in this part will be :

  • Visitor
    • Login — I will just reuse the code available with the default project template for membership stuff.
  • Admin
    • Logout
    • Add Post

The stuff I collected and used all over the net from blogs and used in this part can be summarized in the following,

  1. Using membership for validation
  2. Using the Authorize attribute
  3. Using Model Binders
  4. jQuery Client validation
  5. Small validation framework for business rules and server side validation.(originally written by scott gu)
  6. Using nested master pages in ASP.NET MVC
  7. Applying the "Post/Redirect/Get" (aka PRG) pattern.
  8. Applying some css to make it look nice (based on wordpress blogengine admin layout) [more]

To hold your interest the final look of the administration area will look like this :

admin area

Ok Lets see some code

What's new in version 1 :

Routes

Routes now include an extra route for directing users to the admin area

[code:c#] 

routes.MapRoute(
    "Admin",
    "admin/{action}",
    new { controller = "Admin", action = "Index" }
    );

[/code] 

Models

No new models were added as the database remains as it is, however, I like to highlight a new feature available in the Preview 5, ModelBinders, although ScottGu just mentioned that the team has not yet finalized and will be changed in the beta version.

Note: the MVC team plans to tweak the IModelBinder interface further for the next drop (they recently discovered a few scenarios that necessitate a few changes).  So if you build a custom model binder with preview 5 expect to have to make a few tweaks when the next drop comes out (probably nothing too major – but just a heads up that we know a few arguments will change on its methods). By ScottGu

ModelBinders, which is provided to allow Action methods to take complex types as their parameters. Previously, action methods were only able to take simple types such as strings and integers as their parameters. The new ModelBinder provides the facility to build complex types from component parts that (for example) may be part the result of submitting a form with several fields.

Learn more about ModelBinders from Melvyn Harbour, Timothy Khouri and Maarten Balliauw.

The following code listing is from the PostBinder

 

[code:c#] 

public class PostBinder : IModelBinder
{
    private static string Concat(string modelName, string propertyName)
    {
        return (String.IsNullOrEmpty(modelName)) ? propertyName : modelName + "." + propertyName;
    }

    private static T LookupValue<T>(ControllerContext controllerContext, string propertyName, ModelStateDictionary modelState)
    {
        IModelBinder binder = ModelBinders.GetBinder(typeof(T));
        object value = binder.GetValue(controllerContext, propertyName, typeof(T), modelState);
        return (value is T) ? (T)value : default(T);
    }

    public object GetValue(ControllerContext controllerContext, string modelName, Type modelType, ModelStateDictionary modelState)
    {            if (controllerContext == null)
        {
            throw new ArgumentNullException("controllerContext");
        }
        if (modelType != typeof(Post))
        {
            throw new ArgumentException("This binder only works with Post models.", "modelType");
        }

        // Instantiate a post object, then bind values to each property
        Post p = new Post()
        {

            Title = LookupValue<String>(controllerContext, Concat(null, "Title"), modelState),
            Body = LookupValue<string>(controllerContext, Concat(null, "Body"), modelState),
            Slug = LookupValue<String>(controllerContext, Concat(null, "Slug"), modelState),
            CDate= LookupValue<DateTime>(controllerContext, Concat(null, "CDate"), modelState)
        };
        return p;
    }

}

[/code] 

 

Don't forget to register the Binder (there are four ways to register, check ScottGu's post).

[code:c#] 

protected void Application_Start()
      {
          ModelBinders.Binders[typeof(Post)] = new PostBinder();
          RegisterRoutes(RouteTable.Routes);
      }

[/code] 

Controllers

In this part, the AdminController appears to hold,  the admin tasks, which till now only include the following actions.

  • index : a default action redirects to the write action.
  • write : an action to be responsible for writing things (only have posts now), so it just redirects to posts.
  • writepost : renders a view to enable authenticated users to write posts and publish it.
  • addpost : a Http Post action which inserts the new post into the database.

 

[code:c#] 

[Authorize]
public class AdminController : Controller
{
    jBlogMvcDataContext jbdc = new jBlogMvcDataContext();

    public ActionResult Index()
    {
        //just a default redirection
        //maybe in future this should be configurable
        return RedirectToAction("Write");
    }
    public ActionResult Write()
    {
        //just a default redirection
        //maybe in future this should be configurable
        return RedirectToAction("WritePost");
    }

    [AcceptVerbs("GET")]
    public ActionResult WritePost()
    {
        Post p = new Post();
        return View(p);
    }

    [AcceptVerbs("POST")]
    public ActionResult AddPost(Post p)
    {
        if (!ViewData.ModelState.IsValid)
            return View("WritePost", p);

        try
        {
            Helpers.InsertPost(p);
            return RedirectToRoute("Posts", new { slug = p.Slug });
        }
        catch
        {
            Helpers.UpdateModelStateWithViolations(p, ViewData.ModelState,System.Data.Linq.ChangeAction.Insert);
            return View("WritePost", p);
        }
    }
}

[/code] 

More over, HomeController now has 2 more extra actions :

  • login
  • logout

just copied from the default template nothing new added.

Views

A lot of views are added this part, actually I am trying nesting master pages, one for the admin area overall, and the other for each module (like: write, manage, .. and so in wordpress), so I added :

  • admin.master
  • admin_write.master
  • writepost.aspx
  • login.aspx
  • _loginWidget.acsx

writepost.aspx

<%@ Page Title="Write Post" Language="C#" MasterPageFile="~/Views/Admin/Admin_Write.Master"
    AutoEventWireup="true" CodeBehind="WritePost.aspx.cs" Inherits="jBlogMvc.Views.Admin.WritePost" %>

<asp:Content ContentPlaceHolderID="head" runat="server">

    <script type="text/javascript">
        $(document).ready(function() {
        $("#fields").validate();});
    </script>

</asp:Content>
<asp:Content ContentPlaceHolderID="MainContent" runat="server">
    <h2>Write Post</h2>
    <form id="fields" action="<%=Url.Action("AddPost","Admin")%>" method="post">
    <table cellpadding="0" cellspacing="0">
        <tr>
            <td>
                <div id="postfields">
                    <p>
                        <label for="title">Title</label>
                        <%=Html.TextBox("Title", new { id="title",@class="required"})%>
                        <%=Html.ValidationMessage("Title")%>
                    </p>
                    <p>
                        <label for="body">Body</label>
                        <%=Html.TextArea("Body", new { id = "body", rows = "6", cols = "50", @class = "required" })%>
                        <%=Html.ValidationMessage("Body")%>
                    </p>
                    <p>
                        <label for="slug">Slug</label>
                        <%=Html.TextBox("Slug", new { id = "slug", @class = "required" })%>
                        <%=Html.ValidationMessage("Slug")%>
                    </p>
                    <p>
                        <label for="cdate">Creation Date</label>
                        <%=Html.TextBox("CDate", ViewData.Model.CDate.ToString("MM/dd/yyyy"),
                            new { id = "cdate", @class = "required date" })%>
                        <%=Html.ValidationMessage("CDate")%>
                    </p>
                </div>
            </td>
            <td id="tdsubmitbox" valign="top">
                <div id="submitbox">
                    <div class="buttons">
                        <button type="submit" class="positive">
                            <img src="../../Content/icons/tick.png" alt="" />Publish
                        </button>
                    </div>
                </div>
            </td>
        </tr>
    </table>
    </form>
</asp:Content>

_loginWidget.ascx

And it looks like this

logged in view                                  logged off

logged in widget not logged in

Utils

I added some code to perform the validation logic for custom business rules, this is the simplest implementation for this task copied from ScottGu's post, for more complex implementation scenarios I strongly recommend the following posts,

For client side jquery I used the validation plugin found here, Server side I used the small framework scott gu wrote in his post for simplicity.

Client side validation

And server implementation as well

serverSide

Moreover, The Helper Class (which acts as the business layer) has some additions in order to add a post to the database.

Css and designs

Css http://particletree.com/features/rediscovering-the-button-element/ and http://wordpress.org

Icons http://www.famfamfam.com/lab/icons/silk/

Summary

And thats all for this part, I have more and more features coming while writing this engine I have learned much till now, hope someone is learning with me too.

In this part, I used some features of the ASP.NET MVC to build an administration area, jQuery too was used on client side (validator plugin) so what do you think? you are most welcomed to leave comments.

Download version one : jBlogMvc_version_1.zip

If you liked this blog post then please subscribe to this blog.

Posted in jBlogMvc | 8 Comments

Introducing jBlogMvc

ok

Long time no posts, well I was studying Sharepoint 2007 technologies and actually started a series for development a while ago I just managed to write two  introductory posts and didn't write more I have some ideas I'd love to share in sharepoint development which I hope to write about them some time in the future and complete the series. However, recently the new ASP.NET MVC framework has gathered some fame and actually I too got attached to it and I am keen to learn new technologies and so, also the jQuery javascript library has been the choice of most the .NET web developers community.

Its Time to Learn

So, I have read alot of blogs and articles on ASP.NET MVC which has a massive amount of resources (while not being beta yet), I also read the excellent book "jQuery in Action" and learned a lot from it I do recommend it for learning jquery. Now its time to utilize this learning in a simple application that experience the stuff I read about, then I stumbled across this article Want To Learn Web Programming? Write A Blog Engine so be it, I will build a (Simple-Fully featured) blog engine in order to learn more and use these two new kids on the block.

Of course, I will use ASP.NET MVC, jquery and finally I will use Sql Express as the datastore and Linq to Sql for dal.[more]

Where I learn from

Before starting building my blog series I would like to share the blogs I read to learn from ASP.NET MVC

  1. Storefront MVC Series by Rob Conery.
  2. Stephen Walther Excellent MVC Tips and Forum series.
  3. Of course Scott Gu's mvc announcements and demos.
  4. Phil Haack blog.
  5. Steve Sanderson
  6. Emad Ibrahim the creator of Yonkly the open source twitter clone built on ASP.NET MVC and jQuery.
  7. Matt Hawley
  8. ASP.NET MVC tagged articles on DotNetKicks
  9. The Official ASP.NET MVC forums.

Let's start

So, what's jBlogMvc? its a small blogengine I am going to build in an agile process, jBlogMvc if you haven't notice j stands for jQuery, Blog for the engine itself  and Mvc for the ASP.NET MVC. I say here that this engine will be simple and complete I will try to add features as much as possible and build it in an extensible way like modern blog engines to enable themes, widgets and plugins. Also I need to point that the work on this blog engine is totally inspired from the great open source blog engines which include BlogEngine.NET, WordPress and other non blog engines as yonkly and many others.

What will part 0 cover ?

Other than announcing the blog engine, in this part I will have a version 0 that will have the following:

  • Vistor
    • Viewing posts By Chronological order.
    • Viewing individual posts.

Ok show me some code!

Too much talking lets get to the code now, ok the solution is as shown in the figure consisting of the following :

 solution

The database

For this ZERO part I didn't include much for the blog engine, the only table I included is the Post table as shown below, I do believe this table will be expanded more by time and more parts in the series.

database

Routes

[code:c#]

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

            routes.MapRoute(
                "Posts",
                "post/{slug}",
                new { controller = "Home", action = "post" }
            );

            routes.MapRoute(
                "Default",
                "{action}/{id}",
                new { controller = "Home", action = "Index", id = "" }
            );

        }

[/code]

Models

Just added here a dbml file (Linq to Sql DataContext) , and I added a PostEx.cs file and added a property for the Post, God Bless partial classes. PostEx.cs as shown in Listing 2.

[code:c#]

public partial class Post
    {
        public string RelativeLink
        {
            get
            {
                return VirtualPathUtility.ToAbsolute("~/post/") + Slug;
            }
        }
    }

[/code]

Controllers

For now I only have one controller the HomeController which has simply 3 actions for now.

  • index : Renders a view with all posts sorted in a chronological order
  • post(slug) : Renders a view for the post with a matching slug if not found it renders error404 view
  • premalink(guid) : Renders a view for the post with a matching guid if not found it renders error404 view

HomeController as shown in Listing 2.

[code:c#]

public class HomeController : Controller
    {
        /// <summary>
        /// Renders a view with all posts sorted in a chronological order
        /// </summary>
        /// <returns></returns>
        public ActionResult index()
        {
            var posts = Helpers.GetPostList() ?? new List<Post>();
            return View(posts);
        }

        /// <summary>
        /// Renders a view for the post with a matching slug
        /// if not found it renders error404 view
        /// </summary>
        /// <param name="slug">Post slug to be matched</param>
        public ActionResult post(string slug)
        {
            var post = Helpers.GetPostBySlug(slug);
            return post != null ? View("single", post) : View("error404");
        }

        /// <summary>
        /// Renders a view for the post with a matching premalink
        /// if not found it renders error404 view
        /// </summary>
        /// <param name="id">Post premalink to be matched</param>
        public ActionResult premalink(Guid id)
        {
            var post = Helpers.GetPostByPemalink(id);
            return post != null ? View("single", post) : View("error404");
        }
    }

[/code]

Views

The solution now contains one master page for the overall site, three views, and one usercontrol

  • site.Master : gives the overall look and feel for the site
  • index.aspx : renders all posts.
  • single.aspx : renders a single post.
  • error404.aspx : to be rendered when a request to a non matching post slug or premalink
  • _postView.ascx : the post template to be used

Utils

Two classes that help me

  • Config: Contains some static properties that read from hard coded strings (in a version coming up should read from the web.config or even a database table).
  • Helpers: just some common helper methods.

Config File

[code:c#]

public class Config
   {
       static public string BlogName { get { return "My Blog Name"; } }
       static public string BlogDescription { get { return "This blog is built using the ASP.NET MVC framework."; } }
       static public string BlogUrl { get { return VirtualPathUtility.ToAbsolute("~/"); } }
       static public string Version { get { return "0.1.0.0"; } }
   }

 

[/code]

 

Summary

In this part, I just announced jBlogMvc the ASP.NET MVC and jQuery blogengine which I build in order to learn more about the two new technologies (at least for me), so what do you think? you are most welcomed to leave comments.

Download version zero : jBlogMvc_version_0.zip (624.80 kb)

If you liked this blog post then please subscribe to this blog.

Posted in jBlogMvc | 12 Comments

SP Dev part 2 : Understanding Sharepoint Custom Pages

NOTE: If you haven't read the first post in this series, I would encourage you do to that first, or check out the Sharepoint category. You can also always subscribe to the feeds.

The Sharepoint 2007 System introduces two types of pages the first type usually called Application Pages and other type called Site Pages.

As a sharepoint developer you should know both of these types of pages and when to use them, so let me define them here briefly and show some differences between them to help you decide which type of pages you will want to use when developing in sharepoint.

Application Pages

Application Pages are non customizable and are found in  the C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS, its worthy to note that this physical directory is mapped to the virtual _layouts directory whenever WSS/MOSS creates a new Web application in the IIS. By using this mapping scheme along with some additional processing logic, the WSS/MOSS runtime can make each application page accessible within the context of any site in the farm.

When building custom application pages you should use the Microsoft.Sharepoint.LayoutsPageBase as a base class and should be content pages that reference to the ~/_layouts/application.master master page, Application Pages might include in line code or have a code behind file compiled in a dll, to deploy application pages they should be the LAYOUTS directory and all custom code dlls either in the GAC.[more]

Standard Application Pages in the WSS

Site Pages (Content Pages)

Site Pages can be customized on a site-by-site basis. default.aspx page in the Blank site is considered a site page as well as the AllItems.aspx used in lists. When customizing site pages this might lead to hundreds of versions of one site pages, site pages have only one physical version and all customized pages reside in the Content Database of the Web Application. This leads us to one important optimization point known as page ghosting, imagine that you have just created 100 new WSS sites from the Blank Site template. If none of these sites requires a customized version of its home page (default.aspx), would it still make sense to copy the exact same page definition file into the content database 100 times? Ofcourse not, rather than copying 100 version of the same page in the content database, the WSS runtime can load the page template from the file system of the Web server and use it to process any request for an uncustomized page instance. Therefore, you can say that page ghosting describes the act of processing a request for an uncustomized page instance by using a page template loaded into memory from the file system of the front-end Web server.

Security consideration : Since the site page can be customized for every customized version, a copy must be stored in the content database, which in turn raises a security issue what if a user having an administrator permission and tries to write in line code within a customized version. This security concern is dealt in WSS by having a default policy that prohibits in line scripting in site pages. The default policy also runs site pages in a no-compile mode, which means they are not compiled into DLLs.

 

Conclusion

In this part I just scratched the 2 types of pages used in the Sharepoint System I have to say that there is more and more to talk about on this topic which I will write more through this series.

Posted in Sharepoint | Leave a comment