Friday
Jun262009

ASP.NET MVC Membership Management (Users and Roles)

Here at kmsystems we have really been diving into ASP.NET MVC with everyone in the team doing loads of learning, setting up some new projects using MVC and converting over some old ones. Not to be left out of all the MVC fun :) I've decided to dive in and port over a simple team management app we built called "Whos Doin Wot" from the Morfik 2.0 RIA Tool which I put together a while ago now.

The new release of Whos Doin Wot isn't quite ready for use yet however I want to share some of the work I have done setting up user and role management. I'm a big fan of buy borrow, beg, steal before you build or role your own (just can't see the benefit of re-inventing the wheel if a great wheel already exists) so I started my search and found the following:

ASP.Net MVC Membership Starter Kit which is a really promising membership management tool and would have been exactly what I was looking for, unfortunately the current release does not work on MVC Release 1.0

ASP.NET MVC Membership Management Roni Schuetz which also looks great but costs 30 euros (around $50 Australian dollars) and given that it was just a blog post with no comments I wasn't too sure if I was just kissing my $50 goodbye (maybe I'll give it a go later).

As the options to buy, beg, borrow or steal were not that appealing and with the goal of learning more about MVC I decided to (god forbid) roll my own membership management. Anyway it wasn't going into a full blown management tool I wanted to keep it simple and light to just cover off the very basics.

If you are interested I have uploaded the source code for you to download modify and use in your own projects. This code is jsut a very basic base to start from and extend to meet your requirements. It would be great if you could share any improvements back here with us.

The code covers:

- List all users

- Add a new user

- Edit a user

- Delete a user

- View the roles associated to a user

- Remove a role from a user

- Add a role to a user

- List all roles

- Create a role

- Lists users in a role

- Delete a role

The code I created is based on using ASP.NET Membership in a SQL server database by default MVC points to a SQL Express database named "ASPNETDB.MDF"; under the application's "App_Data" directory. If you would like to use a different SQL server or dataabase update the "ApplicationServices"; connection string within the web.config file. You can run the "aspnet_regsql.exe" utility within the \Windows\Microsoft.NET\Framework\v2.0.50727\ directory to add membership and the other ASP.NET application services to any database.

Tuesday
Jun022009

Waterfall charts in SQL Reporting Services

Recently we completed a project to build a KPI dashboard for a large Australian organisation to show certain performance measures for each business unit. The challenge was that the client wanted a very specific kind of chart,  basically a waterfall chart which displays the end target/goal as the final column. Using the Dundas charts control this task would not be that difficult as we could have used a chart similar to this and made a few tweaks.

However due to the clients Reporting Services Architecture the costs of Dundas licenses was not feasible so we needed to come up with a way to produce a similar chart using the native Reporting Services chart control.

Here's what we learned:

  • The chart type to use is a Stacked Column Chart
  • You need to add a data value the represent the data value you want to appear in the waterfall. In our case we added the KPI actuals eg:(Fields!KPIActual.Value)
  • Then you need to add the same data as a second data value to the stacked series as a running total and subtract the individual first data value at each point. We added the same KPI actual data as a second data value which would be stacked below the first but this time using a running total less each KPI actual eg:RunningValue(Fields!KPIActual.Value, Sum, "chart1_SeriesGroupKPI_Measures")-(Fields!KPIActual.Value). We also set the background colour fill for this series to white so that it would blend into the background of the chart an could not be seen 

 The final result was a nice clean waterfall chart that shows progress towards an end target

Monday
Jun012009

Greenhouse and Energy Reporting NGERS

We have been working with one of Australia's largest logistics companies, building various web applications to help improve some of their current business processes. One of the areas we discussed was their environmental impact and reporting requirements under the National Greenhouse and Energy Reporting Act 2007(the NGER Act). In short the Australian Government has passed an Act that requires organisations to report on greenhouse gas emissions, energy consumption and production.

After doing some research into the NGERS guidelines and requirements we have decided to build an application that will:

  • Make it easier for organisations to capture and track information regarding their greenhouse gas emissions, energy consumption and production
  • Provide some value back to the business for going to the effort in capturing this information. Such as a better understanding of environmental expenses and possible areas for improvement/reduction

Currently we are in the process of designing and developing the application. If you and your company need to report under NGERS and would like to talk to us about what could make your life easier in this area. Or if you would be interested in using this tool to make NGERS reporting easier then please contact us

I will add another post soon when we have a beta version ready for people to try out.

Sunday
May312009

ASP.NET MVC Cascading DropDownLists

Creating DropDownLists using WebForms is easy enough, for those who are venturing into the the world of MVC this may not be as straight forward.

I’ll be using the classic scenario of Cars and their related makes and models.

CarController.cs

public class CarFormViewModel
{
MakeModelRepository makeModelRepository =
    new MakeModelRepository();

private string _carMake = "";

public Car Car { get; private set; }
public SelectList CarMakes { get; private set; }
public SelectList CarModels { get; private set; }
public string CarMake
{
get { return _carMake; }
set { _carMake = value; }
}

// Constructor
public CarFormViewModel(Car car)
{
Car = car;
CarMakes = new SelectList(makeModelRepository.
        GetCarMakes(), "Value", "Text");

if (car.CarMakeModelId > 0)
CarMake = car.CarMakeModel.CarMake;

CarModels = new SelectList(makeModelRepository.
        GetCarModels(CarMake), "Value", "Text", Car.CarMakeModelId);
}
}

Something to be aware of is the use of valueSelected when defining your SelectList, make sure your view items e.g. DropDownList names match your database field names. I found the selected value was not being set correctly when editing a records.

CarForm.aspx

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl
<Vehicles.Controllers.CarFormViewModel>" %>

<script type="text/javascript">
$(function() {
$("#CarMake").change(function() {
var carMake = $("#CarMake > option:selected").attr("value");
var urlAction = "<%= Url.Action("FindCarModels", "Car") %>";
$.getJSON(urlAction, { carMake: carMake }, function(data) {
$("#CarMakeModelId").addItems(data);
});
});
});
</script>

<%= Html.ValidationSummary("Edit was unsuccessful. Please correct
the errors and try again.") %>
<%
using (Html.BeginForm())
{%>
<fieldset>
<
legend>Car</legend>
<
p>
<
label for="CarMake">
Make:</label>
<%= Html.DropDownList("CarMake", Model.CarMakes) %>
<%= Html.ValidationMessage("CarMake", "*") %>
</p>
<
p>
<
label for="CarMakeModelId">
Model:</label>
<%= Html.DropDownList("CarMakeModelId", Model.CarModels) %>
<%= Html.ValidationMessage("CarMakeModelId", "*") %>
</p>
<
p>
<
input type="submit" value="Save" />
</
p>
</
fieldset>
<% } %>
<div>
<%=Html.ActionLink("Back to List", "Index") %>
</div>

Make sure to change the inherits property to reference your new ViewModel. Note the use of the Url.Action helper, this little snippet helps you creates the correct path to your controller action without the use of those dots e.g. …/<controller>/<action>/

jHelper.js

Borrowed from Steve Michelotti.

$.fn.clearSelect = function() {
return this.each(function() {
if (this.tagName == 'SELECT')
this.options.length = 0;
});
}

$.fn.addItems = function(data) {
return this.clearSelect().each(function() {
if (this.tagName == 'SELECT') {
var dropdownList = this;
$.each(data, function(index, optionData) {
var option = new Option(optionData.Text,
                         optionData.Value);

if ($.browser.msie) {
dropdownList.add(option);
}
else {
dropdownList.add(option, null);
}
});
}
});
}

Little helper that clears and adds items to DropDownLists.

Something I found frustrating is when in debug mode a script reference would work find but when running using IIS the script would not load correctly. What you had to do was use those good old dots to get it loading correctly. My tip is to use the ResovleUrl helper.

<script src="<%= ResolveUrl("~/Scripts/jquery-1.3.1.js") %>" 
type="text/javascript"></script>

<
script src="<%= ResolveUrl("~/Scripts/jHelper.js") %>"
type="text/javascript"></script>

There are some workarounds I’ve seen that don’t break intellisense but look a bit messy. I figure I’ve lived without it for this long.

Here is the source code, if there is anything that is unclear or you have any questions feel free to email me.

Friday
May292009

Manifesto for Agile Software Development

At kmsystems we have build a lot of software and in most cases the time frame and budget we have to work with is tight, very tight. The challenge is to not only to meet tight deadlines and budget constraints but above all deliver something of value. The output or result of what we develop must add value to our clients existing processes and business otherwise there is no point in building the solution in the first place. I'm talking about not just solving a problem but solving it in the best possible way that adds the most possible value. Let's face it problems can be solved in a lot of different ways for example you can implement a manual process good old pen and paper, use Excel, create a simple Access database, the list goes on. We build software and its our job to ensure that the software solution we provide adds the most value over all options.

To achieve this we have found agile development methodologies to be an effective way to keep costs and time overheads low yet deliver something that the client will use and get maximum value from.

As part of our agile development practises we try to follow the "Manifesto for Agile Software Development"

We are uncovering better ways of developing
software by doing it and helping others do it.
Through this work we have come to value:

Individuals and interactions over processes and tools
Working software over comprehensive documentation
Customer collaboration over contract negotiation
Responding to change over following a plan


That is, while there is value in the items on
the right, we value the items on the left more.

http://agilemanifesto.org/

and we try to up hold these 12 principles which sit behind the manifesto:

  1. Our highest priority is to satisfy the customer through early and continuous delivery of valuable software.
  2. Welcome changing requirements, even late in development. Agile processes harness change for the customer's competitive advantage.
  3. Deliver working software frequently, from a couple of weeks to a couple of months, with a preference to the shorter timescale.
  4. Business people and developers must work together daily throughout the project.
  5. Build projects around motivated individuals. Give them the environment and support they need, and trust them to get the job done.
  6. The most efficient and effective method of conveying information to and within a development team is face-to-face conversation.
  7. Working software is the primary measure of progress.
  8. Agile processes promote sustainable development. The sponsors, developers, and users should be able to maintain a constant pace indefinitely.
  9. Continuous attention to technical excellence and good design enhances agility.
  10. Simplicity--the art of maximizing the amount of work not done--is essential.
  11. The best architectures, requirements, and designs emerge from self-organizing teams.
  12. At regular intervals, the team reflects on how to become more effective, then tunes and adjusts its behavior accordingly.

It has taken us some time to grow and adopt agile development but I think as a team kmsystems has been able to work fairly closely to these principles and deliver some great software especially on a few recent projects. As a leader I trust my teams to get the job done, however one of the obstacles we face over and over again is engaging the customer in the agile process and keeping them engaged for the length of the project. The agile process does require a higher level of commitment from both parties but the output end result is a far better product. Unfortunately this is not easy to demonstrate up front. I think that open honest communication about the process will give your client and you a good start that will carry you through to being able to demonstrate the value. Remember deliver fast and review often.