ASP.NET MVC Html.DropDownList Example

I’ve been struggling for a while to find a decent example of how dropdown lists work in ASP.Net MVC. It seems like a pretty simple thing to do – show a dropdown list with a selected item, allow the user to select a different item then save the new selection back on the server when the user submits the form containing the dropdown. However, it took me a few hours of searching and experimenting to get my dropdown working.

Here’s how I got it working …

1. In the model used to pass data to the view, ensure there are two fields – one containing the list of items to show in the list on the web page, the other field containing the value of the selected item. Here’s a cut down version of my model class:

public class CustomerModelData
{
    // The list of payment terms. This is a list of strings
    // converted into the SelectList type for use by the
    // Html.DropDownList HTML helper.
    //
    public SelectList PaymentTerms { get; set; }

    // The value of the selected item. Note that this is
    // a string, i.e. the same type as the list members.
    //
    // Note that the name of this field is used by the
    // Html.DropDownList helper later in the example.
    //
    public String PaymentTermID { get; set; }
}

2. In the controller, when the view is initially loaded, populate the model fields above with the list of items for the dropdown and the value of the selected item.

// Load the data from the database.
//
CustomerModelData Model = new CustomerModelData();

List<PaymentTermData> DBTerms = DatabaseManager.PaymentTerms;
List<String> DBTermsText = new List<string>();

foreach (PaymentTermData PT in DBTerms)
{
    DBTermsText.Add(PT.ToString());
}

PaymentTermData SelectedTerm = DatabaseManager.SelectedTerm(); 

// Set the list of items for display converting from a
// list of strings to a SelectList.
//
Model.PaymentTerms = new SelectList(DBTermsText);

// Set the selected item for the drop down.
//
Model.PaymentTermID = SelectedTerm.ToString();

3. In the view, plase the Html.DropDownList helper:

@Html.DropDownList("PaymentTermID", Model.PaymentTerms)

Note that there are two parameters to the DropDownList call:

a. “PaymentTermID” – This is the name of the field in the model that contains the selected item.

b.  Model.PaymentTerms – This is the list of items for the drop down.

4. When the user makes a selection on the drop down and then submits the form containing the drop down, e.g. by pressing the Save or Submit button on the form, the same model class (CustomerModelData) can be used to pass data back to the controller:

[HttpPost]
public ActionResult CustomerDetails(CustomerModelData Data)
{
    // The value chosen by the user is now held in the model.
    //
    String TheSelectedValue = Data.PaymentTermID;
    // The list of values is NOT passed back to the controller.
    // This field is now null.
    //
    SelectList TheValues = Data.PaymentTerms;

Note that the value selected by the user has been updated in the model BUT that the list of values is now null. If the view is reloaded at the end of the controller action, the list will need to be repopulated in the model.

There may be other, more efficient ways of handling dropdown lists in ASP.Net MVC but this example works for me and took a surprising amount of time and trials to get to a working state. Initially, I had tried to think of the DropDownList helper as though it was a Winforms combo box where I could pass a list of objects, e.g. the actual PaymentTermData class, together with an instance of the class as the selected item. However this didn’t work and in the end I reverted to a simple type (String) for both the list and selected item in the drop down.

Also check out this post http://www.sliqtools.co.uk/blog/net/asp-net-mvc-disable-cache-to-keep-ajax-working-ok/ for tips on disabling the cache with Ajax requests as I have come across situations where the dropdownlist (and other stuff) appears not to work with the caching enabled.

5 Tips for setting up your business

Once you have your killer idea for a product or service that will fill a proven gap in the market, you’ll need to go about setting up your business. Hopefully you’ll have done your business planning, if you need some tips on this, do look at our other post here. http://www.sliqtools.co.uk/blog/general/hands-up-who-likes-business-planning/

business-seedling

Here are 5 practical steps you’ll need to consider to actually get the show on the road:

1. Get the name right. Make sure it’s a name that sums up what you offer, either your product or what you want to be known for (your brand values).

There are some useful resources on this website: http://www.start.biz/business_names/

2. Register with Inland Revenue for your Tax and National Insurance payments. You can find more information about that, PAYE and importing & exporting here http://www.hmrc.gov.uk/startingup/

3. Assuming you already have the finance you need to start your business, you’ll need to keep track of your money. Regularly recording both the money going out (purchases or expenditure) and the money coming in (sales or income). You can hire a book-keeper to do this for you (if you’re the sort who likes to keep your receipts in a carrier bag and hand them over to someone else!). Or you can log them yourself in a spreadsheet or specialised software. Don’t forget, if your business issues invoices, SliQ Invoicing Plus is perfect for start-ups as it’s very quick to set up and simple to use.

4. Get yourself noticed. Think about who your likely customers are and the best methods of reaching them. Promotion could include the more traditional leaflets and local newspapers which would be effective for a local trades person for example. If you go the online / digital route, make sure your website appears high in the Search Engine rankings. You may need to hire a professional to advise you here. Regarding social media, it’s worth considering a training course or again, hiring a professional. There are some great tips on digital marketing here:

http://www.smartinsights.com/digital-marketing-strategy/customer-acquisition-strategy/digital-marketing-no-budget/

5. Tap into one of the many sources of business advice just to make sure you have everything covered. The Federation of Small Businesses (FSB) http://www.fsb.org.uk/ and the Governments business support https://www.gov.uk/browse/business provide advice on all aspects of running a business.

For more business startup tips, read http://www.sliqtools.co.uk/blog/uncategorized/business-start-up-checklist/.

Unable to update the EntitySet because it has a DefiningQuery and no InsertFunction element exists

While working with SQL Server and Entity Framework the following error was raised after adding a new table into the SQL Database and updating the model in my project from the DB:

"Unable to update the EntitySet 'Customers' because it has a DefiningQuery and no <InsertFunction> element exists in the <ModificationFunctionMapping> element to support the current operation."

The error was raised as an exception on calling the SaveChanges method on the context after adding a new record into a list/ table on the database.

The solution to the problem was simple – although my new SQL table had an ID column, I hadn’t set the column as the primary key. Setting the column as a primary key in SQL Server Management Studio then going back to my Visual Studio project and rebuilding the entity model from the database made the error go away and let me successfully save new records to the table.

One click to maximize Internet Explorer from the Task Bar

On the whole I prefer using Microsoft’s Internet Explorer to Firefox, but one of IE’s most annoying default features for me is that when you have a few tabs open showing different web pages and you want to click on IE in the task bar in Windows 7 in order to maximize IE and show the last web page you were looking, Windows shows a list of all your open tabs, forcing you to pick a specific tab. I’ve no idea why this is the default behaviour in IE as it mean you have to find the last web page you were looking at in the list then click again to maximise the web page in IE.

However, you can change this behaviour and make IE work like Firefox and simply maximize with the last page you were looking at with one click on IE in the task bar.

To change the setting, do the following …

1. Run Internet Explorer.

2. Press the Alt key on your keyboard so that IE shows its main menu at the top.

3. Click on the Tools menu and choose the Internet Options menu option.

IE will then show the Internet Options dialog.

4. Click the Settings button in the Tabs section as shown in the picture below.

internet-explorer-tabs-options

IE will then show the Tabbed Browsing Settings dialog.

5. In the Tabbed Browsing Settings dialog, uncheck the option “Show previews for individual tabs in the taskbar” as shown in the picture below.

tabbed-browsing-settings6. Click OK to close the options dialogs, then close IE and reopen it.

Now, IE maximises from the taskbar in a single click.

For more Windows tips, see:

http://www.sliqtools.co.uk/blog/windows-help/windows-8-how-to-set-live-mail-as-the-default-email-client/

SliQ Invoicing Plus Version 4 Released

Version 4 of SliQ Invoicing Plus has now been released, 18 months after the release of version 3. Version 4 includes a range of updates requested by our users as well as a refresh in the look of the package.

In version 4, even more flexibility has been included and now customers can customise the standard reports or even copy the reports to create whole new reports. As with our previous versions, all our reports can be exported to Microsoft Excel. Reports can be customised by adding more columns, filtering and sorting any of the columns as well as adding custom groups.

Going along with the theme of increasing flexibility, all the major lists shown in SliQ can also now be customised, e.g. the Invoices & Payments tab list can be customised by adding the invoice delivery address.

The recurring invoices facility has also been overhauled and in V4 it is now possible to create recurring transactions. The new recurring transactions facility makes it easy to change tax rates in the middle of a recurring billing cycle, e.g. if the VAT rate changes.

Many more new features are included in V4 including sales receipts, a sales margin calculator, support for multiple addresses and delivery addresses per customer or supplier, multiple contacts per customer/ supplier, customer price bands and a wizard to help assign customer payments to multiple invoices.

As with our previous major releases, a program of updates is planned on a regular cycle over the new few months.

Version 4 is available for a one-off price and includes a free 30 day trial. V4 is 100% compatible with all previous versions from V1 to V3 and will automatically import and convert all data and settings from older versions when installed on the same PC as a previous version.

For more information on the new features in version 4, check out our Release History page.

Monotouch Exception: This class is not key value coding-compliant …

While writing an iPad application in Monotouch I started getting the following exception while running the program in the iPad simulator:

Objective-C exception thrown.  Name: NSUnknownKeyException Reason: [<MainView 0x99d1460> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key buttonSetup.

Stunned by how unhelpful the exception message was I tried to track down the cause of the error. The only clue the error message gave me was that buttonSetup was the name of a UIButton I had previously had on my main view in the application. However, I had renamed the button so theoretically there were no references to the button left in the project. After reopening the xib for the view in XCode, I tried to track down any remaining reference to the button with no luck until after a few minutes clicking round, I found the following view in Xcode – the Connections Inspector view – which showed a remaining reference to the old button name in the Referencing Outlets:

monotouch-remove-referencing-outlet

To get to the Referencing Outlets section, I clicked on the renamed button (in the pane shown on the left in the pic. above) then opened the Connections Inspector using the toolbar button shown on the top right in the pic. The red rectangle on the bottom right shows the extra referencing outlet to the old control name that I had to remove to get the project to run without an exception. Removing the buttonSetup referencing outlet was easy – just click the x on the File’s Owner widget.

SQLite: How to get the row ID after inserting a row into a table

When working with SQL databases it can often be useful to keep a record of the ID of the row in a table from which a piece of data was read. For example, if you have a Customers table in a database then if you populate a list of Customer objects in your application from the rows in the table, storing the row ID for each object lets you easily update the correct row if you edit the values in one of the Customer objects.

In SQLite, if you have a field of type INTEGER PRIMARY KEY in a table, the database engine will automatically fill the field with the ID for the row. When you insert a new row in the table, e.g. add a new customer into the Customers table taking the example above, then you will need to find out the ID of the new row so you can write it back into the Customer object you’ve just added.

SQLite has a special SQL function – last_insert_rowid() – that returns the ID of the last row inserted into the database so getting the ID of a new row after performing a SQL insert just involves executing the last_insert_rowid() command.

Here is an example in C# showing how to get the ID of the last row inserted into a table in a database.

Create the SQLite database and open a connection to it:

 String mPathName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "testdba.db3");

 SQLiteConnection.CreateFile(mPathName);

 // Open a connection to the database.
 SQLiteConnection Conn = new SQLiteConnection("Data Source = " + mPathName);

 Conn.Open();

Create a table (Customers) in the SQLite database:

 // Create a table.
 //
 String SQL = "CREATE TABLE Customers (ID INTEGER PRIMARY KEY, UNIQUEID VARCHAR(30), ADDRESS VARCHAR(100))";

 SQLiteCommand Command = new SQLiteCommand(SQL, Conn);

 // Create the table.
 //
 Command.ExecuteNonQuery();

Insert a row of data into the table:

 // Reuse the command object and insert a row into the table.
 //
 Command.CommandText = "INSERT INTO Customers (UNIQUEID, ADDRESS) VALUES (@UNIQUEID, @ADDRESS)";

 Command.CommandType = System.Data.CommandType.Text;

 Command.Parameters.Add(new SQLiteParameter("@UNIQUEID", "Fred Bloggs"));
 Command.Parameters.Add(new SQLiteParameter("@ADDRESS", "Acacia Avenue"));

 int Status = Command.ExecuteNonQuery();

Now get the ID of the last row inserted:

 Command.CommandText = "select last_insert_rowid()";

 // The row ID is a 64-bit value - cast the Command result to an Int64.
 //
 Int64 LastRowID64 = (Int64)Command.ExecuteScalar();

 // Then grab the bottom 32-bits as the unique ID of the row.
 //
 int LastRowID = (int)LastRowID64;

Note that in SQLite the row ID is a 64-bit integer but for all practical database sizes you can cast the 64 bit value to a 32-bit integer.

For more SQLite database tips check out:

http://www.sliqtools.co.uk/blog/net/sqlite-how-to-determine-if-a-columns-exists-in-a-table/

SQLite: How to Determine if a Column Exists in a Table

As part of developing a new application using the SQLite database I need to perform some standard database checks when the application starts. Firstly I need to check that the application’s database exists and then either create the database if it doesn’t exist, or, if the database does exist, check that the tables in the SQLite database contain the columns expected by the app.

Checking whether the Database Exists

Checking that the SQLite database exists is easy, I can simply use code like:

if (!File.Exists(mPathName))
{

i.e. I can use the normal System.IO methods in .Net to check whether the database is present.

Creating a SQLite Database

Creating a SQLite database is also straightforward in SQLite. I can create the database file as follows:

// Create the database file.
SQLiteConnection.CreateFile(mPathName);

// Open a connection to the database.
using (SQLiteConnection Conn = new SQLiteConnection("Data Source = " + mPathName))
{
    Conn.Open();

    // Create the required tables. In this example, I'm creating a Customers table with 3 fields - ID, UNIQUEID and DATAFIELD.
    String SQL = "CREATE TABLE Customers (ID INTEGER PRIMARY KEY, UNIQUEID VARCHAR(30), DATAFIELD VARCHAR(100))";

    using (SQLiteCommand Command = new SQLiteCommand(SQL, Conn))
    {
       Command.ExecuteNonQuery();
    }

    Conn.Close();
}

This is all pretty standard SQL and ADO.Net.

Checking if Columns Exist in the SQLite Database

Checking whether columns exist was a little harder to work out for SQLite. Some other databases I’ve used has special methods to get the tables, columns and their attributes. SQLite didn’t have a class to enable me to do this quite so obviously but after some research and experimentation, I found the following code worked:

// Open a connection to the database.
using (SQLiteConnection Conn = new SQLiteConnection("Data Source = " + mPathName))
{
    Conn.Open();

    // Get the schema for the columns in the database.
    DataTable ColsTable = Conn.GetSchema("Columns");

    // Query the columns schema using SQL statements to work out if the required columns exist.
    bool IDExists       = ColsTable.Select("COLUMN_NAME='ID' AND TABLE_NAME='Customers'").Length != 0;
    bool UNIQUEIDExists = ColsTable.Select("COLUMN_NAME='UNIQUEID' AND TABLE_NAME='Customers'").Length != 0;
    bool ElephantExists = ColsTable.Select("COLUMN_NAME='ELEPHANT' AND TABLE_NAME='Customers'").Length != 0;

    Conn.Close();
}

A statement like

ColsTable.Select("COLUMN_NAME='ID' AND TABLE_NAME='Customers'")

returns an array of DataRows. If the column doesn’t exist an array of length 0 will be returned, hence the .Length != 0 check.

Adding a Column if it doesn’t Exist in the SQLite Database

Adding a column to a SQLite database can be performed using standard SQL statements.

String SQL = "ALTER TABLE Customers ADD COLUMN ELEPHANT VARCHAR(100)";

using (SQLiteCommand Command = new SQLiteCommand(SQL, Conn))
{
    Command.ExecuteNonQuery();
}

It turns out that performing these basic operations on a SQLite database is pretty straightforward when you know how. One thing I haven’t bothered to find out yet is to determine whether a column has the correct attributes, e.g. my example ELEPHANT column may change from a 100 character to a 200 character wide column between different versions of the application. However, I’ve never had a good reason for doing such a database update in the past. I’m also relying on the SQLite feature where the database will store any sort of data of almost any length in any column.

For more SQLite tips, see:

http://www.sliqtools.co.uk/blog/technical/sqlite-how-to-get-the-id-when-inserting-a-row-into-a-table/

Human-Centered Design – An Introduction to Designing for Ease of Use

Designing products that are easy to use is not a simple exercise. After a number of years spent designing a range of PC and industrial products, my experience is that those products which appear the simplest, cleanest and easiest to use are, more often than not, the ones that took the most amount of effort to design and complete. Constructing a product that simply exposes every possible feature at once to the user is relatively easy. What’s more difficult is prioritising the user interface, making the most frequent and essential elements readily available while pushing the more advanced, less frequently used features into the background.

human-centred-design

One of the biggest obstacles to overcome when beginning to design anything that is easy to use is the designer’s ego. Almost all designers, whatever their field, e.g.  software, mechanical, usually hold some sort of innate belief about what the user wants and what the best solution should be. This is a natural and essential requirement for any designer. Without the self-belief and initiative to construct a solution a designer would not be able to form an innovative solution for a user need. However, in any mature development process, the ultimate design of a product should not be allowed to rely on what may turn out to be a prejudice, personal desire or pet theory of the loudest or most assertive engineer (or manager) on the team.

One process that can be adopted in any development program is Human-Centred or User-Centred Design. For a process that has sounds rather complicated, it’s actually based on some very simple and low-tech ideas. To describe HCD, let’s break the development process into 3 distinct stages:-

1. Understand the user’s requirements for the product.

In particular try to gain an understanding of the user’s pain point or difficulties.

2. Innovate and design a solution for the user’s product requirements.

3. Test and evaluate the solution with users.

Take the lessons learned and go back to stage 1.

Repeat steps 1, 2 and 3 as required. Any development is a compromise and engineering judgement needs to be used to decide when the improvements are no longer worth the effort of repeating the cycle. HCD techniques come into play mainly in stages 2 and 3 giving the solution developers a set of techniques for presenting and evaluating solutions with users as well as techniques for prioritising evaluation results.

I opened this post by saying that designing for ease of use is not a simple exercise. Although there are only 3 steps listed above they all involve a lot of work, usually over a significant period of time. Adopting HCD techniques can help you increase the chances of a successful development. I’ll elaborate on the HCD techniques in a follow-up post.

Apple Mac: How to Take a Screenshot

One nifty feature I’ve found with my new Apple Mac Mini is that taking screenshots is real easy. If you want to capture an image of a portion of the desktop, simply type the key sequence:

cmd-shift-4

i.e. press down both the cmd key and the shift key then press the 4 key at the same time.

The Mac then displays cursors that you can drag with the mouse to grab any portion of the screen you like – press the left mouse button to begin capture then move the mouse to encompass the desired are before releasing the left mouse button to complete the capture. The image is then automatically saved as a PNG file on the desktop.

After the image is saved onto the desktop, double-clicking the image with the mouse displays the image in the Preview tool. The Preview tool contains a number of handy features, e.g. the Tools menu lets you resize the image and the File menu contains options to export the image in different formats, e.g. as a .JPG file.