Archive

Archive for the ‘c#’ Category

How to run MvcMusicStore v3.0 with SQL Server Express

November 11th, 2011 4 comments

I’ve been trying to do the MVCMusicStore v3.0b tutorial, and I wanted to use SQLExpress rather than SqlServerCe.4.0.
When trying to do this I ran into a number of problems but I finally figured it out.

This guide assumes you already have a working copy of SQL Server Express and that your user account is a System Administrator for the database.

This is the link to the PDF document for the v3.0b tutorial. MvcMusicStore v3.0

(*all page numbers quoted as on the document, page 45 is actually Page 46 when listed in Acrobat)

Below is what I did and the 2 solutions that I found..

  1. As on page 45* I created the AppData Folder.
  2. I downloaded the MVC assets and extracted the files from the zip file.
  3. Right click on AppData and add an existing file, and add in the MvcMusicStore.mdf.
  4. Edit the web.config and added the following connection string:
    <connectionStrings>
      <add name="MusicStoreDb"
        connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|MvcMusicStore.mdf;Integrated Security=True;"
        providerName="System.Data.SqlClient" />
    </connectionStrings>
    	
  5. Added the MusicStoreEntities.cs as on page 47.

At this point Debug the site and I was getting errors. First I was getting errors about meta data failures.
I managed to play a bit more and somehow fixed the meta data issues so that it was no longer erroring, but the queries were not returning any data.

Then I noticed the following 2 issues:

  1. Write some code like the following
    			MusicStoreEntities db = new MusicStoreEntities();
    			string connection = db.Database.Connection.ConnectionString;
    		

    Run up in debug and check the value stored in the connection string.
    Note that the database name is related to the application MvcMusicStore, “MvcMusicStore.Models.MusicStoreEntities”? WTF?

  2. Put a watch on the db.Database.Genres object and note the sql statement is is going to execute. The table name is “dbo.Genres”.
    The issue? Your datbase doesn’t have a “Genres” table it has a “Genre” table (minus the ‘s’).

Solution 1

So to fix these issues I have done the following:

  1. Create a default constructor in the MvcMusicStoreEntities class like follows:

    public MusicStoreEntities()
    {
        this.Database.Connection.ConnectionString = 
               ConfigurationManager.ConnectionStrings["MusicStoreDb"].ConnectionString;
    }
    

    This over-rides the connection string with the one that we have specified in the web.config.

  2. Pluralise your database.

    If your hosting your database on SQL Server you can use the SQL Management studio, or if you are hosting it in AppData then use the server explorer.
    Right click on each table and select “Open Table Definition”. Press F4 to view the properties window, Edit the “Name” property and change the name of the table and add an ‘s’ to the end, Genre -> Genres, Album -> Albums, Artist -> Artists etc. Save the file to apply the name change.

  3. Edit: A bit more digging and I also found this solution to the Pluralised problem, this removes the pluralised table names. Probably a bit easier than the above solution
    In your MusicStoreEntities class add the following

            using System.Data.Entity.ModelConfiguration.Conventions;
    
            protected override void OnModelCreating(DbModelBuilder modelBuilder)
            {
                modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
            }
    
  4. Debug your site and it should all work now.

Solution 2

In attempting to work out the above solution I also found a second solution.

  1. Ensure the constructor is removed from the MusicStoreEntities class.
  2. Edit the web.config file and add the following connection string

    		<connectionStrings>
    			<add name="MusicStoreDb"
    			  connectionString="Data Source=.\SQLEXPRESS;Integrated Security=True;"
    			  providerName="System.Data.SqlClient" />
    		</connectionStrings>
    		
  3. Add the Sample Data as on page 47 & 48 of the PDF guide.
  4. Debug your site and it should work.

    Launch SQL Mangement Studio and refresh the list of databases, you will see you new database [MvcMusicStore.Models.MusicStoreEntities] and look at the tables and they have pluralised names.

Hope this works for you as it did for me. Happy MVC’ing.

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)

Categories: c#, MVC Tags:

Setup App.Config during .msi install, msi re-installing

August 17th, 2011 No comments

The Issue

I wrote a windows form application that deployed  via an .msi installer.

The application has an App.Config file which contains a single configuration value. I wanted to prompt the user for this value during the installation wizard and write it to the application.exe.config file as part of the installation process.

I used the built in Setup project in Visual Studio 2010.

The solution

I could write it all here in my post but I have found one that was created earlier:

http://raquila.com/software/configure-app-config-application-settings-during-msi-install/

I essentially implemented the same solution but I wrote my .config file using a StringBuilder and deleted and re-wrote the.config file in the Post install custom action.

The other thing is that I created short cuts to the application by right-clicking on the primary output and chosing “Create Shortcut”, then I copied this to the desktop and users program menu locations.

The problem

I was installing this for “Everyone” and it would work fine for me, but when other people logged in and tried to launch the program the .msi would run and the application.exe.config file was being overwritten with the orginal version that was deployed with the .msi, which does not contain the users input.

The Fix

The problem is complicated and is related to the application short-cut.

It appears that by default the short-cuts created in the msi are “Advertised ShortCuts”.

According to microsoft when an advertised shortcut is activated “.. the installer verifies that all the components in the feature are installed before launching this file”.

This means that if you delete any of the files that were deployed to the installation location then the .msi will attempt to fix them and re-install the missing components, which in my case means that the application.exe.config is overwritten.

You can identify the “Advertised” short cut by looking at the “Properties” of a short-cut and the “Target” will be greyed out.

I found the post below that identifies an easy way to disable advertised shortcuts.

You need to set the “DISABLEADVTSHORTCUTS” property on the .msi. This can be done easily in the installer, by switching to the “user interface editor” and adding a custom textbox page to the UI. This does mean that you will have an empty step in your installation however, so think of some nice use for it like a warning message about this being a free product??

I acutally have my custom UI that is getting details from the user for the “Edit1Property” so in the Edit2Property I set these values and keep it invisible, (otherwise you would set it in Edit1Property)

  • Edit2Property: DISABLEADVTSHORTCUTS
  • Edit2Value: 1
  • Edit2Visible: false

This updates the property table in the .msi and now all your short-cuts will be normal standard shortcuts.

http://social.msdn.microsoft.com/forums/en-US/winformssetup/thread/b0a3e6d5-38f0-4a37-9418-dd8d9297ef97/

Cheers 🙂

Final Tip: Setting the shortcut icon

Another tip is to set the icon based on the icon embeded in your .exe.

  • In the File System Editor, click on the ShortCut and view the properties
  • Click on the icon property
  • choose browse,
  • change from .ico to .exe
  • browse to the “Primary-Output for…” and choose OK.

It will show you the icons embeded in your .exe and this way you don’t need to deploy a seperate .ico file.

VN:F [1.9.22_1171]
Rating: 10.0/10 (1 vote cast)

Categories: c#, Windows Forms Tags:

Bootstrapper Manifest Generator (2008) – How To Guide v2

March 3rd, 2011 14 comments

I wrote the original Boostrapper Manifest Generator (BMG) blog post a few years ago.

It is one of the most heavily visited pages on my site so I thought I should revisit it, and given that the BMG is so buggy it could be useful to have some screen shots.

I will provide 2 concrete examples of how to use the BMG to create a bootstrapper pre-requisite check.

All this is being done on a Windows 7 32-bit (Virtual) machine, with visual studio 2010 installed.

I have also downloaded and installed the BMG2008 which can be downloaded from here

The application that I am going to bootstrapper is a small test application called “GuidGenerator”, can you guess what it does?

I will be using a standard setup deployment project to create the installer.

Here goes..

Setup BMG 2008

  1. Download the BMG2008 from here
  2. Install the application and note the path that it is installed to as it does not create a short cut, (C:Program FilesMicrosoftBootstrapper Manifest Generator for VS2008), and create your own desktop shortcut
  3. Run the BMG
  4. Click “Tools :: Edit Machine Paths”
  5. You may get a message about the SDK not being installed etc etc. Get past the error message and you will need to set the path to your boot strap directory. Do a search on your file system for “bootstrapper” and you will find a folder somewhere like this (note the SDK path)
    C:Program FilesMicrosoft SDKsWindowsv7.0ABootstrapper
    Enter that into the path and choose OK.

    You are now ready to create a bootstrapper

    Note: This bootstrapper folder is important – read the tips and tricks at the end.

Example 1 – .Net Framework 4.0 Pre-requisite Check

  1. Download the DotNet framework full install from Microsoft here, and save to a location that you can find, mine is @ c:DownloadsdotNetFx40_Full_x86_x64.exe
  2. Run the BMG
  3. Click “File New”
  4. Choose “Package Manifest”, choose OK
  5. Choose “Add Install File”, (button in the top left)

  6. Browse to the .Net Framework that you downloaded earlier and click OK
  7. Display Name: enter a name for the bootstrapper, this is the name of the pre-requisite check that will show up in visual studio. I will call mine “My .net Framework 4.0 Check”
  8. Click back on the “Package” option which is the root of the tree menu on the left and set the Product Name to DotNet4Check – this becomes the name of the folder that the package is created in.
    Note: You have to do it in this order as if you set the package name before adding a file it crashes the BMG.
  9. Click into the product code field and it will default with the “Product Name” just set, (otherwise this can throw a warning if left blank).
  10. System Checks
      You want to set up a system check that fails if the condition is not met, or alternatively by-pass the install if a condition is met.
      If it fails the check then it will prompt the user that they need to install the pre-requisite.

      For the .Net Framework I have chosen to do a simple registry check for the .Net Framework version.

    • Switch to the system checks tab
    • Click on the registry check (2nd icon in the list)
    • Property for Result: DotNet4RegCheck (note: this is the name of the check that is used later in the “Install Conditions” tab
    • Enter the following registry key: HKLMSoftwareMicrosoftNET Framework SetupNDPv4Full
    • Registry Value: Version
  11. Install Conditions
    • Switch to the install conditions tab. This is where we define when our installer should be run.
    • Type: ByPassIf
    • Property: DotNet4RegCheck – (This is the name entered in the “Property for Result” field in the system check
    • Comparison: Ver >=
    • Value: 4.0.30319
  12. Exit Codes
    Set the following: (Note: I am cheating as I am reverse engineering the .Net bootstrapper that comes with VS2010 to get these exit codes

      0 – Success
      3010 – Success with reboot

    Leave all the other options with their defaults

  13. Build: Now we can build the package, (button top right)
  14. Results, note that in my case it succeeded with no errors, and the path contains the folder name that I entered in the product name field.

  15. Copy: Go to the output directory and copy the “DotNet4Check” folder to “C:Program FilesMicrosoft SDKsWindowsv7.0ABootstrapperPackages”
  16. Setup Project
    1. My project looks like this:

    2. Right Click on the Setup Project and choose properites
    3. On the properties window Click the “Pre-Requisites” button.
    4. Deselect anything that is selected that you do not require and choose your check.

    5. In this case I am going to say – “Download prerequisites from the same location as my application”
    6. Build the setup solution in release mode.
    7. Copy the release directory somewhere to a machine missing the pre-requisites. The release directory should look something like this, because we chose to set the download from the same location.

    8. Run the installer and you will see this…

Example 2 – .Net Framework 4.0 Pre-requisite Check – web download

In this example we want to supply a web download version of the installer so you don’t have to distribute the requisite files with your installer.

This will be identical to the previous example with these changes:

  1. After adding the file you get the Properties tab. Enter the URL from the tips below in the “HomeSite URL” setting.
    I used – http://go.microsoft.com/fwlink/?linkid=182805 for the .Net 4.0 Framework. (remember you must right-click and choose paste).

  2. When setting up the package pre-requisites choose to “Download Pre-requisites from the package vendors website”.

Repeat all the other steps and when you choose “install” from the bootstrapper prompt you should get a message that it is downloading.

Tips and Tricks

  • The “Bootstrapper” directory is your friend (on my machine “C:Program FilesMicrosoft SDKsWindowsv7.0ABootstrapper”).
    If you have access to a VS2010 installed machine and go to the bootstrapper directory and into the Packages folder and you will find bootstrappers for 19 different things, including .Net 3.5/4.0 and Client installation versions.
    I suspect if you took a copy of the packages folder back to your older VS2005/2008 environment you would get the pre-requisites.
  • If you don’t intend to set up exit conditions don’t switch to the “Exit Conditions tab”. if you do it will put an empty condition in that throws a warning at build time. The only way to get rid of it is to enter 0 / Success.
  • I suspect for things like .Net you want the user to be able to download the .exe directly. Here are the URL’s provided by the .Net bootstrappers installed with VS2010.

    These are the small web installer based versions

    • .Net Framework 3.5 SP1: http://go.microsoft.com/fwlink/?linkid=118076 download
    • .Net Framework 3.5 Client: http://go.microsoft.com/fwlink/?LinkId=119637 download
    • .Net Framework 4.0: http://go.microsoft.com/fwlink/?linkid=182805 download
    • .Net Framework 4.0 Client: http://go.microsoft.com/fwlink/?linkid=182804 download
  • My web install failed because on my Install I happened to click into the “Value” field and it put the following “N/A for ValueExists and ValueNotExists”. This created an “unexpected error” on install.
    I went into the product.xml file and set value=”” and it worked.
VN:F [1.9.22_1171]
Rating: 10.0/10 (4 votes cast)

Categories: c#, Code Tags:

StringUtil class – Space Before a Capital Letter

September 17th, 2010 No comments

Hi,

I often use enumerations in code that I want to display as text on the screen. For example the state of an object recorded in an enum like

public enum StageType
{
	PreRelease = 0,
	Proposed = 1,
	Open = 2,
	Closed = 3
}

So if I get the matching value out of the database and I want to render a textual representation of the enum to the UI I might do:

lblStatus.Text = ((StageType) iStage).ToString(); // where iStage is an int value representing the enum.

So this is great apart from the first item PreRelease will be shown without a space.

Step in my amazing class which will parse the string and add a space before a capital so “PreRelease” becomes “Pre Release”
This way I can use any Camel case enum string and have it render to the UI nicely.

public static class StringUtil
{

	///
	/// Returns a string with a space after a capital
	///
	///
	///
	public static string SpaceOnCapital(string word)
	{
		StringBuilder sb = new StringBuilder();

		foreach (char c in word)
		{
			if (sb.Length == 0)
			{
				sb.Append(c);
			}
			else
			{
				// not the first character
				// ch
				if (IsCapital(c))
				{
				sb.AppendFormat("{0}", c);
				}
				else
				{
				sb.Append(c);
				}
			}
		}

		return sb.ToString();
	}

	public static bool IsCapital(char c)
	{
		int ascii = (int)c;
		return (ascii >= 65 && ascii <= 90);
	}
}

Cheers

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)

Categories: c# Tags:

Generic List.Sort

August 30th, 2010 No comments

I often want to use a list to sort and every time I have to go searching on how to use the IComparer interface.

Assume I have a Person object with the “DisplayName” property that I wish to sort by.

I created the following class:

public class PersonDisplayNameAscendingComparer : IComparer
{
    #region IComparer Members

    public int Compare(Person x, Person y)
    {
        return x.DisplayName.CompareTo(y.DisplayName);
    }

    #endregion
}

And then assuming you have a List called people, you can sort like this;

    PersonDisplayNameAscendingComparer personComparer = new PersonDisplayNameAscendingComparer();
    people.Sort(personComparer);

Job done.

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)

Categories: c# Tags:

RequiredFieldValidator conditional validation via client side script

May 27th, 2010 No comments

Interesting Problem.

I created a user edit page on an ASP.Net website. A user when looking at their own record got a “Change Password” panel. It is optional and only updated if data is entered in the text boxes. I wanted to use the CompareValidator to compare the txtPassword and txtConfirmPassword textboxes.

This worked great, I set up the CompareValidator to validate the txtConfirmPassword against the txtPassword. Problem is the ConfirmValidator does not fire when there is nothing entered in the txtConfirmPassword textbox. So the user could enter a password and click submit and the compare validator would not fire and the page would submit.

So I needed a RequiredFieldValidator on txtConfirmPassword but this is only needed to be enabled after some text is entered in the txtPassword text box.

I found this article:
http://www.aspdotnetfaq.com/Faq/How-to-control-ASP-NET-Validator-Controls-Client-Side-validation-from-JavaScript.aspx

and implemented this javascript. Note I am using a little jQuery to get the controls. (1.4.1)

And using this information was able to write the following script:

<script type="text/javascript">
    $(document).ready(function() {
        $('#<%=txtPassword.ClientID %>').change(function() {
            var value = $('#<%=txtPassword.ClientID %>').val();
            if(value.length > 0){
                EnableValidators(true);
            } else {
                EnableValidators(false);
            }
        });
    });

    function EnableValidators(enable)
    {
        ValidatorEnable(document.getElementById('<%=rfvConfirmPassword.ClientID%>'), enable);
    }
</script>

The interesting thing is “ValidatorEnable” is a Asp.Net function that client-side enables and disables the validators.

Nice 🙂

VN:F [1.9.22_1171]
Rating: 9.0/10 (1 vote cast)

Categories: ASP .Net, c# Tags:

C# Stack with maximum limit

May 6th, 2010 5 comments

I am writing a web based app at the moment and I am wanting to maintain a history of the persons movements around the site to enable some business logic for handling back button clicks.

I wanted to use a Stack but I did not want to let it get too out of control in memory if people take weird navigation choices around the site. So I wanted a stack that would push on the top but have a maximum limit so that when the maximum was reached the oldest items on the stack just fell out the bottom.

So I wrote the MaxStack. Hope you like it. It uses a generic linked list to implement the stack like interface.

Note its also serializable as I am storing it in session.
(Sorry about the indenting wordpress has mashed it)

MaxStack

using System;
using System.Collections.Generic;

namespace MyArchitecture
{
    /// <summary>
    /// Generic stack implementation with a maximum limit
    /// When something is pushed on the last item is removed from the list
    /// </summary>
    [Serializable]
    public class MaxStack<T>
    {
        #region Fields

        private int _limit;
        private LinkedList<T> _list;
        
        #endregion

        #region Constructors

        public MaxStack(int maxSize)
        {
            _limit = maxSize;
            _list = new LinkedList<T>();
            
        }

        #endregion

        #region Public Stack Implementation

        public void Push(T value)
        {
            if (_list.Count == _limit)
            {
                _list.RemoveLast();
            }
            _list.AddFirst(value);
        }

        public T Pop()
        {
            if (_list.Count > 0)
            {
                T value = _list.First.Value;
                _list.RemoveFirst();
                return value;
            }
            else
            {
                throw new InvalidOperationException("The Stack is empty");
            }

            
        }

        public T Peek()
        {
            if (_list.Count > 0)
            {
                T value = _list.First.Value;
                return value;
            }
            else
            {
                throw new InvalidOperationException("The Stack is empty");
            }
            
        }

        public void Clear()
        {
            _list.Clear();
            
        }

        public int Count
        {
            get { return _list.Count; }
        }

        /// <summary>
        /// Checks if the top object on the stack matches the value passed in
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool IsTop(T value)
        {
            bool result = false;
            if (this.Count > 0)
            {
                result = Peek().Equals(value);
            }
            return result;
        }

        public bool Contains(T value)
        {
            bool result = false;
            if (this.Count > 0)
            {
                result = _list.Contains(value);
            }
            return result;
        }

	public IEnumerator GetEnumerator()
	{
            return _list.GetEnumerator();
	}

        #endregion

    }
}
VN:F [1.9.22_1171]
Rating: 5.3/10 (4 votes cast)

Categories: c# Tags:

List<object> Find with delegate

March 11th, 2008 No comments

Thought this was really cool.

I have a generic List of objects, for example:

List<User> users = GetAllUsers();

I want to find a user by username. Usually you would loop through looking for the item with the matching username and return the user that was found.

or you could do this:

User loggedOnUser = users.Find(delegate(User u) { return u.Username == "jbloggs"; });

Much less code, and you could match on any property of the object that you wanted.

Cheers

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)

Categories: c#, Code Tags:

Dynamically creating user controls in code behind

February 27th, 2008 No comments

If you have a user control that you wish to dynamically add to your page the following will not work;

UserControl control = new UserControl()

The problem is that the control has not been successfully created and all the internal controls that make up the user control, like text boxes etc, will be null.

The way to create the control is with the “LoadControl()” statement.

UserControl control = LoadControl("~/controls/UserControl.ascx") as UserControl;

and now it will work.

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)

Categories: c#, Code Tags: ,