Tuesday, 27 September 2011

How to post code in blogger!

Ok, after struggling initially with posting code in blogger I managed to figure out how to do this. When I started this blog I didn't realise the following tags existed:

<pre name="code">
code goes here!
</pre>


This is much better and results in better formatted posts. The only real "gotcha" is you'll have to replace some "html" style tags with their html safe equivalent. For example, "<" becomes "&lt;"

Now to go back and fix my blog...

Monday, 19 September 2011

MS Dynamics 2011 and MVVM

So, I've been out of the Microsoft Dynamics world for about a year now (and semi AWOL in the process!), but after changing jobs I find myself back in this world using 2011. First up, Silverlight! Now, I have started to notice quite a bit that a lot of samples or guides on CRM 2011 and Silverlight don't seem to use MVVM. Why on earth is that? First things first, this in my opinion sheds a very bad light on Dynamics development. The very first project I get to work on had already been started by a previous developer. I open up the project and to my dismay I see absolutely zero view models. Task 1 - Push TDD.

So, why would we not use MVVM in Dynamics 2011? Let's walk through a sample I found and my phase 1 of refactoring. I open up the code behind and find this:


    private DataItemCollection _collection;
    public System.String _serverUrl;
    private string _userId;
    public MainPage()
    {
        InitializeComponent();
        this.Loaded += new RoutedEventHandler(MainPage_Loaded);
    }

    void MainPage_Loaded(object sender, RoutedEventArgs e)
    {
        GetPageInformation();
         LoadCompanies();
    }

    private void LoadCompanies()
    {
        _collection = new DataItemCollection();
        QueryExpression query = QueriesHelper.GetAllAccounts();
        SoapHelper.BeginExecuteRetrieveMultiple(query, new AsyncCallback(GetAccountsCompleted), null);
    }

    private void GetAccountsCompleted(IAsyncResult result)
    {
        OrganizationResponse response = ((IOrganizationService)result.AsyncState).EndExecute(result);
        if ((response != null) && (response.Results.Count > 0))
        {

...I SHALL PROTECT YOUR EYES FROM A MONSTROSITY OF A FUNCTION HERE...

        }

        if (!Deployment.Current.Dispatcher.CheckAccess())
        {
            Deployment.Current.Dispatcher.BeginInvoke(delegate()
            {
                this.TreeViewClients.DataContext = _collection;
            });
        }
        else
        {
            this.TreeViewClients.DataContext = _collection;
        } 
    }

    private void GetPageInformation()
    {
        ScriptObject xrm = (ScriptObject)HtmlPage.Window.GetProperty("Xrm");
        ScriptObject page = (ScriptObject)xrm.GetProperty("Page");
        ScriptObject pageContext = (ScriptObject)page.GetProperty("context");
        _userId = (string)pageContext.Invoke("getUserId");
        _serverUrl = (string)pageContext.Invoke("getServerUrl");
    }


So what do we have here? What hints do I get as to why we wouldn't implement MVVM? Ok, so it looks like either the developer hadn't done much Silverlight/WPF before... or didn't quite know how to MVVM this. Looking at the code I can see that there's 2 things that we need to be considerate of when considering MVVM:

1. Queries need to run Asynchronous.

2. Access to our dispatcher for when we need to run "stuff" on the UI thread.

So how do we move this across to a MVVM structure then? Step 1, let's create a ViewModel:


    public class MyDamnViewModel
    {
        private readonly Dispatcher _dispatcher;

        public MyDamnViewModel()
        {
            _dispatcher = Deployment.Current.Dispatcher;
        }
    }


One plan here will be to allow for testing, but for now just copy the dispatcher to a local variable.

So what else can we add to this? How about everything! Considering the old form set everything up in the "onload" let's go with this for now. Let's just copy ALL methods across to my viewmodel and add the 2 method calls to our ViewModel constructor (GetPageInformation and LoadCompanies)... This will cause 1 major problem...


    this.TreeViewClients.DataContext = _collection;


What do we do? I notice my DataItemCollection already inherits from ObservableCollection... let's work with that for now and mark for review... Refactor the variable _collection so that we expose as a public ObservableCollection property:


    private DataItemCollection _collection; 
    public ObservableCollection<DataItem> NowWeHaveACollection 
    { 
        get { return _collection; } 
        set 
        { 
            _collection= (DataItemCollection)value; 
            NotifyPropertyChanged("NowWeHaveACollection"); 
        } 
    } 


I won't go into NotifyPropertyChanged stuff into too much depth here... but to get us by I just inherited from INotifyPropertyChanged and added this code to the view model:


    public event PropertyChangedEventHandler PropertyChanged;
    protected void NotifyPropertyChanged(String info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }


Let's worry about refactoring and tidying all that up in a phase 2. For now I just want to get a basic MVVM structure in place.

So what did this new property give us? We can just set the property instead of directly accessing the control:


    NowWeHaveACollection = _collection;


Nearly there yet boss? Not quite. Code should be there, but we don't have anything hooked up. Let's set up our datacontext in the XAML:


    <usercontrol.datacontext> 
        <MyDamnViewModel /> 
    </usercontrol.datacontext>


And set our bindings up in the XAML instead of in the code. In my case it was a telerik tree view so we have converters and all sorts of rubbish in the code... I'll save that for another post. Let's pretend for now it's a bog standard list or something. Set this on your object in the XAML:


    ItemsSource="{Binding NowWeHaveACollection}"


And now our main form looks like this:


    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
        }
    }


Ignoring the fact that it's called "MainPage" and some "phase 2" refactoring we're pretty much done.

So, to answer the question - No reason not to use MVVM in Dynamics 2011. I'd like to see less samples using direct code behind please!!

Monday, 10 May 2010

How to create an email validator on a web page

Came across this requirement recently on an asp.net application I'm developing. Handy to know that you can easily create a regular expression to handle email formats like this:

<asp:textbox id="textbox1" runat="server">
  <asp:regularexpressionvalidator controltovalidate="textbox1" display="dynamic"
    errormessage="* Your entry is not a valid e-mail address." id="valRegEx" 
    runat="server" validationexpression=".*@.*\..*">*
  </asp:regularexpressionvalidator>
</asp:textbox>

Friday, 13 November 2009

SQL Server - How do I select just the date portion of a datetime field

There are a few ways to do this, but I find the easiest is to use the float version of a datetime and crop off the decimal portion (right of the decimal place is the time portion)

DECLARE @currentDate DateTime
SET @currentDate = Cast(Floor(Cast(GetDate() as Float )) As DateTime)

Friday, 9 October 2009

"Failed to pause full-text catalog for backup" while backing up a database

So you're trying to back up your database and you get the following error:

Failed to pause full-text catalog for backup. Backup was aborted. Check to make sure Microsoft Full-text Service is running properly and SQL server service have access to full-text service.


There are a couple of things that could be up here. Try all of the following and see if that get's you out of this:

1. Check if the full text service is running. This can be found by opening up the windows services and locating either "SQL Server Full Text Search" or "Microsoft Search Service". If it's not running or disabled then this may be your problem- Retry the backup.

2. Ensure full text catalog is enabled on the databases by running the following command:

exec sp_fulltext_database 'enable'

Retry the backup.

3. If all of the above fails take a note of how the full text catalog is set up on the database in question. It should be accessible via Storage -> Full Text Catalogs. When you see what tables and fields it references try dropping and recreating the full text catalog. Retry the backup.


Hope this helps!


Karma Gardas Snippets Diary - Blogged

"The virtual directory specified already exists"... but it doesn't!

I've come across this issue intermittently on some servers, but I haven't figured out yet why it happens. The times I've seen it happen is when the virtual folder wasn't created with all the permissions required, and then deleting it seems to leave a remnants of it behind. An example of this is when you cannot locate the virtual directory but can see it referenced by an app pool.

So, how do you get rid of it?

9 times out of 10 the following works for me. Let's say the new virtual directory is called "MyDir" and was located in the web site "My Web"

- Open up a command prompt
- Type in the following command:

IIsVDir /delete "My Web"/MyDir

Sometimes if that doesn't work creating the virtual directory (using the same name - MyDir in this example) and running the above command again usually works.

If anyone can shed any light on why this remnants happens please do.