Saturday, September 26, 2009

Using the query system in EPiServer Community

The query system in EPiServer Community is a simple way of retrieving entities and collections specific to EPiServer Community. In this blog post I’ll walk through four examples of how the query system can be used.

Let us start with an easy one: Get a user by an ID. This can of course be done by calling the EPiServer.Community.CommunitySystem.CurrentContext.DefaultSecurity.GetUser() method, but let’s see how it can be done by querying:

As we are retrieving a user, we create a query of type UserQuery. All queries have properties of type [x]Criterion, where [x] can be Integer, String, Boolean etc. This means that before setting a property value, we always have to define its criterion type. In this case, as the ID is an int we create an IntegerCriterion and assign it to the userQuery.ID property. We can then set its Value. At last, we call the GetQueryResult() method to get the result of the query.

In the previous example we were only looking for one entity. Now what if we have a list of email addresses, and we want to retrieve all the users with those addresses?

One of the most common mistakes when using the query system is to forget an initialization of an object. If we were to remove the second or third line in the example above, we would get the error message: “Object not set to an instance of an object”. If you’re new to the query system, you’ll probably see this message quite a few times before you get the hang of it, but the only thing it means is that you’ve forgotten to initialize one of the objects.

Now, let’s pick up the pace. Searching is an important feature of every website, and in a search you’ll need to do logical operations. If in a search, you want to retrieve all the clubs with the word “Elephant” in the title OR the description, you’ll need to use a Logical OR operator:

In order to do a logical operation in a query, you need a CriteriaGroup to which you can add all the criteria. In the example above we create a StringCriterion for the clubs Name, and add it to the criteriagroup. We then do the same for the description, but now we specify a LogicalOperator. Finally, we need to add the criteriagroup to the query.

In the final example we’ll see how to query attributes.Let us say you’ve created an attribute for type IUser of type string which specifies the user’s phone number. You now want to retrieve a user based on that phone number:

That’s it for now, happy querying!

Monday, September 21, 2009

Customizing an EPiServer Community Module using Attributes

While developing an EPiServer Community or EPiServer Relate+ site, you will find the custom Community modules extremely useful. Sooner or later though, you will realize that you need to customize them in order to fit the customers need.

In this blog post, I’ll walk you through how to customize the ‘Add User’ module in the ‘System Settings’ section of the Community tab. I will not show you how to create a custom module as this has previously been explained by the brilliant Joel Abrahamsson.

So the goal in this blog post is to add a custom field, in this case a phone number, to the ‘Add User’ module:

The first thing you need to do is to create a class that inherits from and extends the EPiServer.Community.Web.Administration.EditUserPage class:

In this class I’ve added the textbox that we’ll include in the page later on, and three methods: OnInit, OnLoadComplete and a click event for the save button. Let’s take a look at the OnInit method first:

First we call the OnInit method in the base class, and then we invoke the buttonSave.Click event by supplying the method, buttonSave_Click. This means that the base class’ buttonSave_Click event will be called first and the buttonSave_Click event in our custom class will be called afterwards. The buttonSave_Click event looks like this:

Now, this is where the fun begins. In order for us to save the new users phone number, we are going to use attributes. For more information on attributes in EPiServer Community, click here. So assuming we have added a PhoneNumber attribute of type string for the type IUser, we will be able to save the phone number.

Before we can do this though, we need to retrieve the user who the phone number belongs to. As the buttonSave_Click event of the base class has already been fired, the user has been created and the only thing we need to do is to get the email address in order to retrieve the user. By snooping around in the base class, you’ll see that getting the email address is as easy as this: tabPageUserSettings.Email

So we now have the email address and are able to retrieve the user by calling the GetUserByUserName method (assuming an email address is used as the username). We then clone the user, set the attribute value, update the user and voilá! The phone number is saved.

So far this will not work as we haven’t changed the @Page directive of the EditUser.aspx or added the label and textbox. So first, change the @Page directive of the EPiServerCommunity\Security\EditUser.aspx so that the page inherits your custom class instead of the default implementation. Second, add a label and a textbox to the EditUser.aspx, make sure the textbox has the same id as in your custom class.

Now everything will work fine, except for one thing: Editing the user. If you try to edit the user you just created, you’ll see that the phone number textbox remains empty. In order to fix this, we need to override the OnLoadComplete method of the base class:

Again, we get the email and using that we retrieve the user. We can then get the PhoneNumber attribute value, and add that to the Text property of the textbox. And we’re done :)

Wednesday, August 26, 2009

Tips and tricks on taking the 70-536 Microsoft .NET Framework – Application Development Foundation exam

One thing I noticed in this exam is that the details of the exam can save you from failing, and the details actually make it easier for you to guess correctly if you don’t know the answer for a question. These are things you would easily notice if you did the exam without a time limit and in your own living room, but as soon as you’re a bit stressed out they’re easy to ignore.

These examples might help you out if you’re absolutely stuck on a question and don’t know what to do.

Example #1:
All the answers for a question look similar, but if you take a good look at them you’ll see that one or two of the answers have nothing to do with the question whatsoever. Let’s say all the answers are lines of code containing a method, and inside the method something is done (it doesn’t matter what). The natural thing to do is to focus on what is done inside the method and how the method is declared, that’s where you assume you’ll find the answer.

But what about the name of the method? I know for a fact that I usually don’t pay attention to the method name unless it’s in a larger context, but you really should. What if, in one of the answers, the method is called SerializeDataSet(…) and the question has nothing to do with serialization? Then you can probably eliminate this answer and you’re one step closer to where you want to be.

Example #2:
As far as I’ve seen, this exam does not contain any trick questions (questions that lead you in the wrong direction). So if a question tells you that you have a variable ‘x’, and one of the answers does not use this variable, you can be pretty sure the answer is wrong.

Example #3:
Make sure you read the questions carefully and more than once. If a question states that a collection should be strongly typed, make sure the answer you choose in fact is strongly typed. If a question asks you to encrypt a file, make sure you choose the answer that encrypts (not decrypts) it. If you’re in a rush, details like these may be easy to ignore.

Last but not least, mark all the questions you are unsure of for review. The other questions in the exam might give you a clue on the way, so you should always go over the questions more than once. And if you don’t know the answer for a question, and you’re not able to eliminate any of the answers, go with your first hunch. Statistics show that your first hunch is more likely to be correct than choosing an arbitrary answer.

Good luck!

Wednesday, August 19, 2009

How to study for the 70-536 Microsoft .NET Framework – Application Development Foundation exam

As I passed my 70-536 exam today, I thought I’d write this blog post to try to help out everyone else out there studying for the exam. Before starting though, remember one thing: This way of studying worked for me, it might not be the best way for you!

Also, Microsoft states that “Candidates should have at least two to three years of experience developing Web-based, Windows-based, or distributed applications by using the Microsoft .NET Framework 1.0, the .NET Framework 1.1, the .NET Framework 2.0, or the .NET Framework 3.5.

That’s really not necessary, I have 6 months of experience and I managed to pass it without too much hassle. It will save you a lot of study time if you have more experience than me though!

Before you start studying you should get an overview of the ‘Skills measured’. Highlight all the topics you know you’re unsure of, and be honest with yourself! If you find yourself thinking “I might know this”, you should assume that you don’t know. You’re not fooling anyone but yourself.

Do the same thing with the contents overview in the Self-Paces Training Kit.(Mind that this exam is exactly the same for .NET 2.0 and 3.5)

After doing this you’ll have a good overview of what the exam covers and how much you know.

The next part is where you need some self control: the studying itself. In my world there are two ways of doing this:
  1. First study for the topics you don’t know, then have a look at those you do know (just to check that your knowledge covers everything)
  2. First have a look at those you do know, then study for the topics you don’t know
If you go for #1, by the time you’re done studying for the things you don’t know, you’ll probably be sick of studying and skip the part where you have a look at what you actually know. So #2 is the best way to go (trust me!)

When having a look at what you do know, quickly browse through the relevant topics in the book. If you see anything you don’t recognize, read it. If you don’t understand it after reading it, you should put it on your ‘Don’t know’ list.

So now you’ve covered everything you do know, and it’s time for the time consuming part: Learning what you don’t know. Read the highlighted topics, and if you don’t understand what you’re reading Google and Bing are your friends.

Each time you’ve covered a new topic, test your knowledge by doing a MeasureUp test (in custom mode - selecting the relevant topic)

And finally, when you’ve covered all of the topics: Do the MeasureUp test in the certification mode. If you don’t pass, you’ll get a nice overview over which topics you don’t know well enough and you can have a look at these topics again. And surprise, surprise: This step repeats itself until you know all the topics well enough!

And one last tips for all the procrastinators out there: As charming as procrastination is, it’s not very helpful. Make a schedule and stick to it! Some blood, sweat and tears later, and you’ll be certified :)

Next time: Tips and tricks on doing the exam itself

Monday, July 13, 2009

Attributes in EPiServer Relate+

Attributes in EPiServer Relate+ is an easy way of extending classes without having to do it programmatically. In order to assign an attribute to an object, the object has to implement the IAttributeExtendableEntity interface and to everyone’s joy most objects in Relate+ do.

In this example each user of type EPiServer.Common.Security.IUser will be able to register their favorite sport of type System.String. The first thing to do is to add the attribute in the Community tab of the edit interface:

The attribute is now defined in the database, so we can set its value:

Getting the attribute value is just as simple:

Now what if we want to find all the users who have rugby as their favorite sport? Most of the EPiServer Community classes allow querying based on a set of criteria, and that’s the way to go:

First a new UserQuery is created and a StringCriterion is added. Multiple criterions can be added if that’s needed. The GetQueryResult method fills up the cache with the query result. Use the RemoveQueryResultCache method to clear the cache:

Piece of cake!