INCLUDE_DATA

Managing custom messages after registration, login etc. easily with custom HtmlHelpers

Johannes Hiemer April 11th, 2008

To clear up the mess I created with this title, I will begin with an explanation of what I was thinking about. While I am writing my CustomMembershipProvider I finally ended up at a point where I had to think about how to present system events to the front end user browsing the webpage. To underline what I am talking about I show you a screenshot.

Here you can easily see what I was trying to explain above. At the beginning of my work I did not care about these messages. Their were to few of them to work at a simple and plain solution. After these message got more and more I had a big desire for finding the simple-and-plain-solution. The code that was working for me looked like this:

<% if (ViewData.StatusMsgs != null)
   { %>

<%= ViewData.StatusMsgs.Title%>

<%= ViewData.StatusMsgs.Description%>
<% } else { %>
Internal StatusMessageSystemError occured. Please Contact your administrator
<% } %>

As you can see, it is a lot inline-code and not very nice. While working with ASP.NET MVC sooner or later you stumble over HtmlHelpers. For me it was the point to create my first own HtmlHelper. My StatusMessageHtmlHelper looks like this:

public static string StatusMessage(StatusMessages statusMessage)
        {
            if (statusMessage == null)
            {
                statusMessage = new StatusMessages();
                statusMessage.ControllerName = "CustomHtmlHelper";
                statusMessage.Title = "Internal system error";
                statusMessage.Description = "Internal StatusMessageSystemError occured. Please Contact your administrator";
            }
            /**
             * info = 0,
             * warning = 1,
             * error = 2,
             * fatal = 3
             */

            string fontColor = null;
            switch (statusMessage.MessageType)
            {
                case 0:
                    fontColor = "#000000";
                    break;
                case 1:
                    fontColor = "yellow";
                    break;
                case 2:
                    fontColor = "red";
                    break;
                case 3:
                    fontColor = "red";
                    break;
                default:
                    fontColor = "#000000";
                    break;
            }

            string statusMessageTag = "

{0}

” + “
{1}
“; return string.Format( statusMessageTag, statusMessage.Title, statusMessage.Description ); }

All details are derived from my object StatusMessage, consisting of these code-blocks:

public class StatusMessages
    {

        private int _MessageType;
        private string _ControllerName;
        private string _Title;
        private string _Description;

        public string ControllerName
        {
            get { return _ControllerName; }

            set { _ControllerName = value; }
        }

        public string Title
        {
            get { return _Title; }
            set { _Title = value; }
        }

        public string Description
        {
            get { return _Description; }
            set { _Description = value; }
        }

        public int MessageType
        {
            get { return _MessageType; }
            set { _MessageType = value; }
        }

    }

    public enum MessageType
    {
        info = 0,
        warning = 1,
        error = 2,
        fatal = 3
    }

Perhaps you can already imagine how I managed the transfer from controller to the view. I just created another helper-method in my controller

public void CreateStatusMessage(string title, string description, MessageType messageType)
        {
            viewData.StatusMsgs = new StatusMessages();
            viewData.StatusMsgs.MessageType = (int) messageType;
            viewData.StatusMsgs.ControllerName = "UserController";
            viewData.StatusMsgs.Title = title;
            viewData.StatusMsgs.Description = description;

        }

Having this method I can call it very easy and providing viewData in RenderView catches it up all together

UserController:
CreateStatusMessage("Login failed", "Either your password or the provided username were incorrect, please try again", MessageType.error);
                    RenderView("Login", viewData);

UserListViewData.cs
public StatusMessages StatusMsgs { get; set; }

And finally in the end in my aspx page I am just importing the namespace and calling my first custom HtmlHelper.

<%@ Import Namespace="Playground.Controllers" %>

<%=CustomHtmlHelpers.StatusMessage(ViewData.StatusMsgs) %>

That’s all. If you got other suggestions for complete different architecture (approach) or slight restructuring, please let me know!

Creating a dynamic menu with Silverlight and LINQ to XML Part 2, the Xml-Part

Johannes Hiemer April 8th, 2008

To complete the menu-creation via Linq2Xml I am going to present the 2 second and more essential part of my menu.
To be able to create a menu on the fly we need a xml file with our menu definitions in it. I made it quite simple so we just have the following properties in it: title, description, image, height and width.
The xml-file looks like this:


	

		images/button_1.jpg
		This is a button
    100
    100
	

To work more comfortable with data we get from the xml-file later on I created just a simple and plain entity class. My XmlMenu.cs looks like this

 public class XmlMenu
    {
        private string _title;
        private string _image;
        private string _description;
        private int _height;
        private int _width;

        /**
         * 
         *   
         *
         *       images/button_1.jpg
         *       This is a button
         *   
         *  
         */

        public string Title
        {
            get { return _title; }
            set { _title = value; }
        }

        public string Image
        {
            get { return _image; }
            set { _image = value; }
        }
….

The most important part is now our method to retrieve and handle our xml-data. This is split up into two methods:

   public XDocument LoadXmlDocument(string documentName)
        {
            XDocument document = XDocument.Load(documentName);
            if (document != null)
                return document;
            else
                return null;
        }

        public List GetXmlMenu()
        {
            XDocument document = LoadXmlDocument(”menu.xml”);

            var menues = from menu in document.Descendants(”menuitem”)
                    select new XmlMenu
                    {
                        Title = menu.Element(”title”).Value,
                        Image = menu.Element(”image”).Value,
                        Description = menu.Element(”description”).Value,
                        Width = int.Parse(menu.Element(”width”).Value),
                        Height = int.Parse(menu.Element(”height”).Value)

                    };

            if (menues.Count() != 0)
                return menues.ToList();
            else
                return null;
        }

As you can see, I am now mapping in my Linq2Xml query just the data retrieved from my xml-file to the entity-class. Handling it this way it is very comfortable to get the properties of each button in my new created list.
Completing the code-listing with customized dynamic menu creation in my CreateMenu(Grid grid)-method

List menues = GetXmlMenu();
….
int k = 0;
                foreach (XmlMenu menu in menues)
                {
                    grid.Children.Add(CreateButton(menu.Title, menu.Width, menu.Height, i, k));
                    k++;
                }

Comments and ideas are welcome!

The project as a zip-file

Creating a dynamic menu with Silverlight and LINQ to XML

Johannes Hiemer April 1st, 2008

To cover the category “Silverlight” I started out to develop a small “menu”. Till yet it has not to much functionality, but the fundamental properties are given. It supports creation at runtime, dynamic load of the button image, and mouseover/mouseclick animation.
First of all starting out with the Page.xaml



    
        
            
                
                
            
        
    

* Important mark: I am not a designer and never will be, so don’t expect all this to be beautiful. It is just beautiful, because it is functional. :-)

 public Page()
        {
            // Required to initialize variables
            InitializeComponent();
            Grid grid = new Grid();
            LayoutRoot.Children.Add(grid);
            LayoutRoot.ShowGridLines = true;
            CreateMenu(grid);

        }

As you can see, that’s initialization of the component, the creation of the new Gird wherein the menu will be placed. The CreateMenu(Grid grid) looks like this:

 public void CreateMenu(Grid grid)
        {
         .....

            grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(110) });
            for (int i = 0; i < 7; i++)
                grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(110) });

            Random rand = new Random();
            for (int i = 0; i < grid.RowDefinitions.Count; ++i)
            {
                for (int k = 0; k < grid.ColumnDefinitions.Count; ++k)
                {
                    grid.Children.Add(CreateButton("Test", 100, 100, i, k));
                }
            }
        }

The most important things are in the CreateButton(String Label, int Width, int Height, int RowProperty, int ColumnProperty) - Method

StackPanel stackPanel = new StackPanel();
            stackPanel.Orientation = Orientation.Vertical;
            stackPanel.Children.Add(new Image { Source = new BitmapImage(new Uri("button.png", UriKind.Relative)) });
 button.Content = stackPanel;
            button.Style = (Style)(Application.Current.Resources["menuButton"]);

With this series of filling up the button’s properties we would get the following xaml-code:


In your App.xaml you can now define some storyboards for the mouseover and mouseclick events.

I think that’s a good starting point to built your own menu. To see my menu in action check out this example here: Dynamic menu with Silverlight

The LINQ to XML part is coming in the next few days I think. Depending how much time I am gonna have. To give some preview what it is gonna do: The labels, button-images and links will be loaded from a xml-file to generate the menu based upon the data.

The many different ways to pass form-data with ASP.NET MVC

Johannes Hiemer March 31st, 2008

There are often questions about the many different ways how to get form-data in ASP.NET MVC correctly. First of all, to clarify there is no correct way. I depends on what you want to do. I am using this post to show you the many different ways. Perhaps I am gonna fill up with more and more..

First:

User name: Password:
 public void Login(string userName, string password, string ReturnUrl)
        {
...

Second:

Please login: <%using (Html.Form("User","Login")) { %>
Username: <%= Html.TextBox("userName")%>
Password: <%= Html.TextBox("password")%>
<%= Html.SubmitButton("Login")%>
<%}%>
public void FormSubmit(string name, string password)
{
..

Third:

<%=using(Html.Form(c => c.Update(ViewData.Item.ItemID))) { %>


……
Name: <%=Html.TextBox("Item.ItemName", ViewData.Item.ItemName)%>
<%}%>
public void Update(int id) {{viewData.Item = db.Items.Single(i => i.ItemId == id);Binding.UpdateFrom(viewData.Item, RequestForm);db.SubmitChanges();}

Fourth:

Please login: <%using (Html.Form(action => action.ChangePassword())) { %>
Username: <%= Html.TextBox("username")%>
 public void ChangePassword()
        {
            string username = Request.Form.Get("username");
            string password = Request.Form.Get("password");

Till now these are the most useful ways to handle it.

Creating a custom MembershipProvider with LINQ and ASP.NET MVC

Johannes Hiemer March 28th, 2008

The intention behind this article for me was getting in contact with ASP.NET MVC and LINQ.

ASP.NET MVC is different approach about designing and working with web-applications. For most of the readers MVC should be a very common pattern. For the new ones to programming I suggest reading the introduction to this topic at wikipedia.

LINQ is very handy way to handle SQL, XML and Array/List access. You can query collections, enumerable classes XML and SQL in the native programming language, in web-projects mostly C# or VB.NET. In this article I am gonna use LINQ to SQL, which is in fact just a kind of object/relational mapper (O/RM) which is provided with visual studio. You can easily generate entity classes based up on a database schema, so it does fit very good to the model-view-controller approach.

Base of the MembershipProvider

To get in touch with new technologies on the web, I am always trying to do a little sample-application. The easiest and most common thing you will see on web pages are user-management with registration, login and so on.

Since ASP.NET 2.0 I think, Microsoft is shipping a very good small web page security framework with the .NET framework. Do not start totally from scratch I just grabbed the database-schema, renamed the tables.

Renamed database tables

Subsequent you just need to create a new LINQ to SQL dbml-file.

Now you can just open up the server explorer and drop the needed tables onto the field. The first step we had to take on our custom membership provider is done.

Preparing the web.config

To tell our web application that it should use our custom membership provider instead of the .NET build in we need to edit our web.config. The entry should look somehow like this:





As you can see above we are just telling our application that we got a new default provider for our membership management. In the providers-section we add the typical web.config entries. Our next step is to create the class called LinqMembershipProvider.

The LinqMembershipProvider

The LinqMemberShipProvider just implements all the methods normally provided by the MembershipProvider. In fact it is just a kind of “linq-rewritten” class. An extract you can see here:

 namespace Playground.Models.Provider
{
    public class LinqMembershipProvider : MembershipProvider
    {

        private String name;
        private String sApplicationName;
        private Boolean enablePasswordReset;
        private Boolean enablePasswordRetrieval;
        private Boolean requiresQuestionAndAnswer;
        private Boolean requiresUniqueEmail;
        private int passwordAttemptThreshold;
        MembershipPasswordFormat passwordFormat;

        PlaygroundDataContext playground = new PlaygroundDataContext();

        public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
        {
            this.name = name;

                if (config["enablePasswordRetrieval"] != null)
                    enablePasswordRetrieval = Convert.ToBoolean(config["enablePasswordRetrieval"].ToLower());

                if (config["enablePasswordReset"] != null)
                    enablePasswordReset = Convert.ToBoolean(config["enablePasswordReset"].ToLower());

                if (config["requiresQuestionAndAnswer"] != null)
                    requiresQuestionAndAnswer = Convert.ToBoolean(config["requiresQuestionAndAnswer"].ToLower());

....

public override bool ValidateUser(string username, string password)
        {
            bool validated = false;

            if (playground.GetUserByUsername(username).Count < 1)
                validated = false;
            else
            {
                pMembership membership = playground.GetUserDetailsByName(username);
                validated = this.ComparePasswords(password, membership.Password, membership.PasswordSalt);
            }
            return validated;
        }

Causing the class to be a bigger one, about 600 lines of code I just presented the beginning and a sample-method.
As you can see I am calling my datacontext called playground. The PlaygroundDataContext looks like this:

namespace Playground.Models
{
    public partial class PlaygroundDataContext
    {
        public List
 GetUserByUsername(String name)
        {
            return pUsers.Where(u => u.UserName == name).ToList();

        }

        public List
 GetUserByEmail(String email)
        {
            return pMemberships.Where(m => m.Email == email).ToList();
        }

        public List
 GetUsers()
        {
            return pUsers.ToList();
        }
…
   }
}

As you can see it’s not about magic, it is just about rewriting existing code for another data-access-layer.

I hope this helps you getting started with customizing a MembershipProvider for your own needs.