June 2007


This story went very well. I also got to learn more about how to customize fields in a gridview a little better.

Basically, the requirement is to create a page that allows a user to see another student’s profile — that is, their alias, first name and last name, and About Me text. It’s actually quite similar to the user’s own profile/account page, except that this (for obvious reasons) shouldn’t be editable, and that we’re not retrieving the logged-in user’s id, but specifying one on the request.

After basically taking the My Profile markup and modifying it for this page, it was nearly done. Putting a test parameter on the request wasn’t too difficult, and I find it interesting how the URL ends up being something like:

~/Classes/ViewStudent.aspx?user=15ea2612-f67c-4e00-874b-19a216316b32

It seems pretty unwieldy, but when I think about it, this is good in that it makes it harder to guess what someone’s userid is. Not that it wouldn’t be too difficult though.

Anyway, here is the View Student page:

View Student

The second part of this was to link to this page from the View Class and View Study Group pages.. specifically to change the text of the user’s alias into a hyperlink. I did some exploring and figured out how to configure a hyperlink field that accomplished this. Below is a screenshot of the View Study Group page with the new hyperlinked field (which I labelled “User”).

View Study Group with User Links

This was somewhat of a challenging user story, but after several attempts, I got it working. I realized in the process that I need to beef up some of my database skills, but the main thing is that for now it works alright.

The main task was to make URLs for the current user’s classes and associated study groups. For this, I needed to get the user id, the class id, the class name, the study group id, and the study group name. Unfortunately these were spread apart in several different tables, and up to this point I had only done joins on two tables.

I did a little searching, and although it’s not the best performance-wise, it’s acceptable to do a join on 3 or 4 tables… and this is basically what I did to get the feature working. I had a little trouble at first with the syntax, ending up with too many matching records because I didn’t specify all the necessary conditions across all tables for the userid to remain constant. After fixing this, it seems to work well, and I set up the links to use the study group and class ids to open the view class and view study group pages without a hitch.

A screenshot of the implementation for one user:

My WBI

I wasn’t quite sure what to call this page, as it isn’t technically the home page, but it is the main page that users should go to after login. I finally settled on “My WBI”, which I don’t really like, and feels oh-so-dot-com-bubble-ish. But oh well.

We are already on our 4th iteration of the project. I’ll be having a semi-long break after this iteration for a trip overseas, so I don’t want to end the release in the middle of some major feature.

Here are the customer user stories for this release:

  • Allow student users to view the classes they are enrolled in (show class name), as well as which study group they belong to (show study group name). The class name and study group name should link to the view class and view study group pages respectively, with the appropriate parameters selected. Also, this should be the first page they come to after logging in.
  • Allow student users to see the profiles of other students in their class and/or in their study group, by clicking on their name in the class enrollment list, or their study group page.
  • Add support for viewing an instructional unit for a class. The view class page should list all the instructional units for the class, with relevant data.

Ok… whew. That’s a lot of story, so let’s see how the estimates come up from the development perspective.

  • Allow student users to view their classes enrolled in and the study group they are in. These names link to view class and view study group pages. Make this the page to redirect to after login. (1 hour)
  • Allow student users to see the profiles of other students in their class and/or in their study group, by clicking on their name in the class enrollment list, or their study group page. (1 hour)
  • Design an instructional unit table and update the database. Add test data. (1 hour)
  • Show the instructional units for a class in the view class page, with associated fields. (1.5 hours)
  • Make an administrative area for admins and teachers, where they can create and edit instructional units. (1.5 hours)
  • In the list of classes in the view my classes page, show the current or latest instructional unit for each class, along with their mastery goals. (1 hour)

As you may have seen, we just don’t have the bandwidth to tackle the last customer story, which may be just as well, considering it opens a whole new can of worms. The stories already committed for this release are fairly significant in themselves, and the estimates assume that the pace will start to quicken more.

Although some early stories were much more difficult to implement, the release ended with some real, tangible progress in using ASP and in moving the application forward. With the implementation of a few more pages, I expect that most of the groundwork for the user accounts will be laid down, and we’ll get into the meat of the mastery learning application.

I’ve written at length in this week’s posts on some of my complaints about ASP, but at the same time, I don’t want to give the impression that ASP is a flawed approach. I think it, like many Microsoft products, has to be many things to many people, simply since MS is so dominant in the marketplace… and I can certainly understand how trying to market for the widest audience possible would make certain design decisions difficult.

That being said, I think I need to start revisiting the books I was reading at the beginning of the project to review some of the examples and tutorials. As I’ve encountered roadblocks, I’ve typically found answers in a variety of places and done all sorts of my own experimentation. I’ve noticed that at least with my own foray into Agile programming, there’s been an unconscious pressure to keep adding functionality, without taking enough time to evaluate what other alternative approaches exist. Maybe this is just my own fault for not building this in to the process, but I find it hard to see how a developer could go to a customer and ask for time to explore and evaluate design alternatives that may not even exist. I guess what I’m saying is that the Agile process seems to fall a little short for me in terms of promoting the kind of learning and analysis that would pay big dividends later on. But in pretty much every other respect, I thoroughly like the fact that an Agile approach has kept me focused on getting things done.

I think I can improve on my estimates, but it’s the estimates on tasks I’ve never done before, which are still going to feel like shots in the dark. I made several design errors that put me back a few days in the last few weeks, but that’s pretty much to be expected given my inexperience. And it’s to be expected in the future for at least some time as well.

I have time for 1 more iteration before I am going overseas for vacation, so I hope to build something worthwhile on this past release, and cement some of the ASP concepts I’ve been running through so that when I get back, I haven’t totally forgotten how to do things.

This story didn’t involve writing any production code, but it was a good, first foray into the world of enterprise application design. All I can say for now is that most of the stuff I read was over my head, because there are just too many issues and concepts that I haven’t had a lot of exposure to.

The short version of my conclusion of all this, is that this isn’t the best time to learn how to re-architect the application, for several reasons:

  1. This is not what you’d call an “enterprise” application.
  2. I assume you should have a pretty solid, broad understanding of the basics of ASP and its relevant abstractions, since this essentially involves peeking under the hood and doing things much differently than all the Microsoft books show. It’s pretty clear after reading around a bit that the prescribed Microsoft approach is the use of the drag-and-drop Designer and code generation tools, and that there is a bit of a learning curve to doing things a different way.
  3. What we have now is “good enough.” And if it’s good enough, then there isn’t a compelling reason to improve it, in the face of other more urgent requirements and features.

On the flip side, I do want to learn this stuff at some point, but it will probably be after I feel much more comfortable with ASP, and am out of exploration and trial mode. This may not happen before the end of this project, but one can always hope. :)

Anyhow, here are two articles by Frans Bouma that provided some good perspective and big-picture understanding of entity classes and the domain model approach:

Solving the data access problem

The Database model is the Domain model

This story turned out to be pretty easy, and looking back, I’m not even sure why I only put this down as the only part for this story. Anyhow, it was easy enough that I decided to try for the next story as well for today, and got that done too. To summarize the changes:

  1. I made a new master page for non logged in users, and then made the login page inherit off of that instead of the original template. That way, there isn’t any irrelevant navigation bar and “login” link.
  2. I set the page title for all the existing pages. Turns out this is an easy to access attribute in the page directive which sets the master page.
  3. I added breadcrumbs in the navigation area for logged-in users.
  4. I fleshed out the student user navigation menu, adding a My Classes and My Study Groups nav heading. These point to placeholder pages for now — nothing implemented, but eventually something will be there.

You can see the results of #3 and #4 here:

Breadcrumbs and Navigation

These two stories went well, and were accomplished in less than an hour. How we only have one more story left in this release before the retrospective.

Wow… another story that was straightforward. I’m on a roll.

Today’s story had two parts that were essentially doing the same thing — we previously were displaying just a username for the list of students in a class and in a study group. Now, we want to use the new UserInfo table to draw out the user fields, specifically alias, last name, and first name.

I set up a data source to do a join on the UserInfo table and the User_Classes, and User_StudyGroups tables respectively, which gave me the relevant records, and did a display on the user information without any hitches.

View Class 3

Since everything went quickly, I also added the class name on the view study group page, since it’s relevant as to which class the study group is for.

View Study Group 2

This story definitely didn’t take the 1.5 hours estimated, which is great. It looks like for the features where I’ve done something similar before, it’s taking a fraction of what I estimated, so I can start to reduce estimates on those types of features. On the other hand, if some of the stories from earlier in the week reveal, I’m underestimating tasks that I have little or no experience in. It’s starting to balance out in this release, but I’d rather be closer on both types of estimates in the next release.

Finally, I had a good story today! After all the difficulty the last few days, it was nice to have something working more or less the way I expected it to work. In this story, I had to add the associated study groups to the View Class page, using the data from the new DB structure.

I set up the datasource and control fine, but there was another part to the story, which was to add a link per each study group record to the view study group page, which uses the study group id as a request parameter.

Luckily, in the gridview control, you can add a HyperLink field, and this one was actually intuitive enough that I pretty much got it after a few attempts, without having to search online due to weird errors. So here’s the new class page with associated study group info:

View Class 2

You can’t see the URL that the View links point to, but basically they take the studygroupid and pass it in as a parameter, like so: ~/StudyGroup/StudyGroup.aspx?group={0} Where {0} is the StudyGroupID.

If it looks rather unimpressive, well, that’s because it is. I don’t know if that’s a testament to my slowness at “getting” ASP, or because of the convoluted way in which ASP is set up. But at least it works correctly now. Tomorrow’s story is to then fix the enrollment info to show user information from the new UserInfo, rather than displaying a UserID. After all, we don’t want students addressing each other, e3da843-ffd3423.

Finally. Well, yesterday I talked about another roadblock I hit for the view profile page. The roadblock is this: I need the UserID of the user, so that I can retrieve just a particular user’s information (first name, last name, alias, etc.). Unfortunately, even though that seems just about the most basic piece of information that ought to be somehow available somewhere in the ASP wizard-like syntax… it isn’t.

Through a bunch of searches online, I found out that there is a programmatic way to get the userid pretty simply, but then how do I specify a dynamic value inside the datasource that sets up the select statement, which is itself a wizard? I couldn’t just specify a programmatic call inside that wizard. So I remembered a technique from an earlier reading, in setting up a hidden label which has the appropriate value.

I did this, but the value wasn’t appearing… I was just getting a blank. I struggled a lot with this until I was just about ready to give up, and just tried for kicks to make the call not in the page itself, but in the page load event handler instead. All of a sudden it works, which means that I don’t have a solid grip on the page lifecycle in ASP, because I had assumed that making the call in the page load event handler was too late for the select statement.

Finally, I had to rewrite the form fields to use a DetailsView. I tried for awhile to just take straight fields, but felt like I was swimming upstream to set up a view and edit for the various fields, so I caved in and used the DetailsView control, which (admittedly) easily sets up a view/edit operation on a data source. If only it didn’t insist on working the way it does.

My Account 2

Regardless, this story is finally done, much longer than I had anticipated. However, I’m not going to pus out other stories from this release, and instead extend the anticipated release date by a few days, especially since last release cut a story short. If I run into more problems in future stories, then I might consider pushing out one or two at the end. We’ll see.

Well, today was another struggle. I was able to fix the create user page, and the good news is that I feel like I understand the create user wizard a lot more now, and how the lifecycle of user creation happens. I also am getting a better sense of how the HTML-like syntax of defining an SQL Data Source actually gets converted into an SQL statement that is executed. It seems to me that there’s a whole abstraction layer on the SQL statement that is just a thin wrapper. I guess it’s there to enable more simple drag and drop/code-less query generation, but again, it feels overly constricting.

I don’t want to get too down on ASP. I think part of the issue is that I’m jumping in at ASP 2.0, which added a lot of these wizards and code generation controls, which I assume that if you programmed in ASP prior to 2.0, you had to do manually. So the wizards are a nice breath of fresh air, which automate a lot of the repetitive work that had to be done before. The problem, though, is that if you just learn the wizard, you have no idea what’s going on underneath the hood, which in my experience, has been very frustrating. It’s surprised me how simple what some of these “magic” controls are abstracting, and I wish I could’ve started learning from a different set of books that took a more in-depth approach.

Anyhow, maybe this revelation has to somehow play into the next round of release planning.

The point of today’s story is that I did fix up create user by removing the Profile system calls, and instead setting up a data source to do an insert into the new UserInfo table, right after the user is created. After I figured out what was going on, it wasn’t too difficult.

I also removed the whole security question and answer thing. I previously thought it was a nice feature that was simple to have in there, but it makes creating test users all that much more tedious, and the customer never asked for it in the first place. I should’ve never left it in there. (And I’m sure Agile proponents would be thinking YAGNI right now.)

Anyhow, that’s done, but I hit another major roadblock for View Profile, so this story is going to have to continue into tomorrow.

Next Page »