Archive

Archive for the ‘.Net’ Category

ASP.NET MVC : Accessing String Resources in CSHTML files

April 26th, 2014

When writing web pages in ASP.NET MVC, the standard way of outputting label names is often unsatisfactory as you end up with a label that follows a variable name, e.g. including a line like:

@Html.LabelFor(model => model.PadNumberLength)

ends up showing a label:

PadNumberLength

where you really want:

Pad Number Length

There are a number of other ways of changing the label, e.g. you could put a DisplayName attribute on the property in the model, e.g.

[DisplayName("Pad Number Length")]
public int PadNumberLength { get; set; }

However, especially if you have come to ASP.NET MVC programming from a desktop environment such as Winforms or WPF, the most natural way to get a label name is from a resource file. This also makes it easier to localise your pages in the future.

An ASP.NET MVC project contains a Resources file under the Properties node in the solution explorer. You can put all your string resources in this file. To access the resources in a CSHTML file, include the following HTML helper in your solution:

public static MvcHtmlString ResourceString<T>
    (this HtmlHelper<T> html, string ResourceName)
{
    var Manager = new ResourceManager(typeof(Properties.Resources));
    return MvcHtmlString.Create(Manager.GetString(ResourceName));
}

This means you can then write labels such as:

<label>@Html.ResourceString("PAD_NUMBER_LENGTH")</label>

that output the resource strings from your Properties.Resources file.

Easy Way of Examining Exception Details in Visual Studio

April 16th, 2014

When an exception is raised while debugging an application in Visual Studio, a dialog like the following appears showing a number of options to get more detail on the exception, e.g. the stack trace and line number on which the exception occurred:

One way of digging into the exception to find out more details is to click on the View Detail … link in the dialog. This shows a watch window like view that lets you tunnel into the exception fields.

However, an easy way of scanning all the exception details, is to click the Copy exception detail to the clipboard option, then paste the copied data into Notepad. You then get all the available exception details in a form you can easily scroll through or even search.

Kendo UI Grid: Custom Edit Button for Ajax Grid

September 21st, 2013

While trying to display a list of data in a Kendo UI grid for which the data was loaded via Ajax, I wanted to have a custom command that loaded a new page to edit a row. In the specific case I was looking at, I didn’t want to edit inline or edit the row data in a popup dialog – I wanted to leave the page showing the grid and load a new HTML page to do the edit.

The project I was working on used ASP.NET MVC and the handy Kendo UI MVC wrappers. The key to loading a new page was inserting a clickable link that could call a controller action and pass in the ID of the row to edit. To keep things consistent, I also wanted my link to look like a normal Kendo UI grid edit button.

While I could find examples of how to include custom links when a Kendo Grid was server bound, finding out how to do the same things for an Ajax bound grid was more difficult. In the end I found that specifying a column template like this worked:

columns.Bound(invoice => invoice.ID)
   .ClientTemplate
      (@Html.ActionLink
          ("<span class='k-icon k-edit'></span>Edit",
           "Edit",
           new { ID = "#=ID#" },
           new { @class = "k-button k-button-icontext" }).ToHtmlString());

Note that the first argument to the Html.ActionLink call is usually used to give the text of the link but I also included a span in order to add the correct Kendo CSS classes to make the link look like a button with an edit icon.

The result of the above client template for a column in a Kendo grid is that an edit button like the following is displayed:

kendo-ui-edit-button

and when the button is pressed, the following controller action is called:

/Invoices/Edit/3

assuming that the controller for the grid is the Invoices controller and that the row ID (or primary key of the record for the row) is 3.

Entity Framework Error: OriginalValues cannot be used for entities in the Added state

September 19th, 2013

When saving new entries to a SQL Server database using the Entity Framework, I came across the following exception error:

OriginalValues cannot be used for entities in the Added state

There may be a number of reasons why the exception was raised but I found that in my case I had to check the data I was trying to save to make sure that values were specified for all the fields and that the fields were in the ranges required by the SQL Server database.

Here is a list of the checks I had to implement before writing the data to the database using Entity Framework:-

1. Check that a value required in the SQL database didn’t have a null value, e.g. make sure a string field had an empty value “” rather than null.

2. Check that string values weren’t too long to fit, e.g. check that if the database field had a max length of 40 characters I wasn’t trying to save more characters than would fit.

3. Check that any DateTime fields were not out of range for the SQL DateTime fields. .Net DateTime defaults have the value 1/1/1 but SQL dates have a different range to .Net and cannot accept values of 1/1/1.

For each DateTime field I called this function to check (and force) the fields into a range the SQL database would accept.

public static DateTime Default(DateTime Value)
{
   if (Value == null)
   {
      return DateTime.Today;
   }
   else
   {
      // Check the .Net value is in a valid range for a SQL DateTime.
      if (Value < SqlDateTime.MinValue.Value || Value > SqlDateTime.MaxValue.Value)
      {
         Value = DateTime.Today;
      }
      return Value;
   }
}

ASP.Net MVC Disable Cache To Keep Ajax Working OK

June 15th, 2013

After coming back to my ASP.Net MVC project where I was using the Html.DropDownList scheme I had written about earlier on this blog, I cam across a bug where my dialog containing the dropdownlist wouldn’t show the correct selected item. I could choose a new selected item and submit the form back to the server OK but on reloading the dialog, the first item in the dropdown was always selected. My initial though was that my example code was incorrect and that I needed to start hunting again to find out how dropdownlists really work. However, while debugging, I noticed that the controller action that was returning the partial view for the Jquery dialog containing the dropdownlist seemed to only run once. I had placed a breakpoint in the action and noticed that the breakpoint was only hit when the dialog was loaded for the first time.

I was loading the view into containing the dropdownlist into a Jquery dialog using a load call like this:

$(this).load("@Url.Action("CreateCustomer", "Customers")"

A little research found out that these type of Ajax calls can be cached by browsers. This explained why the load resulted in my action being called once but not a second time – since the IE browser had cached the response.

To get the partial view to load reliably, I ad to disable the cache. To do this I put an OutputCache attribute on the controller action as follows:

[OutputCache(Duration = 0, VaryByParam = "*")]
[HttpGet]
public ActionResult CreateCustomer()

This attribute could be applied at the controller level in order to disable caching for the entire controller:

[OutputCache(Duration = 0, VaryByParam = "*")]
 public class CustomersController : Controller

but for the specific problem I had, it works fine just being applied to my specific controller action.

ASP.NET MVC Html.DropDownList Example

May 24th, 2013

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.

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

May 14th, 2013

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.

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

February 13th, 2013

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 Determine if a Column Exists in a Table

January 20th, 2013

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/

Storing Images in XML files using C#

September 29th, 2012

XML files contain data in the form of text. Any data can be stored in and retrieved from an XML file as long as you can convert the data to text before writing to the XML file and then convert the text from the XML file into the correct data type when reading it back.

To convert and image in to a string so that you can store the image in an XML file, there are a couple of steps to go through:-

1. Convert the image to an array of bytes.
2. Convert the array of bytes to a string.

For this second step there is already a standard encoding scheme – Base64 – for encoding binary (byte) data into a string format. Luckily for both these conversion steps, .Net already includes the necessary classes and methods to do the work for us.

Here is a C# example of converting a PNG file into a string that could then be stored in an XML file:

String TheImageFile = @”c:\about.png”;

Image TheImage = Image.FromFile(TheImageFile);

TypeConverter converter = TypeDescriptor.GetConverter(typeof(Image));

String TheImageAsString = Convert.ToBase64String((Byte[])converter.ConvertTo(TheImage, typeof(Byte[])));

Converting back from a string to an image is a matter of reversing the steps …

Byte[] TheImageAsBytes = Convert.FromBase64String(TheImageAsString);

MemoryStream MemStr = new MemoryStream(TheImageAsBytes);

Image I = Image.FromStream(MemStr);

If you have a document containing a mix of text and images that you want to tidily save into a single file, you can use code like the above to easily store any embedded images as well as the text.