Monthly Archives: February 2014

Creating a centralised resource project

Once you’ve created your project, should you wish you distribute your software to multiple countries, then the question of localisation must, inevitably, arise. If you’re using .NET then a very tempting option is to use resource files. Most of the plumbing is already done for you, you simply need to create a resource file, and then localise it by copying the file and changing the extension to the correct culture.

Example

Say, for example, you had written your software in British English, and you wanted to localise to American English. Here’s you’re English version:

Image

For an American version, copy the resource file:

Image

Call the new file the same as the old one, but with the correct culture; for example:

Resource1.en-US.resx

Image

And here’s some code to use the resource string in question:

         static void Main( string[] args)
        {
            Console.WriteLine(Properties. Resource1.LocalString);
        }

Okay, so here’s the brilliant thing about resources; that’s it. When I change my culture it uses the culture specific resource file:

         static void Main( string[] args)
        {
            Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US" );

            Console.WriteLine(Properties. Resource1.LocalString);
        }

So – what’s new?

It’s pretty likely that you’ve already seen that part. You may also have seen the next part too – but my guess is that if you’ve read this long, you haven’t.

Centralise resources

In the above project, having a resource file and just accessing it seems to make a lot of sense, but what if there’s more than one project; what if you have a solution with a few projects?

Image

You could have a resource file for each project, and that works. But, what if you decide to translate to French, but no-one on your team speaks fluent (and it does have to be fluent) French? There are LOTS of companies that will accept a resource file and translate – they’ll also accept several, and translate them all, but why make it so that you need several?

Centralised resources in action

Create a new class library in the following vein:

namespace Localise
{
    public class Localise
    {
        private static ResourceManager _resourceMan;

        private static ResourceManager ResourceMan
        {
            get
            {
                if (_resourceMan == null)
                {
                    ResourceManager tmpRes = new ResourceManager("Localise.Localise.Properties.Resources" , typeof(Resources ).Assembly);
                    _resourceMan = tmpRes;
                }
                return _resourceMan;
            }
        }

        public static string GetResString( string key)
        {
            string valString = ResourceMan.GetString(key);
            return valString;
        }
    }
}

If you’ve ever had a look at the resources.designer.cs then this code should look very familiar. That of course is internal, so doesn’t work for this.

All your resources now go in here, and you simply reference it from your project like so:


Console.WriteLine(Localise.Localise.GetResString("LocalString"));

Conclusion

There are other ways to handle resource strings – you can hold them in the database, in text files, you could build a whole infrastructure of resource assets. If you have a massive solution distributed to hundreds of countries then that’s probably worth it. If not, use what Microsoft give you for free.

The server principal “server” is not able to access the database “DBName” under the current security context.

I got this error recently – seemingly for no reason. I thought it might be an idea to share the workaround, as I didn’t find it anywhere when searching (although I did find a mass of other potential solutions – so this is the post I wanted to find while searching).

The Problem

I started getting the error:

The server principal “server” is not able to access the database “DBName” under the current security context.

This occurred after recreating a database and trying to run a stored procedure. It’s obviously a security error; but it appeared that the security was sufficient to execute the SP in question.

Attempt 1

The first thing I came across was this:

SELECT USER_NAME(P.GRANTEE_PRINCIPAL_ID) AS PRINCIPAL_NAME,
DP.PRINCIPAL_ID,
DP.TYPE_DESC AS PRINCIPAL_TYPE_DESC,
P.CLASS_DESC,
OBJECT_NAME(P.MAJOR_ID) AS OBJECT_NAME,
P.PERMISSION_NAME,
P.STATE_DESC AS PERMISSION_STATE_DESC
FROM SYS.DATABASE_PERMISSIONS P
INNER JOIN SYS.DATABASE_PRINCIPALS DP
ON P.GRANTEE_PRINCIPAL_ID = DP.PRINCIPAL_ID
WHERE P.STATE_DESC = 'DENY'

That showed nothing; i.e. there was no explicit “deny”.

Attempt 2

Next, I came across something that suggested using the following to explicitly grant connect to the current user:

use msdb
grant connect to [domaincurrentuser]

Again, this didn’t work for me.

Attempt 3

I then came across a raft of suggestions to do the following:

1. Log in with Microsoft SQL Server Management Studio and click OK when the error appears.
2. Press F7 to open Object Explorer Details.
3. Right click on the column header at the top of the new window and uncheck Collation
4. In the left column, right-click Databases and click Refresh
5. Find your database and click the + sign to expand it.

It didn’t work (and I couldn’t really work out why it would); but based on the quantity of suggestions and positive response – try it).

Attempt 4

Try running the SP as “sa”. If it still doesn’t work then:

ALTER DATABASE DBName SET TRUSTWORTHY ON

sp_changedbowner 'sa'

If you’re still reading then you may be in the same boat as me; try this:

Attempt 5 – success


USE DBName
GO
EXECUTE sp_grantdbaccess guest

/*
REVOKE CONNECT FROM guest
GO
*/

This WORKED, and I didn’t know why. Firstly, if this IS your problem; don’t leave guest enabled – it’s a LARGE security hole. What it likely means is that your SP is executing as a user that may not exist in your DB. Have a look for a command such as the following somewhere in the SQL:

EXECUTE AS 'SomeUser'

Where ‘SomeUser’ isn’t in your DB. The reason that enabling ‘Guest’ works is that it acts as a fallback; if you try to do something as a user with no permission, it will use Guest if it can’t execute.

Unit Testing an MVVM RelayCommand

The RelayCommand is an excellent way to communicate between a view and View Model in MVVM without creating a link to a specific instance of either. However; one problem that I recently encountered when using these was: how are they unit tested.

Take the following piece of code (taken from https://tfsutilities.codeplex.com/):


    public class MainViewModel : ViewModelBase
    {          
        public RelayCommand FindOrphanedWorkspaceCommand { get ; private set ; }

This is instantiated here:

         public MainViewModel( IDataService dataService)
        {
            ...

            FindOrphanedWorkspaceCommand = new RelayCommand(FindOrphanedWorkspaces);

And, finally, the method itself:

         /// <summary>
        /// Call method to retrieve all workspaces that currently have no pending changes
        /// </summary>
        private void FindOrphanedWorkspaces()
        {
            // Doesn't really matter what this actually does

So; can we just write a test; what about this:

    [TestClass]
    public class MainViewModelTest
    {
        [ TestMethod]
        public void FindOrphanedWorkspaces()
        {
            IDataService ds = new Mock.MockDataService ();
            MockMainViewModel mvm = new MockMainViewModel (ds);

            mvm.FindOrphanedWorkspaceCommand();

        }

The answer, of course, is no (otherwise this wouldn’t be a particularly useful blog post).

The Workaround

There is a workaround (which is pretty much by fallback workaround these days when I find something can’t be unit tested for reasons of protection):

Simply change the private method to protected and subclass the viewmodel:

    class MockMainViewModel : MainViewModel
    {
        public MockMainViewModel( IDataService dataService) : base (dataService) { }

         public void FindOrphanedWorkspaces()
        {
            base.FindOrphanedWorkspaces();

This certainly works and, in its defence, it tests as completely as calling the RelayCommand (I don’t believe testing the MVVM architecture is within the remit of the test architecture of any dependent program).

However…

It feels like a lot of additional work (as it happens, it’s work you may have to do anyway for other things, but that’s beside the point). So, what’s the alternative?

RelayCommand implements ICommand, here’s the metadata:


namespace GalaSoft.MvvmLight.Command
{
    // Summary:
    //     A command whose sole purpose is to relay its functionality to other objects
    //     by invoking delegates. The default return value for the CanExecute method
    //     is 'true'. This class does not allow you to accept command parameters in
    //     the Execute and CanExecute callback methods.
    public class RelayCommand : ICommand
    {
        // Summary:
        //     Initializes a new instance of the RelayCommand class that can always execute.
        //
        // Parameters:
        //   execute:
        //     The execution logic.
        //
        // Exceptions:
        //   System.ArgumentNullException:
        //     If the execute argument is null.
        public RelayCommand( Action execute);
        //
        // Summary:
        //     Initializes a new instance of the RelayCommand class.
        //
        // Parameters:
        //   execute:
        //     The execution logic.
        //
        //   canExecute:
        //     The execution status logic.
        //
        // Exceptions:
        //   System.ArgumentNullException:
        //     If the execute argument is null.
        public RelayCommand( Action execute, Func< bool> canExecute);

        // Summary:
        //     Occurs when changes occur that affect whether the command should execute.
        public event EventHandler CanExecuteChanged;

        // Summary:
        //     Defines the method that determines whether the command can execute in its
        //     current state.
        //
        // Parameters:
        //   parameter:
        //     This parameter will always be ignored.
        //
        // Returns:
        //     true if this command can be executed; otherwise, false.
        public bool CanExecute( object parameter);
        //
        // Summary:
        //     Defines the method to be called when the command is invoked.
        //
        // Parameters:
        //   parameter:
        //     This parameter will always be ignored.
        public virtual void Execute( object parameter);
        //
        // Summary:
        //     Raises the GalaSoft.MvvmLight.Command.RelayCommand.CanExecuteChanged event.
        public void RaiseCanExecuteChanged();
    }
}

Consequently, you can simply do this:


        [ TestMethod]
        public void FindOrphanedWorkspaces()
        {
            IDataService ds = new Mock.MockDataService ();
            MockMainViewModel mvm = new MockMainViewModel (ds);

            mvm.FindOrphanedWorkspaceCommand.Execute( null);

        }

And, there’s more. If you’ve implemented the CanExecute, you can test if that works; for example:

Assert.IsTrue(mvm.FindOrphanedWorkspaceCommand.CanExecute(null));

Or

Assert.IsFalse(mvm.FindOrphanedWorkspaceCommand.CanExecute(null));

In my case, as it stands, the former.

Conclusion

So, we can check whether the command can execute, and whether it does execute. Admittedly this isn’t ground-breaking research, but it took me longer that it should have to figure it out, and next time, I’ll have a blog post to refer to.