ASP.NET Social Networks—Making Friends (Part 2)

Implementing the presentation layer

Now that we have the base framework in place, we can start to discuss what it will take to put it all together.

Searching for friends

Let's see what it takes to implement a search for friends.

SiteMaster

Let's begin with searching for friends. We haven't covered too much regarding the actual UI and nothing regarding the master page of this site. Putting in simple words, we have added a text box and a button to the master page to take in a search phrase. When the button is clicked, this method in the MasterPage code behind is fired.

Search

The Search.aspx page has no interface. It expects a value to be passed in from the previously discussed text box in the master page. With this text phrase we hit our AccountRepository and perform a search using the Contains() operator. The returned list of Accounts is then displayed on the page. For the most part, this page is all about MVP (Model View Presenter) plumbing. Here is the repeater that displays all our data.

The fun stuff in this case comes in the form of the ProfileDisplay user control that was created so that we have an easy way to display profile data in various places with one chunk of reusable code that will allow us to make global changes.

A user control is like a small self-contained page that you can then insert into your page (or master page). It has its own UI and it has its own code behind (so make sure it also gets its own MVP plumbing!). Also, like a page, it is at the end of the day a simple object, which means that it can have properties, methods, and everything else that you might think to use.

Once you have defined a user control you can use it in a few ways. You can programmatically load it using the LoadControl() method and then use it like you would use any other object in a page environment. Or like we did here, you can add a page declaration that registers the control for use in that page. You will notice that we specified where the source for this control lives. Then we gave it a tag prefix and a tag name (similar to using asp:Control). From that point onwards we can refer to our control in the same way that we can declare a TextBox!

You should see that we have <Fisharoo:ProfileDisplay ... />. You will also notice that our tag has custom properties that are set in the tag definition. In this case you see ShowDeleteButton="false". Here is the user control code in order of display, code behind, and the presenter:

All this logic and display is very standard. You have the MVP plumbing, which makes up most of it. Outside of that you will notice that the ProfileDisplay control has a LoadDisplay() method responsible for loading the UI for that control. In the Search page this is done in the repAccounts_ItemDataBound() method.

The ProfileDisplay control also has a couple of properties one to show/hide the delete friend button and the other to show/hide the invite friend button. These buttons are not appropriate for every page that the control is used in. In the search results page we want to hide the Delete button as the results are not necessarily friends. We would want to be able to invite them in that view. However, in a list of our friends the Invite button (to invite a friend) would no longer be appropriate as each of these users would already be a friend. The Delete button in this case would now be more appropriate.

Clicking on the Invite button makes a call to the Redirector class and routes the user to the InviteFriends page.

Inviting your friends

This page allows us to manually enter email addresses of friends whom we want to invite. It is a standard From, To, Message format where the system specifies the sender (you), you specify who to send to and the message that you want to send.

This is a simple page, so the majority of the code for it is MVP plumbing. The most important part to notice here is that when the Invite button is clicked the presenter is notified to send the invitation.

The interesting thing here is the SendInvitation() method, which takes in a comma delimited array of emails and the message to be sent in the invitation. It then makes a call to the Email.SendInvitations() method.

This method is responsible for parsing out all the emails, creating a new FriendInvitation, and sending the request via email to the person who was invited. It then adds an alert to the invited user if they have an Account. And finally we have to add a notification to the messaging system once it is built.

Outlook CSV importer

The Import Contacts page is responsible for allowing our users to upload an exported contacts file from MS Outlook into our system. Once they have imported their contacts, the user is allowed to select which email addresses are actually invited into our system.

Importing contacts

As this page is made up of a couple of views, let's begin with the initial view.

As you can see from the code we are working in panels here. This panel is responsible for allowing a user to upload their Contacts CSV File. It also gives some directions to the user as to how to go about exporting contacts from Outlook. This view has a file upload box that allows the user to browse for their CSV file, and a button to tell us when they are ready for the upload.

There is a method in our presenter that handles the button click from the view.

This method is responsible for handling the upload process of the HttpPostedFile. It puts the file reference into a StreamReader and then reads the stream into a string variable named contacts. Once we have the entire list of contacts we can then call into our Email class and parse all the emails out.

This method expects a string that contains some email addresses that we want to parse. It then parses the emails using a regular expression (which we won't go into details about!). We then iterate through all the matches in the Regex and add the found email addresses to our list provided they aren't already present. Once we have found all the email addresses, we will return the list of unique email addresses. The presenter then passes that list of parsed emails to the view.

Selecting contacts

Once we have handled the upload process and parsed out the emails, we then need to display all the emails to the user so that they can select which ones they want to invite.

Now you could do several sneaky things here. Technically the user has uploaded all of their email addresses to you. You have them. You could store them. You could invite every single address regardless of what the user wants. And while this might benefit your community over the short run, your users would eventually find out about your sneaky practice and your community would start to dwindle. Don't take advantage of your user's trust!

Now the user has a list of all the email addresses that they uploaded, which they can then go through selecting the ones that they want to invite into our system. Once they are through selecting the emails that they want to invite, they can click on the Invite button. We then iterate through all the items in the checkbox list to locate the selected items.

Confirm friendship

Having covered all these ways to invite someone into our site, we now need to look at what the invited user sees in the invitation. Let's start with what they would see in their inbox.

The user gets an email in their inbox telling them that so and so has invited them to come to Fisharoo. Once they open that email, they can see the request again as well as the link that they can follow to the site to take advantage of the invitation.

As you can see this link brings them to server/Friends/ConfirmFriendshipRequest.aspx with a GUID for an invitation key. There are two screens that the user might see after this point. The first screen is for the users who are already members. It asks them to log in again to confirm the friendship.

The other screen is for the users who aren't members, or the users who aren't logged in.

The only real logic in the ConfirmFriendshipRequest.aspx page is to check the GUID that is passed in to make sure that it is valid. This happens in the presenter of this page.

Either we can load a friendInvitation from the GUID or not. If we can, then we check to see if the user is already a member of the system and logged in. If they are logged in we automatically redirect them to the login screen. Otherwise we prompt them to log in or create an account. If the friendInvitaiton can't be loaded properly, then we show an error explaining that. Where the real magic occurs for the invitation process is in the login and registration pages.

Login

In the login presenter we have added some logic to the Init method to recognize if we have a friendship request or not.

This logic lets the user know that by logging in they will be accepting the friend request. Then in the AccountService.cs file we have added some additional logic. If the login is a success and there is a friend request, we confirm the request and make these two users friends, via the FriendService we discussed in the first part of this article.

Registration

If the invited friend is not already a user of the site, then we allow them to walk through the registration site as normal. Once the registration is complete, we not only register them but we also create the friendship.

Show friends

Now that we have everything we need to invite and accept a friend, we need the ability to see our friends. For this we will add to our Friends section landing page (Default.aspx) a list of all our friends. This will actually be quite easy as we will use our ProfileDisplay user control that we created earlier for our Search page. This page will simply consist of a repeater with our ProfileDisplay control. We set the ShowFriendRequestButton to false as these are already our friends.

Friends on profile

After having a page that shows all of our friends, it should be easy to update our public profile to show a handful of friends. To do this we will open the Profile.aspx page and add to it a bit. We are simply going to add the same sort of repeater to the profile page as we did in the case of the Friends/Default.aspx page.

Status updates

Status updates (our micro blog) are very simple to implement at this point. We will need to open the master page and add a small section to take in and display a top listing of these updates. In our master page we will add a panel to our global display. It will be responsible for taking in new updates as well as displaying the most recent updates.

As you can see, this method simply redirects via the Redirector class to the Profiles/StatusUpdates.aspx page. This then takes us to displaying our top StatusUpdates in the master page. To do this we need to add the method that gets the top N StatusUpdates.

Now that we have a way to capture new status updates as well as a way to display the most recent updates, we need to provide a way for our user to see all of their updates. We will do this with a page dedicated to showing this data.

This page of course has the same plumbing issues as do the others. But it basically boils down to calling into the StatusUpdateRepository and get all StatusUpdates for a given Account. The only difference between this and showing the TopN StatusUpdates, as we did on the master page, is that we will show all the updates here.

Alerts & Offers

Series & Level

We understand your time is important. Uniquely amongst the major publishers, we seek to develop and publish the broadest range of learning and information products on each technology. Every Packt product delivers a specific learning pathway, broadly defined by the Series type. This structured approach enables you to select the pathway which best suits your knowledge level, learning style and task objectives.

Learning

As a new user, these step-by-step tutorial guides will give you all the practical skills necessary to become competent and efficient.

Beginner's Guide

Friendly, informal tutorials that provide a practical introduction using examples, activities, and challenges.

Essentials

Fast paced, concentrated introductions showing the quickest way to put the tool to work in the real world.

Cookbook

A collection of practical self-contained recipes that all users of the technology will find useful for building more powerful and reliable systems.

Blueprints

Guides you through the most common types of project you'll encounter, giving you end-to-end guidance on how to build your specific solution quickly and reliably.

Mastering

Take your skills to the next level with advanced tutorials that will give you confidence to master the tool's most powerful features.

Starting

Accessible to readers adopting the topic, these titles get you into the tool or technology so that you can become an effective user.

Progressing

Building on core skills you already have, these titles share solutions and expertise so you become a highly productive power user.